Проблема с расшифровкой ключа AES с RSA и расшифровкой сообщения - PullRequest
0 голосов
/ 06 апреля 2020

Я работаю над приложением безопасного чата. У меня есть ключ 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));
}
...