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

Java Security: Illegal key size or default parameters?

我之前问过一个问题,但没有得到正确的回答,也没有得到任何指导。

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

我在我的Linux服务器上安装了Java1.60.12,下面的代码运行得非常好。

1
2
3
4
5
6
7
8
9
10
11
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);
}

今天,我在我的服务器用户上安装了Java1.60.26,当我尝试运行我的应用程序时,我得到了下面的例外。我猜它可能与Java安装配置有关,因为它在第一个配置中起作用,但在后面的版本中不起作用。

1
2
3
4
5
6
7
8
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);

笔记:*服务器的1.60.12 Java目录的JavaSturnices几乎完全与1.60.26JavaAdvices文件匹配。第一个提供程序中没有其他提供程序。*前面的问题在这里。


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

您可能需要下载此文件:

Java加密扩展(JCE)无限强度管辖权策略文件6

Java加密扩展(JCE)无限强度管辖权策略文件7下载

Java加密扩展(JCE)无限强度管辖权策略文件8下载(仅适用于Java 8 U162之前的版本)

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


JRe/JDK/Java 8管辖权文件可以在这里找到:

Java加密扩展(JCE)无限强度管辖权策略文件8下载

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


对于Java 7,下载链接是JCE-7下载

在Javajdk1.7.0y10jrLabStand中复制两个下载的JAR把旧罐子放在安全的一边。

对于Java 8,下载链接是JCE-8下载在Javajdk1.80y45 jrLib安全中复制下载的JAR把旧罐子放在安全的一边。


使用Java 9、Java8U161、Java7U171和Java6U181,默认情况下禁用该限制。参见JavaBug数据库中的问题。

从Java8U151开始,您可以以编程方式禁用限制。

In older releases, JCE jurisdiction files had to be downloaded and installed separately to allow unlimited cryptography to be used by the JDK. The download and install steps are no longer necessary.

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

1
Security.setProperty("crypto.policy","unlimited");


这是一个仅限代码的解决方案。无需下载或处理配置文件。

它是基于反射的解决方案,在Java 8上进行了测试

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

//进口

1
2
3
4
5
import javax.crypto.Cipher;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Map;

/方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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
}

学分:德尔塔


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

解决方案是VICTRO&AMP.杰姆斯建议,您需要按照JRE版本(Java6、Java7或Java8)下载JCE(Java加密扩展)。

jce-zip包含以下jar:

  • 本地策略.jar
  • 美国出口政策.jar
  • 你需要从你的/jre/lib/security中替换这些罐子。如果您使用的是UNIX系统,则可能会引用/home/urs/usr/lib/jvm/java--oracle/

    有时仅仅替换local_policy.jar,安全文件夹中的us_export_policy.jar在UNIX上不起作用,因此我建议首先将安全文件夹复制到桌面,替换jar的@desktop/security文件夹,从/jre/lib/中删除安全文件夹,将桌面安全文件夹移动到/jre/lib/。

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


    "Java加密扩展(JCE)无限强度管辖权策略文件6"

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


    我在使用Windows7x64、Eclipse和JDK1.6.0_30时也遇到了同样的错误。在jdk安装文件夹中有一个jre文件夹。当我把前面提到的jar添加到jdk的lib/security文件夹中时,这一点让我一开始很不高兴。完整路径:

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

    下载并将此存档的jce文件夹中包含的文件解压缩到该文件夹中。


    这里有一个关于这个问题的简短讨论。它链接到的页面似乎已不存在,但其中一个响应可能是您需要的:

    Indeed, copying US_export_policy.jar and local_policy.jar from core/lib/jce to $JAVA_HOME/jre/lib/security helped. Thanks.


    如果安装jre:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 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;
    };

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

    1
    2
    3
    4
    5
    // 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所得到的。


    我也得到了这个问题,但是在用下载的(从JCE)替换现有的问题之后,解决了这个问题。新的加密文件提供了无限的强度。


    如果您在apt中使用Linux发行版并添加了webup8 ppa,那么只需运行命令即可。

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

    其他更新:

  • 无限的权限管辖策略文件包含在Java 9中,默认使用
  • 从Java 8更新161开始,Java 8默认为无限强度管辖权策略。
  • 从Java 8更新151开始,无限的权限管辖策略包含在Java 8中,但默认情况下不使用。要启用它,您需要编辑EDOCX1(对于jdk)或EDOCX1(对于jre)中的java.security文件。取消注释(或包括)行

    crypto.policy=unlimited

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

  • 在Java 8更新151之前,其余的答案保持有效。下载JCE无限制强度权限策略文件并替换。

    有关详细信息,请参阅下面的我的个人博客文章-如何安装Java加密扩展(JCE)无限强度管辖权策略文件


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

    这是在不修改策略文件的情况下生成可与任何JVM版本一起使用的密钥的示例。自行使用。

    在AgileBits博客上有一篇关于128到256个密钥大小是否重要的好文章

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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);
    }


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

    java.security.InvalidKeyException: Illegal key size or default

    JAR和详细概念都可以从以下链接中理解:

    EasyBooo4UCOM


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

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

    和变化:

    1
    #crypto.policy=unlimited

    1
    crypto.policy=unlimited

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

    选项1:使用长度较短的RSA 2048证书

    选项2:您将在jre\lib\security中更新两个jar。无论使用Java HTTP://www. Oracle .COM/TeaTeWorks/Java/JavaSe/DeWalss/JCIE-6下载-429 243.HTML

    或者使用IBM WebSphere或使用其Java的任何应用服务器。当我在WebSphere上部署EAR时,我面临的主要问题是使用最大长度的认证,引发了相同的异常

    1
    Java Security: Illegal key size or default parameters?

    我用两个JAR更新WebSphere中的Java ItalsLED文件夹https://ww14.software.ibm.com/webapp/iwm/web/reg/pick.do?来源=jcesdk&lang=en_-us

    您可以在链接https://www-01.ibm.com/support/docview.wss中查看参考?UID= SWG2166333


    你得去那里

    /JDK1.80Y152Y/JRE/LIB/安全性Java.安全性并取消注释

    1
    #crypto.policy=unlimited

    1
    crypto.policy=unlimited