Java Cryptography Extension的密钥长度限制

时间:2014-09-15 08:45:34

标签: java cryptography bouncycastle jce jca

我知道Sun / Oracle JVM中的关键因为司法原因而受到限制。但据我所知, JCE(Java密码术扩展)的概念是用户可以选择自己的安全提供商来弥补这一限制。

出于这个原因,我试图将Bounce Castle作为安全提供程序与 Orcale JDK 1.7 结合使用。

为了找出我使用此代码的实际允许的keylegth:

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" );
}
}

Orcale JDK 1.7 的输出及其在提供商中的构建是:

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

但是当我通过切换到

来应用BC作为提供者时

Cipher.getInstance("AES", bouncyCastleProvider).getProvider()

它仍然显示有限的密钥长度(RSA除外),如下所示:

MaxAllowedKeyLength (for 'BC version 1.46' using current 'JCE Policy Files'):
  DES        = 64
  Triple DES = 128
  AES        = 128
  Blowfish   = 128
  RSA        = 2147483647

但是当我将JDK更改为 openJDK 时,我得到了这个输出:

MaxAllowedKeyLength (for 'BC version 1.46' using current 'JCE Policy Files'):
  DES        = 2147483647
  Triple DES = 2147483647
  AES        = 2147483647
  Blowfish   = 2147483647
  RSA        = 2147483647

这令我感到惊讶,因为我的印象不是JDK,而是安全提供商限制密钥长度。但我的测试表明,无论我选择哪个提供商,JDK都会限制密钥长度。

我的问题是:我有错吗?有没有办法释放Oracle JDK的密钥?

1 个答案:

答案 0 :(得分:10)

密钥长度限制在JCE中确定,即在JRE中,而不是在提供者中。 JCE在将限制移交给提供者之前检查限制。

正确的解决方法是安装unlimited strength policy files。虽然这可能是您的开发工作站的正确解决方案,但非技术用户在每台计算机上安装文件很快成为一个主要的麻烦(如果不是障碍)。使用您的程序分发文件无法;它们必须安装在JRE目录中(由于权限,它甚至可能是只读的)。

Bouncy Castle确实提供了自己的API,它与JCE是分开的。此API不强制执行任何密钥长度限制。这也不是一个理想的解决方案,因为API完全不同于JCE并且绑定到BC,BC是一个额外的1MB库,可以随程序一起分发。

最后,还有一个reflection workaround described here更详细。

OpenJDK没有任何密钥长度限制,这就是为什么它们都只是Integer.MAX_VALUE