Search code examples
javac++encryptionopensslbouncycastle

RSA_NO_PADDING is different between Java and C++?


In Java ,I use Bouncy Castle encrypt data using padding:

Cipher cipher = Cipher.getInstance("RSA/ECB/NOPADDING");

The Base64 encoded result is :

AAAAAAAAAAAAAAAAA.....H6hBDxOrCI0K8fd13vOYtsKdo4SI3VZTa3...

Ant it won't change every time.

And in C++, I use OpenSSL library to encrypt data :

RSA_public_encrypt(rsa_len, (unsigned char *)str, (unsigned char*)p_en, p_rsa, RSA_NO_PADDING);

The Base64 encoded result is :

bxeeBPfFRJsLOzJLMS/qGKtDe1zPw8H491QsE+uuRRay6/ep69fqv386j8...

And it will change every time I run code.

I read Wiki and know RSA encryption is a deterministic encryption algorithm.

So the result of java is reasonable and my question is:

  1. Is "AAAAAAAA..." padding is correct for no padding of java?
  2. What has openssl done in C++ code to cause the result seems to have padding and time varying?

Update

I found that my java code is correct. And When calling RSA_private_encrypt with RSA_NO_PADDING, the input must have the same size as the RSA key modulus. .After I fill my input to 256 bytes , openssl can decrypt the java encrypt result.

So, the question become to:

What has openssl done to fill the input to reach the required length?

Update

At last, I don't have much time to research the OAEP in openssl.And the server use this unsafe way due to history problem. So I fill my input with byte 0.Just like:

This is input                         //<-----following many ASCII 0 char to reach 256 bytes length

But this will cause the output be the same. Any other code should prevent this in either server and client.


Solution

  • And it will change every time I run code.

    Yes. That's due to Optimal Asymmetric Encryption Padding (OAEP).

    If you send the same message twice, like Attack at dawn, your adversary who observes the message won't be able to learn anything (or make an educated guess) when he sees the message again. The property is known as semantic security or Ciphertext Indistinguishability (IND-CPA).

    Here's a related talk by Dr. Matt Green on PKCS padding versus OAEP padding. Its very approachable: A bad couple of years for the cryptographic token industry.


    Is "AAAAAAAA..." padding is correct for no padding of java?

    Possibly. I believe its just a string of leading 0x00 bytes that have been Base64 encoded.


    What has openssl done in C++ code to cause the result seems to have padding and time varying?

    Its using OAEP.


    So, the question become to:
    What has openssl done to fill the input to reach the required length?

    Its using OAEP.

    The question may become: why is Java not using it because lack of OAEP means you could leak information for each message encrypted.