Изменение дешифрования / шифрования шифрования

Я перерабатываю код, который расшифровывает данные, надеясь, что я смогу зашифровать его и получить те же самые данные, с которых он начинался, по причинам, которые заставили бы этот вопрос слишком долго и не по теме .

public void Test() throws Exception {

    String pk_enc = //...

    String hashStr_64 = //...

    byte[] hashStr_encrypted = Base64.decode(hashStr_64);

    X509EncodedKeySpec e = new X509EncodedKeySpec(Base64.decode(pk_enc));
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    RSAPublicKey RSApublicKey = (RSAPublicKey) keyFactory.generatePublic(e);
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
    cipher.init(2, RSApublicKey); // ƈ' means decrypt
    byte[] hashStr_decrypted = cipher.doFinal(hashStr_encrypted);
    String hashStr_result = new String(hashStr_decrypted);

    // Now in reverse...
    Cipher cipher1 = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
    // instantiating a new cipher or using the original one makes no difference
    cipher1.init(1, RSApublicKey); // Ƈ' means encrypt
    byte[] hashStr_encrypted_reverse = cipher1.doFinal(hashStr_decrypted);
    String hashStr_64_reverse = Base64.encode(hashStr_encrypted_reverse);
}

Весь код до // Now in reverse... не может быть изменен, но это не значит, что невозможно преобразовать hashStr_result обратно в hashStr_64 , правильно?

Однако код, который я написал после, должен делать именно это, не работает. hashStr_encrypted_reverse отличается от hashStr_encrypted . Почему это и как я могу это исправить?

Еще один признак того, что что-то пошло не так в шифровании, - это то, что произойдет, если я попытаюсь снова расшифровать ...

// Decrypt again
Cipher cipher2 = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
cipher2.init(2, RSApublicKey);
byte[] hashStr_decrypted_again = cipher.doFinal(hashStr_encrypted_reverse);

Это бросает:

javax.crypto.BadPaddingException

Мне все равно, но, возможно, это могло бы помочь ответить на вопрос.

Всего 2 ответа


Терминология будет путать. Существует 4 операции RSA, которые лучше всего описываются как: подписание, проверка, шифрование, дешифрование. Сопоставляя их на более низком уровне и используя только язык шифрования и дешифрования, они отображают следующее:

контрольная пара

  • Подпись -> шифрование с закрытым ключом
  • проверка -> дешифрование с помощью открытого ключа

шифровать-расшифровать пару

  • шифрование -> шифрование открытым ключом
  • дешифрование -> дешифрование с помощью закрытого ключа.

Как вы можете видеть, каждая пара операций имеет закрытый ключ с одной стороны, а открытый ключ - с другой.


Как сказал в своем комментарии @JamesKPolk, это не то, как работает RSA. RSA - это асимметричный алгоритм шифрования: есть два ключа, открытый и закрытый. Симметричный алгоритм (например, AES) имеет один ключ, который используется как для шифрования, так и для дешифрования, и этот ключ должен храниться в безопасности, за исключением отправляющей и принимающей сторон.

Почему асимметричное шифрование?

  • Вы можете зашифровать с помощью открытого ключа (обычно чужого ключа, который они поделили с вами), и они должны использовать свой закрытый ключ для его расшифровки. Любой может иметь открытый ключ (поэтому он является общедоступным ), но он не может использоваться для чтения зашифрованного сообщения. Здесь у вас проблемы.
  • Кроме того, вы можете зашифровать сообщение с помощью закрытого ключа (как правило, собственного), а кто-то еще может использовать ваш открытый ключ для его расшифровки. Так реализуются цифровые подписи: например, вы должны зашифровать дайджест документа, и любой может проверить вашу подпись, если у них есть открытый ключ, но никто другой не мог его подписать.

Есть идеи?

10000