Using “RSA/ECB/PKCS7Padding” with Bouncy Castle

2020-06-28 13:10发布

问题:

I tried to use "RSA/ECB/PKCS7Padding" for encryption. It is not supported in JCE. So I downloaded Bouncy Castle but it seems that Bouncy Castle also does not support this transformation. The following codes:

Security.insertProviderAt(new BouncyCastleProvider(), 1);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS7Padding");

throws

Caused by: java.security.NoSuchAlgorithmException: Cannot find any provider supporting RSA/ECB/PKCS7Padding
    at javax.crypto.Cipher.getInstance(Cipher.java:524)
    ....
Caused by: javax.crypto.NoSuchPaddingException: Unsupported padding PKCS7Padding
    at sun.security.pkcs11.P11RSACipher.engineSetPadding(P11RSACipher.java:129)
    at javax.crypto.Cipher$Transform.setModePadding(Cipher.java:360)
    at javax.crypto.Cipher.getInstance(Cipher.java:517)
    ... 4 more

Am I doing it correctly?

TIA.

回答1:

It's not possible to implement PKCS#7 padding as described in RFC2315 section 10.3 note 2 for all RSA key sizes:

Some content-encryption algorithms assume the input length is a multiple of k octets, where k > 1, and let the application define a method for handling inputs whose lengths are not a multiple of k octets. For such algorithms, the method shall be to pad the input at the trailing end with k - (l mod k) octets all having value k - (l mod k), where l is the length of the input. In other words, the input is padded at the trailing end with one of the following strings

and specifically:

This padding method is well-defined if and only if k < 256; methods for larger k are an open issue for further study.

Which means that you could implement this for RSA with 2048-bit keys, but already 4096-bit keys are too much for arbitrary data. This is why PKCS7Padding is reserved for block ciphers where each block is usually between 128 and 256-bit. This is also why libraries don't generally support this sort of combination.

The above specification contains everything you need to know to implement the PKCS#7 padding scheme. When you do, you will pad your data using it and then encrypt with RSA/ECB/NoPadding. You might run into the problem that although the padded plaintext and the key size are the same, the encryption doesn't work. That's because your padded plaintext might still exceed the key. You may need to add a zero byte to the front of the plaintext and only pad (0x00 + plaintext) so that the most significant bits are unset.



回答2:

Even if such a thing would exist, using RSA with PKCS#7 padding or a scheme directly derived from PKCS#7 padding would be insecure (or, to be more precise, it would not be CPA-secure).

What is infinitely more likely is that the client doesn't require PKCS#7 padding but that the encrypted data should be contained in a CMS message format. PKCS#7 is a predecessor of this format, the PKCS#7 padding is only a small part of this specification.

Bouncy Castle contains an implementation of this format:

Generators/Processors for S/MIME and CMS (PKCS7/RFC 3852).

currently contained in the bcpkix* JAR files.



回答3:

To summaries my commenta, According to the java7 doc, There list of standard algorithms must be supported by every implementation of JCE Cipher API. Bouncy castle support additional algorithms as well. I use "AES/ECB/PKCS7Padding" in my application. You could find supported algorithms by bouncy castle in algorithm section and "RSA/ECB/PKCS1Padding" or "RSA/NONE/PKCS1Padding" should work.