首页 文章

Java安全:非法密钥大小或默认参数?

提问于
浏览
358

我之前曾问过一个关于这个问题的问题,但它没有得到正确答案而且无处可去 .

所以我已经澄清了关于这个问题的一些细节,我真的很想听听你如何解决这个问题或者我应该尝试什么的想法 .

我在我的Linux服务器上安装了 Java 1.6.0.12 ,下面的代码运行得非常完美 .

String key = "av45k1pfb024xa3bl359vsb4esortvks74sksr5oy4s5serondry84jsrryuhsr5ys49y5seri5shrdliheuirdygliurguiy5ru";
try {
    Cipher c = Cipher.getInstance("ARCFOUR");

    SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "ARCFOUR");
    c.init(Cipher.DECRYPT_MODE, secretKeySpec);

    return new String(c.doFinal(Hex.decodeHex(data.toCharArray())), "UTF-8");

} catch (InvalidKeyException e) {
    throw new CryptoException(e);
}

今天我在我的服务器用户上安装了 Java 1.6.0.26 ,当我尝试运行我的应用程序时,我得到以下异常 . 我的猜测是它与Java安装配置有关,因为它在第一个工作,但在更高版本中不起作用 .

Caused by: java.security.InvalidKeyException: Illegal key size or default parameters
    at javax.crypto.Cipher.a(DashoA13*..) ~[na:1.6]
    at javax.crypto.Cipher.a(DashoA13*..) ~[na:1.6]
    at javax.crypto.Cipher.a(DashoA13*..) ~[na:1.6]
    at javax.crypto.Cipher.init(DashoA13*..) ~[na:1.6]
    at javax.crypto.Cipher.init(DashoA13*..) ~[na:1.6]
    at my.package.Something.decode(RC4Decoder.java:25) ~[my.package.jar:na]
    ... 5 common frames omitted

第25行是: c.init(Cipher.DECRYPT_MODE, secretKeySpec);

Notes:
*服务器 1.6.0.12 java目录下的java.security几乎完全匹配 1.6.0.26 java.security文件 . 第一个没有其他提供者 .
*上一个问题是here .

