检查是否有无限密码

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

我想你可能可以使用Cipher.getMaxAllowedKeyLength() ,同时还可以将你使用的密码与已知的“好”,安全密码(如AES)列表进行比较。

这里有一篇参考文章 ,列出了Java 1.4以来的最大密钥大小pipe辖限制(这些可能没有改变,除非法律也改变 – 见下文)。

如果您在一个有encryption出口/import限制的国家运营,您必须咨询您所在国家/地区的法律,但在这些情况下假定您没有可用的无限强度encryption(默认情况下)在你的JVM中。 换句话说,假设您使用的是甲骨文公司的官方JVM ,而且您恰好居住在一个国家,美国已经对encryption的出口限制进行了调整(而且由于甲骨文是一家美国公司,它将受制于这些限制),那么你也可以假设在这种情况下,你没有无限的力量可用。

当然, 这并不妨碍你build立自己的 ,从而给予自己无限的力量,但根据你当地的法律,这可能是非法的。

这篇文章概述了从美国出口到其他国家的限制。

本着与丹·克鲁兹(DanCruz)的回答相同的精神,只用一行代码,而且没有任何例外:

 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); } } 

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

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

如果无限制encryption可用,则返回1,否则为0。

Cipher.getMaxAllowedKeyLength方法logging了如何检查限制的方法:

如果安装了JCE无限强度pipe辖权策略文件,则返回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); } } 

这是一个完整的复制粘贴版本,以允许testing

 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

如果您使用的是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 

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


您可以使用以下方法初始化一个static final boolean ,然后您可以使用它来testing无限的encryption支持(因为只有在安装了无限制的策略时才支持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; 

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

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

如果结果是2147483647 ,那么您拥有无限encryption。

在旧版本的groovy上,你应该删除-e

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

我最近不得不添加一个JCE检查,我的解决scheme发展到以下片段。 这是一个groovy脚本,但它应该很容易转换为标准的Java方法与try catch。 这已经通过Java 7和Java 8的testing。

 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