Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Key length limit with Java Cryptography Extension

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?

like image 823
Randy Avatar asked Sep 15 '14 08:09

Randy


1 Answers

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.

like image 157
ntoskrnl Avatar answered Oct 13 '22 01:10

ntoskrnl