16 回答

  • 1

    从Java 9或8u151开始,您可以在文件中使用注释:

    <JAVA_HOME>/jre/lib/security/java.security
    

    并改变:

    #crypto.policy=unlimited
    

    crypto.policy=unlimited
    
  • 4

    “Java密码学扩展(JCE)无限强度管辖政策文件6”

    http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html

  • 2

    我也遇到了这个问题,但在用已下载的(从JCE)替换现有的一个后,解决了这个问题 . 新的加密文件提供了无限的力量 .

  • 662

    可以在此处找到JRE / JDK / Java 8管辖区文件:

    Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8 Download

    就像詹姆斯上面所说:
    ${java.home}/jre/lib/security/ 中安装文件 .

  • 1

    这是 code only solution . 无需下载或搞乱配置文件 .

    这是一个基于反射的解决方案, tested on java 8

    在程序的早期调用此方法一次 .

    //进口

    import javax.crypto.Cipher;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Modifier;
    import java.util.Map;
    

    //方法

    public static void fixKeyLength() {
        String errorString = "Failed manually overriding key-length permissions.";
        int newMaxKeyLength;
        try {
            if ((newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES")) < 256) {
                Class c = Class.forName("javax.crypto.CryptoAllPermissionCollection");
                Constructor con = c.getDeclaredConstructor();
                con.setAccessible(true);
                Object allPermissionCollection = con.newInstance();
                Field f = c.getDeclaredField("all_allowed");
                f.setAccessible(true);
                f.setBoolean(allPermissionCollection, true);
    
                c = Class.forName("javax.crypto.CryptoPermissions");
                con = c.getDeclaredConstructor();
                con.setAccessible(true);
                Object allPermissions = con.newInstance();
                f = c.getDeclaredField("perms");
                f.setAccessible(true);
                ((Map) f.get(allPermissions)).put("*", allPermissionCollection);
    
                c = Class.forName("javax.crypto.JceSecurityManager");
                f = c.getDeclaredField("defaultPolicy");
                f.setAccessible(true);
                Field mf = Field.class.getDeclaredField("modifiers");
                mf.setAccessible(true);
                mf.setInt(f, f.getModifiers() & ~Modifier.FINAL);
                f.set(null, allPermissions);
    
                newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES");
            }
        } catch (Exception e) {
            throw new RuntimeException(errorString, e);
        }
        if (newMaxKeyLength < 256)
            throw new RuntimeException(errorString); // hack failed
    }
    

    积分:Delthas

  • 1

    对于这个问题here进行了简短的讨论 . 它links to似乎消失了,但其中一个响应可能就是你所需要的:

    实际上,将US_export_policy.jar和local_policy.jar从core / lib / jce复制到$ JAVA_HOME / jre / lib / security有帮助 . 谢谢 .

  • 26

    由于美国的限制,默认JDK仅通过128位密钥支持加密 . 因此,要支持256位长密钥加密,我们必须在 $JAVA_HOME/java-8-oracle/jre/lib/security 文件夹中替换 local_policy.jarUS_export_policy.jars ,否则它将给出:

    java.security.InvalidKeyException:非法密钥大小或默认值

    从链接可以理解 jar 和详细的概念:

    easybook4u.com

  • 0

    您很可能现在没有安装无限强度文件 .

    您可能需要下载此文件:

    Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6

    Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 7 Download

    Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8 Download(仅适用于Java 8 u162之前的版本)

    从zip中提取jar文件并将其保存在 ${java.home}/jre/lib/security/ 中 .

  • 48

    对于JAVA 7,下载链接为jce-7-download

    将两个下载的jar复制到Java \ jdk1.7.0_10 \ jre \ lib \ security中
    备份较旧的 jar 以便更安全 .

    对于JAVA 8,下载链接为jce-8-download
    将下载的jar复制到Java \ jdk1.8.0_45 \ jre \ lib \ security中
    备份较旧的 jar 以便更安全 .

  • 26

    使用Windows 7 x64,Eclipse和JDK 1.6.0_30时遇到了同样的错误 . 在JDK安装文件夹中有一个 jre 文件夹 . 当我将上述 jar 添加到JDK的lib / security文件夹时没有运气,这让我一开始就放弃了 . 完整路径:

    C:\Program Files\Java\jdk1.6.0_30\jre\lib\security
    

    下载this archivejce 文件夹中包含的文件并将其解压缩到该文件夹中 .

  • 5

    如果您正在使用带有apt的Linux发行版并添加了webupd8 PPA,则只需运行该命令即可

    apt-get install oracle-java8-unlimited-jce-policy
    

    Other updates:

    • 无限强度管辖权政策文件包含在 Java 9 中,默认使用

    • Java 8 Update 161 开始,Java 8默认为无限强度管辖政策 .

    • Java 8 Update 151 开始,无限强度管辖政策包含在Java 8中,但默认情况下不使用 . 要启用它,您需要编辑 <java_home>/jre/lib/security (对于JDK)或 <java_home>/lib/security (对于JRE)中的java.security文件 . 取消注释(或包括)该行

    crypto.policy=unlimited

    确保使用以管理员身份运行的编辑器编辑文件 . 策略更改仅在重新启动JVM后生效

    Java 8 Update 151 之前,其他答案保持有效 . 下载JCE Unlimited Strength Jurisdiction政策文件并替换 .

    How to install Java Cryptography Extension (JCE) unlimited strength jurisdiction policy files

  • 15

    默认情况下,Java仅支持AES 128位(16字节)密钥大小进行加密 . 如果您不需要超过支持的默认值,则可以在使用 Cipher 之前将键修剪为适当的大小 . 有关默认支持的密钥,请参阅javadoc .

    这是一个生成密钥的示例,该密钥可以在不修改策略文件的情况下与任何JVM版本一起使用 . 请自行决定使用 .

    这是一篇很好的文章,关于密钥128到256密钥大小是否重要AgileBits Blog

    SecretKeySpec getKey() {
        final pass = "47e7717f0f37ee72cb226278279aebef".getBytes("UTF-8");
        final sha = MessageDigest.getInstance("SHA-256");
    
        def key = sha.digest(pass);
        // use only first 128 bit (16 bytes). By default Java only supports AES 128 bit key sizes for encryption.
        // Updated jvm policies are required for 256 bit.
        key = Arrays.copyOf(key, 16);
        return new SecretKeySpec(key, AES);
    }
    
  • 5

    如果您安装JRE,问题是 jre\lib\security 文件夹中 default_local.policy 文件 contentcontent

    // Some countries have import limits on crypto strength. This policy file
    // is worldwide importable.
    
    grant {
        permission javax.crypto.CryptoPermission "DES", 64;
        permission javax.crypto.CryptoPermission "DESede", *;
        permission javax.crypto.CryptoPermission "RC2", 128,
                                         "javax.crypto.spec.RC2ParameterSpec", 128;
        permission javax.crypto.CryptoPermission "RC4", 128;
        permission javax.crypto.CryptoPermission "RC5", 128,
              "javax.crypto.spec.RC5ParameterSpec", *, 12, *;
        permission javax.crypto.CryptoPermission "RSA", *;
        permission javax.crypto.CryptoPermission *, 128;
    };
    

    如果您不需要全球有效设置,您只需编辑此文件并将内容更改为

    // Country-specific policy file for countries with no limits on crypto strength.
    grant {
        // There is no restriction to any algorithms.
        permission javax.crypto.CryptoAllPermission;
    };
    

    这是如果你从Oracle下载JCE会得到什么 .

  • 38

    对于Java 9,Java 8u161Java 7u171Java 6u181,默认情况下现在禁用此限制 . 见issue in Java Bug Database .


    Java 8u151开始,您可以以编程方式禁用限制 .

    在旧版本中,必须单独下载和安装JCE管辖区文件,以允许JDK使用无限制的加密 . 不再需要下载和安装步骤 .

    相反,您现在可以在首次使用JCE类之前调用以下行(即最好在应用程序启动后立即调用):

    Security.setProperty("crypto.policy", "unlimited");
    
  • 16

    在Java中,默认情况下AES支持128位密钥,如果您计划使用192位或256位密钥,则java编译器将抛出非法密钥大小异常,您将获得该密钥 .

    解决方案是胜利者和James建议的,你需要根据你的JRE版本(java6,java7或java8)下载JCE(Java Cryptography Extension) .

    JCE zip包含以下JAR:

    • local_policy.jar

    • US_export_policy.jar

    你需要从 <JAVA_HOME>/jre/lib/security 替换这些jar . 如果您使用的是unix系统,则可能会引用 /home/urs/usr/lib/jvm/java-<version>-oracle/

    有时只是替换local_policy.jar,安全文件夹中的US_export_policy.jar在unix上不起作用,所以我建议先将安全文件夹复制到桌面,替换jar的@ Desktop / security文件夹,从/ jre / lib中删除安全文件夹/&将Desktop安全性文件夹移动到/ jre / lib / .

    例如:: sudo mv security /usr/lib/jvm/java-7-oracle/jre/lib

  • 16

    有两种方法可以解决这个问题

    option number 1 : 使用长度较短的证书RSA 2048

    option number 2 : 无论你使用java http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html,你都会在 jre\lib\security 中更新两个 jar

    或者您使用IBM websphere或使用其java的任何应用程序服务器 . 我遇到的主要问题是我使用了最大长度的认证,当我在websphere上部署耳朵时,会抛出相同的异常

    Java Security: Illegal key size or default parameters?
    

    我用两个 jar 更新了websphere中的java intsalled文件夹https://www14.software.ibm.com/webapp/iwm/web/reg/pick.do?source=jcesdk&lang=en_US

    你可以在链接中检查参考https://www-01.ibm.com/support/docview.wss?uid=swg21663373

相关问题