检查Unlimited Cryptography是否可用

时间:2011-10-31 12:15:53

标签: java jce

如何在Java代码中检查当前JVM是否具有可用的无限强度加密?

9 个答案:

答案 0 :(得分:43)

与Dan Cruz的答案一脉相承,但只有一行代码而没有例外:

boolean limit = Cipher.getMaxAllowedKeyLength("RC5")<256;

所以完整的程序可能是:

import javax.crypto.Cipher;

public class TestUCE {
  public static void main(String args[]) throws Exception {
    boolean unlimited =
      Cipher.getMaxAllowedKeyLength("RC5") >= 256;
    System.out.println("Unlimited cryptography enabled: " + unlimited);
  }
}

答案 1 :(得分:33)

如果您使用的是Linux并且已安装JDK(但Beanshell不可用),则可以使用随JDK提供的runscript命令进行检查。

jrunscript -e 'exit (javax.crypto.Cipher.getMaxAllowedKeyLength("RC5") >= 256 ? 0 : 1);'; echo $?

如果无限制加密可用,则返回0状态代码;如果不可用,则返回1。零是正确的成功&#39; shell函数的返回值,非零表示失败。

答案 2 :(得分:25)

我认为您可以使用Cipher.getMaxAllowedKeyLength(),同时还可以将您正在使用的密码与已知的“好”安全密码列表进行比较,例如AES。

Here's a reference article列出了Java 1.4中最新的密钥大小管辖权限制(这些限制可能没有改变,除非法律也发生了变化 - 见下文)。

如果您在一个拥有加密出口/进口限制的国家/地区开展业务,您必须咨询您所在国家/地区的法律,但在这些情况下您可以安全地假设您在JVM中可以使用(默认情况下)无限强度加密。换句话说,假设你正在使用official JVM from Oracle,而你碰巧生活在一个美国已经对加密出口限制的国家(并且由于甲骨文是一家美国公司,它将受制于这些限制),那么在这种情况下你也可以假设你没有无限的力量。

当然,that doesn't stop you from building your own,从而给予自己无限的力量,但根据您当地的法律,这可能是非法的。

This article概述了从美国出口到其他国家的限制。

答案 3 :(得分:15)

方法Cipher.getMaxAllowedKeyLength中记录了如何检查是否适用限制的方法:

  

如果安装了JCE无限强度管辖区政策文件,则会返回Integer.MAX_VALUE

这意味着如果返回除(或确实低于)Integer.MAX_VALUE之外的任何值,那么限制确实适用。

以下方法的JavaDoc中有更多信息:

/**
 * Determines if cryptography restrictions apply.
 * Restrictions apply if the value of {@link Cipher#getMaxAllowedKeyLength(String)} returns a value smaller than {@link Integer#MAX_VALUE} if there are any restrictions according to the JavaDoc of the method.
 * This method is used with the transform <code>"AES/CBC/PKCS5Padding"</code> as this is an often used algorithm that is <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#impl">an implementation requirement for Java SE</a>.
 * 
 * @return <code>true</code> if restrictions apply, <code>false</code> otherwise
 */
public static boolean restrictedCryptography() {
    try {
        return Cipher.getMaxAllowedKeyLength("AES/CBC/PKCS5Padding") < Integer.MAX_VALUE;
    } catch (final NoSuchAlgorithmException e) {
        throw new IllegalStateException("The transform \"AES/CBC/PKCS5Padding\" is not available (the availability of this algorithm is mandatory for Java SE implementations)", e);
    }
}

请注意,自Java 9以来,默认情况下会安装无限制加密策略(受导入/导出规则影响的那些策略必须安装有限的加密策略)。因此,此代码主要用于向后兼容性和/或其他运行时。

答案 4 :(得分:5)

这是一个完整的复制粘贴版本,允许进行测试

import javax.crypto.Cipher;
import java.security.NoSuchAlgorithmException;

class Test {
    public static void main(String[] args) {
        int allowedKeyLength = 0;

        try {
            allowedKeyLength = Cipher.getMaxAllowedKeyLength("AES");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        System.out.println("The allowed key length for AES is: " + allowedKeyLength);
    }
}

运行

javac Test.java

java Test

如果JCE无效输出:128 JCE的工作方式如下:2147483647

答案 5 :(得分:3)

如果您使用的是Linux,可以使用此命令轻松查看

java -version ; \
echo 'System.err.println(javax.crypto.Cipher.getInstance("AES/CBC/PKCS5Padding").getMaxAllowedKeyLength("AES"));'  \
| java -cp /usr/share/java/bsh-*.jar bsh.Interpreter >/dev/null

如果输出类似,则无法使用无限强度加密

java version "1.7.0_76"
Java(TM) SE Runtime Environment (build 1.7.0_76-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.76-b04, mixed mode)
128

答案 6 :(得分:2)

您可以使用groovy从命令行一步检查:

groovysh -e 'javax.crypto.Cipher.getMaxAllowedKeyLength("AES")'

如果结果为2147483647,则您可以无限制加密。

在旧版本的groovy上,您必须删除-e

groovysh 'javax.crypto.Cipher.getMaxAllowedKeyLength("AES")'

答案 7 :(得分:0)

注意:请使用jefflunt's answerKonstantinSpirov's answer。这个答案不是一个有效的答案,因为它总是返回true。我在这里留下这个答案只是因为它在答案和评论的其他地方被引用,仅作为参考。


您可以使用以下内容初始化static final boolean,然后可以使用它来测试无限加密支持(因为只有安装了无限制策略才支持AES 256位。)

boolean isUnlimitedSupported = false;
try {
    KeyGenerator kgen = KeyGenerator.getInstance("AES", "SunJCE");
    kgen.init(256);
    isUnlimitedSupported = true;
} catch (NoSuchAlgorithmException e) {
    isUnlimitedSupported = false;
} catch (NoSuchProviderException e) {
    isUnlimitedSupported = false;
}
System.out.println("isUnlimitedSupported=" + isUnlimitedSupported);
// set static final variable = isUnlimitedSupported;

答案 8 :(得分:-1)

我最近不得不添加JCE检查,我的解决方案演变为以下代码段。这是一个groovy脚本,但使用try catch转换为标准java方法应该很容易。这已经过Java 7&amp; S测试。 Java 8。

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.SecretKey;

// Make a blank 256 Bit AES Key
final SecretKey secretKey = new SecretKeySpec(new byte[32], "AES");
final Cipher encryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// This line will throw a invalid key length exception if you don't have
// JCE Unlimited strength installed
encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey);
// If it makes it here, you have JCE installed