Java:从applet为AES256修补客户端安全策略

dre*_*rew 5 java security encryption applet cryptography

我在商业Web应用程序中需要AES256加密/解密.目前一切都很好,密钥大小为128.这在加密方面并不令人满意,所以我的问题是如何最好地绕过这个问题而不需要用户手动安装任何东西.

我有来自Oracle的无限制管辖jar文件,但我不知道在用户的JRE/lib/security目录中替换这些文件是否与旧版本兼容.显然我不想破坏用户的JRE.此外,我对我的JRE安全目录有写权限,但我认为某些用户不具备这些权限.

有没有一个简单的方法来解决这个问题,或者我是坚持使用弱加密还是可能有问题的用户步骤?


更新"unrestricting" javax.crypto.JceSecurity

@ntoskml你是对的.getMaxAllowedKeyLength仍然返回有限的密钥大小,但加密成功,密钥大小== 256 :).如果有强加密功能,我会更新我的测试方法并设置密钥大小.谢谢

>>> from javax.crypto import Cipher
>>> Cipher.getMaxAllowedKeyLength("AES")
128
>>> from java.lang import Class
>>> c = Class.forName("javax.crypto.JceSecurity")
>>> isRestricted = c.getDeclaredField("isRestricted")
>>> isRestricted.setAccessible(True)
>>> isRestricted.set(None, False)
>>> isRestricted.get(None)
False
>>> Cipher.getMaxAllowedKeyLength("AES")
128
>>> from javax.crypto import KeyGenerator
>>> kge = KeyGenerator.getInstance("AES")
>>> kge.init(256)
>>> aesKey = kgen.generateKey()
>>> c2 = Cipher.getInstance("AES")
>>> c2.init(Cipher.ENCRYPT_MODE, aesKey)
>>> c2.doFinal("test")
array('b', [-81, 99, -61, -51, 93, -42, -68, -28, 107, 59, -109, -98, -25, 127, 37, 23])
Run Code Online (Sandbox Code Playgroud)

重启Jython控制台后的测试用例

>>> # Reflection as above
>>> isRestricted.get(None)
True
>>> kge.init(256)
>>> aesKey = kge.generateKey()
>>> c2.init(Cipher.ENCRYPT_MODE, aesKey)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
        at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1011)
        at javax.crypto.Cipher.implInit(Cipher.java:786)
        at javax.crypto.Cipher.chooseProvider(Cipher.java:849)
        at javax.crypto.Cipher.init(Cipher.java:1213)
        at javax.crypto.Cipher.init(Cipher.java:1153)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)

java.security.InvalidKeyException: java.security.InvalidKeyException: Illegal key size or default parameters
Run Code Online (Sandbox Code Playgroud)

宾果:)感谢分享@ntoskml

nto*_*rnl 5

编辑:这是这个问题的更新答案:如何避免在部署应用程序时安装"Unlimited Strength"JCE策略文件?


只需使用几行反射就可以禁用键大小限制.我们在我们的程序中使用此方法,该方法需要访问256位加密以实现互操作性.

private static void removeCryptographyRestrictions() {
    if (!isRestrictedCryptography()) {
        return;
    }
    try {
        java.lang.reflect.Field isRestricted;
        try {
            final Class<?> c = Class.forName("javax.crypto.JceSecurity");
            isRestricted = c.getDeclaredField("isRestricted");
        } catch (final ClassNotFoundException e) {
            try {
                // Java 6 has obfuscated JCE classes
                final Class<?> c = Class.forName("javax.crypto.SunJCE_b");
                isRestricted = c.getDeclaredField("g");
            } catch (final ClassNotFoundException e2) {
                throw e;
            }
        }
        isRestricted.setAccessible(true);
        isRestricted.set(null, false);
    } catch (final Throwable e) {
        logger.log(Level.WARNING,
                "Failed to remove cryptography restrictions", e);
    }
}

private static boolean isRestrictedCryptography() {
    return "Java(TM) SE Runtime Environment"
            .equals(System.getProperty("java.runtime.name"));
}
Run Code Online (Sandbox Code Playgroud)

但是,我们的程序不是applet,我不确定applet是否可以访问反射API.

关于合法性的问题也仍然存在.有这个限制的原因.如果您担心,请咨询律师.

如果可能,请尝试将其保留为128位密钥.即使考虑到摩尔定律,打破128位AES也需要花费数十亿年的时间.更长的密钥在现实世界中没有任何好处 - 特别是当密钥来自密码时,密码无论如何都没有任何接近256位的熵.