6

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?

Randy
  • 1,299
  • 2
  • 10
  • 23
  • The same key length for symmetric and asymmetric ciphers doesn't make much sense. Also DES is limited to 64 (56 effective) bits by design, as Triple DES is limited to 112 effective bits (64*2 technical, where people would ususally use the same key on two of the three DES-sequences. The only limit that needs to be raised to increase security is the one for AES (and maybe Blowfish, not sure there). All this to say, that `MaxAllowedKeyLength` of `2147483647` doesn't make any sense for AES, because the max key length of AES is 256 bits by design. – mwhs Sep 15 '14 at 08:59
  • 1
    Just one more comment: for short- and medium-term security there is no need to increase the AES key length of 128 bits. The currently best known attack to AES with a 128 bit key has a complexity of 126 bits. This means that it would take `2^126` steps to recover the key. – mwhs Sep 15 '14 at 09:08
  • @mwhs Thank you, this is actually helping me. I was just confused about the different output of the openJDK. – Randy Sep 15 '14 at 09:32
  • possible duplicate of ["Unlimited Strength" JCE Policy Files](http://stackoverflow.com/questions/1179672/unlimited-strength-jce-policy-files) – ntoskrnl Sep 15 '14 at 11:00
  • As explained in the question above, the key length limits are not determined in the provider, but in the JRE. OpenJDK does not limit key lengths, so the limits are simply `Integer.MAX_VALUE`. – ntoskrnl Sep 15 '14 at 11:02
  • @ntoskrnl For future reference, while that question is an excellent resource, it isn't a duplicate. Questions should be closed only if the question itself is a duplicate and I don't think these two are. – Duncan Jones Sep 15 '14 at 11:25
  • @Duncan Fair enough, I posted an answer here that is perhaps more relevant to this question. – ntoskrnl Sep 15 '14 at 12:43

1 Answers1

12

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.

ntoskrnl
  • 5,714
  • 2
  • 27
  • 31
  • Thank you very much! Just on futher question: We are working on an embedded device which uses openJDK anyway. What should be prefered openJDK/JCE or the Bouncycastle API to provide the highest quality of encryption? – Randy Sep 15 '14 at 13:28
  • 1
    @Randy Encryption algorithms are standard, so it doesn't make a difference from that perspective. But the BC library basically duplicates functionality already included in the JRE, so I would go with the included provider. I don't know about embedded environments, but you also get intrinsics and other optimizations with SunJCE on x86 and sparc. – ntoskrnl Sep 15 '14 at 14:04
  • Reflection workaround no longer works in Java8 https://github.com/jruby/jruby/issues/4101 – bbozo Oct 27 '16 at 10:06