I am aware that the keylenght in the Sun/Oracle JVM is limited for judical reasons. However as far as I understood the concept of the JCE (Java Cryptography Extension) is that a user can choose it's own security provider to compensate this limitation.
For this reason I am trying to operate the Bounce Castle as security provider in conjunction with the Orcale JDK 1.7.
In order to figure out the actual allowed keylegths I am using this code:
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import java.security.GeneralSecurityException;
import java.security.Provider;
import java.security.Security;
public class JCETest {
public static void main( String[] args ) throws GeneralSecurityException
{
BouncyCastleProvider bouncyCastleProvider = new BouncyCastleProvider();
Security.addProvider(bouncyCastleProvider);
System.out.println( "\nSecurity-Provider:" );
for( Provider prov : Security.getProviders() ) {
System.out.println( " " + prov + ": " + prov.getInfo() );
}
System.out.println( "\nMaxAllowedKeyLength (for '" + Cipher.getInstance("AES").getProvider() + "' using current 'JCE Policy Files'):\n"
+ " DES = " + Cipher.getMaxAllowedKeyLength( "DES" ) + "\n"
+ " Triple DES = " + Cipher.getMaxAllowedKeyLength( "Triple DES" ) + "\n"
+ " AES = " + Cipher.getMaxAllowedKeyLength( "AES" ) + "\n"
+ " Blowfish = " + Cipher.getMaxAllowedKeyLength( "Blowfish" ) + "\n"
+ " RSA = " + Cipher.getMaxAllowedKeyLength( "RSA" ) + "\n" );
}
}
The output for the Orcale JDK 1.7 and it's build in providers is:
Security-Provider:
SUN version 1.7: SUN (DSA key/parameter generation; DSA signing; SHA-1, MD5 digests; SecureRandom; X.509 certificates; JKS keystore; PKIX CertPathValidator; PKIX CertPathBuilder; LDAP, Collection CertStores, JavaPolicy Policy; JavaLoginConfig Configuration)
SunRsaSign version 1.7: Sun RSA signature provider
SunEC version 1.7: Sun Elliptic Curve provider (EC, ECDSA, ECDH)
SunJSSE version 1.7: Sun JSSE provider(PKCS12, SunX509 key/trust factories, SSLv3, TLSv1)
SunJCE version 1.7: SunJCE Provider (implements RSA, DES, Triple DES, AES, Blowfish, ARCFOUR, RC2, PBE, Diffie-Hellman, HMAC)
SunJGSS version 1.7: Sun (Kerberos v5, SPNEGO)
SunSASL version 1.7: Sun SASL provider(implements client mechanisms for: DIGEST-MD5, GSSAPI, EXTERNAL, PLAIN, CRAM-MD5, NTLM; server mechanisms for: DIGEST-MD5, GSSAPI, CRAM-MD5, NTLM)
XMLDSig version 1.0: XMLDSig (DOM XMLSignatureFactory; DOM KeyInfoFactory)
SunPCSC version 1.7: Sun PC/SC provider
BC version 1.46: BouncyCastle Security Provider v1.46
MaxAllowedKeyLength (for 'SunJCE version 1.7' using current 'JCE Policy Files'):
DES = 64
Triple DES = 128
AES = 128
Blowfish = 128
RSA = 2147483647
But when I apply BC as provider by switching to
Cipher.getInstance("AES", bouncyCastleProvider).getProvider()
It still shows me the limited key length (except for RSA) like this:
MaxAllowedKeyLength (for 'BC version 1.46' using current 'JCE Policy Files'):
DES = 64
Triple DES = 128
AES = 128
Blowfish = 128
RSA = 2147483647
But when I change the JDK to openJDK, I get this output:
MaxAllowedKeyLength (for 'BC version 1.46' using current 'JCE Policy Files'):
DES = 2147483647
Triple DES = 2147483647
AES = 2147483647
Blowfish = 2147483647
RSA = 2147483647
This astonishes me since I was under the impression that not the JDK but the security-provider limiting the key length. But my tests are showing that obviously the JDK is limiting the key length, no matter which provider I choose.
My question is: Did I got something wrong? Is there a way to unleash the keyleght with the Oracle JDK?
The key length limits are determined in the JCE, that is in the JRE, not in the provider. JCE checks the limits before it hands over to the provider.
The correct solution to this is to install the unlimited strength policy files. While this is probably the right solution for your development workstation, it quickly becomes a major hassle (if not a roadblock) to have non-technical users install the files on every computer. There is no way to distribute the files with your program; they must be installed in the JRE directory (which may even be read-only due to permissions).
Bouncy Castle does provide its own API though, which is separate from the JCE. This API does not enforce any key length limits. This is not an ideal solution either, as the API is totally different from the JCE and bound to BC, and BC is an extra 1MB library to distribute with your program.
Finally, there is also a reflection workaround described here in more detail.
OpenJDK does not have any key length limits, which is why they are all simply Integer.MAX_VALUE
.