我知道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的密钥?
答案 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
。