Javaコードで、現在のJVMが無制限の強度の暗号化を利用できるかどうかを確認するにはどうすればよいですか?
9 に答える
Dan Cruz の回答と同じ精神で、ただしコードは 1 行で、例外を通過することはありません。
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 は使用できない) 場合はrunscript
、JDK に付属のコマンドで確認できます。
jrunscript -e 'exit (javax.crypto.Cipher.getMaxAllowedKeyLength("RC5") >= 256 ? 0 : 1);'; echo $?
0
これは、Unlimited Cryptography が利用できる場合、または利用できない場合にステータス コードを返し1
ます。ゼロはシェル関数の正しい「成功」戻り値であり、ゼロ以外は失敗を示します。
おそらくCipher.getMaxAllowedKeyLength()を使用できると思いますが、使用している暗号を、AES などの「適切な」安全な暗号の既知のリストと比較します。
これは、Java 1.4 の時点で有効だった最大鍵サイズの管轄区域の制限をリストした参照記事です (法律も変更されない限り、これらは変更されていない可能性があります。以下を参照してください)。
暗号の輸出入が制限されている国で事業を行っている場合は、自国の法律に相談する必要がありますが、これらの状況では、(デフォルトで) 無制限の強度の暗号を利用できないと想定するのがおそらく安全です。あなたのJVMで。別の言い方をすれば、Oracle の公式 JVMを使用していて、たまたま米国が暗号の輸出制限を課している国に住んでいると仮定します (また、Oracle は米国の会社であるため、これらの対象となります)。制限)、この場合、無制限の強度を利用できないと仮定することもできます。
もちろん、だからと言って独自の を構築し、それによって無限の力を自分に与えることを止めるわけではありませんが、地域の法律によっては、それが違法となる可能性があります。
この記事では、米国から他国への輸出に関する制限について概説します。
制限が適用されるかどうかを確認する方法は、メソッドに記載されています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 以降、無制限の暗号化ポリシーがデフォルトでインストールされることに注意してください (輸入/輸出規制の影響を受けるものは、代わりに制限付きの暗号化ポリシーをインストールする必要があります)。したがって、このコードは主に下位互換性や他のランタイムのために必要になります。
これは、テストを可能にするための完全なコピー ペースト バージョンです。
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
groovy を使用して、コマンド ラインから 1 ステップで確認できます。
groovysh -e 'javax.crypto.Cipher.getMaxAllowedKeyLength("AES")'
結果が の場合、2147483647
暗号化は無制限です。
古いバージョンの groovy では、以下を削除する必要があります-e
。
groovysh 'javax.crypto.Cipher.getMaxAllowedKeyLength("AES")'
注: jefflunt の回答またはKonstantinSpirov の回答を使用してください。この回答は常に を返すため、有効な回答ではありません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;
最近、JCE チェックを追加する必要があり、私のソリューションは次のスニペットに進化しました。これはグルーヴィーなスクリプトでしたが、try catch を使用して標準の Java メソッドに変換するのは簡単なはずです。これは、Java 7 および 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