Search code examples
javaencryptionrsabadpaddingexception

Cipher decryption / encryption changing results


I'm reverse engineering some code which is decrypting data, hoping I'll be able to encrypt it back and obtain the same data it started with, for reasons that would make this question too long and off-topic.

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); // '2' 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); // '1' means encrypt
    byte[] hashStr_encrypted_reverse = cipher1.doFinal(hashStr_decrypted);
    String hashStr_64_reverse = Base64.encode(hashStr_encrypted_reverse);
}

All the code before // Now in reverse... cannot be changed, but that doesn't mean it's impossible to convert hashStr_result back to hashStr_64, right?

However, the code I've wrote after, that should do just that, doesn't work. hashStr_encrypted_reverse is different from hashStr_encrypted. Why is that and how can I fix it?

Another sign that something went wrong in the encryption is what happens if I try to decrypt again...

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

This throws:

javax.crypto.BadPaddingException

I don't really care, but maybe it could help answer the question.


Solution

  • Terminology will be confusing. There are 4 RSA operations, best described as: signing, verifying, encrypting, decrypting. Mapping these to a lower-level and using only the language of encryption and decryption, these map as follows:

    sign-verify pair

    • signing -> encrypt with private key
    • verifying -> decrypt with public key

    encrypt-decrypt pair

    • encrypting -> encrypt with public key
    • decrypting -> decrypt with private key.

    As you can see, each pair of operations has the private key on one side and the public key on the other.