Сквозное шифрование в Android.Я пытаюсь реализовать приложение чата в Android.
Я пробовал алгоритмы AES для шифрования и дешифрования, успешно сгенерировал закрытый и открытый ключ
GenerateRsaKeyPair.java класс, который генерирует публичный и приватныйпопытка ключа {
// 1. generate public key and private key
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024); // key length
KeyPair keyPair = keyPairGenerator.genKeyPair();
String privateKeyString = Base64.encodeToString(keyPair.getPrivate().getEncoded(), Base64.DEFAULT);
publicKeyString = Base64.encodeToString(keyPair.getPublic().getEncoded(), Base64.DEFAULT);
// 2. print both keys
System.out.println("rsa key pair generated\n");
Log.e("privateKey", privateKeyString );
Log.e("publicKey", publicKeyString );
isgenerated=false;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
этот код зашифровывает сообщение попытаться {
// 1. generate secret key using AES
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128); // AES is currently available in three key sizes: 128, 192 and 256 bits.T
// the design and strength of all key lengths of the AES algorithm are sufficient to protect classified information up to the SECRET level
SecretKey secretKey = keyGenerator.generateKey();
plainText=editTextsend.getText().toString();
// 2. get string which needs to be encrypted // our case message
String text = plainText;//"<your_string_which_needs_to_be_encrypted_here>"
Log.e("string",text);
// 3. encrypt string using secret key
byte[] raw = secretKey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//PKCS5Padding
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[16]));
String cipherTextString = Base64.encodeToString(cipher.doFinal(text.getBytes(Charset.forName("UTF-8"))), Base64.DEFAULT);
Log.e("ciphertext",cipherTextString);
// 4. get public key
X509EncodedKeySpec publicSpec = new X509EncodedKeySpec(Base64.decode(publicKeyString, Base64.DEFAULT));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(publicSpec);
// 6. encrypt secret key using public key
Cipher cipher2 = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding");
cipher2.init(Cipher.ENCRYPT_MODE, publicKey);
String encryptedSecretKey = Base64.encodeToString(cipher2.doFinal(secretKey.getEncoded()), Base64.DEFAULT);
Log.e("encryptedSecretKey",encryptedSecretKey);
// 7. pass cipherTextString (encypted sensitive data) and encryptedSecretKey to your server via your preferred way.
// Tips:
// You may use JSON to combine both the strings under 1 object.
// You may use a volley call to send this data to your server.
} catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException | InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
этот код успешно расшифровывает сообщение попытаться {
// 1. Get private key
PKCS8EncodedKeySpec privateSpec = new PKCS8EncodedKeySpec(Base64.decode(privateKey, Base64.DEFAULT));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(privateSpec);
Log.e("secretKey",privateKey+"");
// 2. Decrypt encrypted secret key using private key
Cipher cipher1 = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding");
cipher1.init(Cipher.DECRYPT_MODE, privateKey);
byte[] secretKeyBytes = cipher1.doFinal(Base64.decode(encryptedSecretKeyString, Base64.DEFAULT));
SecretKey secretKey = new SecretKeySpec(secretKeyBytes, 0, secretKeyBytes.length, "AES");
Log.e("secretKey",secretKey+"");
// 3. Decrypt encrypted text using secret key
byte[] raw = secretKey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(new byte[16]));
byte[] original = cipher.doFinal(Base64.decode(encryptedTextString, Base64.DEFAULT));
String text = new String(original, Charset.forName("UTF-8"));
Log.e("text",text);
// 4. Print the original text sent by client
System.out.println("text\n" + text + "\n\n");
} catch (NoSuchAlgorithmException | InvalidKeySpecException | InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
Я ожидаю, чтомой закрытый ключ и открытый ключ должны быть одинаковыми для конкретного пользователя, но в моем коде, когда я создаю свое приложение, он каждый раз генерировал разные закрытый и открытый ключи, поэтому как бы я управлял текущим пользователем предыдущими сообщениями чата и данными и этим каждый раздля чата и группового чата.Любой ответ и предложение будут заметны.