java - Java 加密扩展的 key 长度限制

标签 java cryptography bouncycastle jce jca

我知道出于司法原因,Sun/Oracle JVM 中的 key 长度是有限的。然而,据我了解,JCE(Java 加密扩展) 的概念是用户可以选择自己的安全提供程序来补偿此限制。

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

为了找出实际允许的 keylegths,我正在使用此代码:

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()

它仍然像这样向我显示有限的 key 长度(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

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

我的问题是:我做错了什么吗?有没有办法释放 Oracle JDK 的关键作用?

最佳答案

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

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

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

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

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

关于java - Java 加密扩展的 key 长度限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25844026/

相关文章:

java - 不支持的 major.minor 版本 51.0,但所有内容都设置为 JDK 1.6

c# - 连接字符串时如何插入空格 ("")?

java - IllegalBlockSizeException 尝试解密字符串

c# - 需要使用 C# 进行 BouncyCaSTLe PGP 文件加密的示例

java - 如何将 PKCS10CertificationRequest 打印为字符串?

java - 允许一次登录一台设备

java - SparkJava 异常 java.lang.NoClassDefFoundError : org/eclipse/jetty/websocket/server/pathmap/PathSpec

javascript - 好的斯坦福 Javascript 加密库 (SJCL) 示例? (JS密码学)

ios - CCCrypt 崩溃(EXC_BAD_ACCESS)

java - 如何在 Bouncy CaSTLe JSSE (1.68) 中启用命名组?