Я работаю над приложением безопасного чата. У меня есть ключ AES для шифрования / дешифрования сообщения, а пользователи имеют собственные открытые / личные ключи RS для шифрования / дешифрования ключа AES. Мой код выдает мне такую ошибку:
> javax.crypto.BadPaddingException: Decryption error
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:383)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:294)
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:363)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
at javax.crypto.Cipher.doFinal(Cipher.java:2164)
at org.fastchat.User.decryptAESKey(User.java:183)
at org.fastchat.User.readMessage(User.java:210)
at org.fastchat.WatchInbox.startWatch(WatchInbox.java:59)
at org.fastchat.WatchInbox.run(WatchInbox.java:32)
Ошибка в функции дешифрования ключа AES с закрытым ключом RSA. Я обнаружил, что проблема может быть с неправильным ключом (ключи хранятся в сериализации, каждый пользователь когда-то генерировал ключи в объекте профиля) или проблемами с кодированием / декодированием. Я решил сохранить зашифрованный ключ AES в каком-то файле и прочитать этот файл для расшифровки ключа AES. Есть ли какой-нибудь лучший способ для AES-ключа, зашифрованного в магазине? Я делаю кодировать / декодировать правильно? Любая помощь приветствуется, у меня нет никаких идей сейчас. Мой код здесь, и каждая часть процесса имеет различные функции.
public SecretKey generateAESkey() throws NoSuchAlgorithmException {
System.out.println("Generating AES key...\n");
SecureRandom random = new SecureRandom();
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128, random);
SecretKey aeSecretKey = keyGenerator.generateKey();
System.out.println("AES1 KEY " + new String(Base64.getEncoder().encodeToString(aeSecretKey.getEncoded())));
System.out.println("===========================\n");
return aeSecretKey;
// return keyGenerator.generateKey();
}
public byte[] encryptAESKey(SecretKey key, PublicKey pubKey) throws Exception {
System.out.println("Encrypt AES key...\n");
String aesKey = new String(Base64.getEncoder().encodeToString(key.getEncoded()));
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] aesEnc = cipher.doFinal(aesKey.getBytes());
System.out.println("AES ENCRYPTED: " + aesEnc);
System.out.println("==========================\n");
return aesEnc;
// return cipher.doFinal(aesToEnc);
}
public byte[] encryptMessage(String message, SecretKey aeSecretKey) throws Exception {
System.out.println("Encrypt message...\n");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, aeSecretKey);
byte[] msgBytes = message.getBytes(); // This will be encrypted
byte[] msgEnc = cipher.doFinal(msgBytes);
System.out.println("=============================\n");
return msgEnc;
// return cipher.doFinal(msgBytes); //This will be in .txt file
}
public void checkerUpdate(User receiver) throws IOException {
BufferedWriter check = new BufferedWriter(new FileWriter(receiver.getCheck() + "/" + getUsername() + ".txt"));
Random random = new Random();
Integer num = random.nextInt(100);
check.write(num);
check.close();
}
public void sendMessage(String message, User receiver) throws Exception {
// First generate AES key
SecretKey aesSecretKey = generateAESkey(); // keysize = 128
// Encrypt message with AES key, will be in file
byte[] encMsg = encryptMessage(message, aesSecretKey);
// Encrypt AES key, put in file
byte[] aesEnc = encryptAESKey(aesSecretKey, receiver.getPub());
// Send message and key to receiver
FileOutputStream msgWrite = new FileOutputStream(receiver.getInbox() + "/" + getUsername() + ".msg", true);
FileOutputStream keyWrite = new FileOutputStream(receiver.getInbox() + "/" + getUsername() + ".kgn", true);
keyWrite.write(Base64.getEncoder().encode(aesEnc));
msgWrite.write(Base64.getEncoder().encode(encMsg));
keyWrite.close();
msgWrite.close();
// Add file to CHECKER, temp operations for WatchInbox service
checkerUpdate(receiver);
}
// FUNCTIONS FOR DECRYPTION
public byte[] decryptAESKey(byte[] aesEnc) throws Exception {
System.out.println("Decrypt AES key...\n");
byte[] aesEncString = Base64.getDecoder().decode(aesEnc);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, getPriv());
byte[] decAes = cipher.doFinal(aesEncString);
System.out.println("===========================\n");
return decAes;
// return cipher.doFinal(Base64.getDecoder().decode(aesEnc));
}
public String decryptMessage(byte[] msg, SecretKeySpec aeskey) throws Exception {
System.out.println("Decrypt message...\n");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, aeskey);
String msgDec = cipher.doFinal(Base64.getDecoder().decode(msg)).toString();
System.out.println("============================\n");
return msgDec;
// return cipher.doFinal(Base64.getDecoder().decode(msg)).toString();
}
public String readMessage(User sender) throws Exception {
// Read file in inbox
File msgtoRead = new File(getInbox() + "/" + sender.getUsername() + ".msg");
FileInputStream keytoRead = new FileInputStream(getInbox() + "/" + sender.getUsername() + ".kgn");
// Read 128bits from filetoRead. That is encrypted key.
byte[] aesEnc = new byte[128];
keytoRead.read(aesEnc);
// Decrypted aes key for decode
byte[] aesDec = decryptAESKey(aesEnc);
SecretKeySpec aesKey = new SecretKeySpec(aesDec, "AES/CBC/PKCS5Padding");
// Read message
byte[] message = Files.readAllBytes(msgtoRead.toPath());
keytoRead.close();
// Decrypt message with loaded AES key (aesKey), return this
return new String(decryptMessage(message, aesKey));
}