us_export_policy unlimited strength policies jurisdiction files extension downloads java jce

java - unlimited - Comprobando si Criptografía Ilimitada está disponible



policy java 6 (9)

¿Cómo puedo verificar, en el código Java, si la JVM actual tiene disponible una criptografía de fuerza ilimitada?


Creo que probablemente podría usar Cipher.getMaxAllowedKeyLength() , al mismo tiempo que compara el código cifrado que está usando con las listas conocidas de "buenos" y seguros, como el AES.

Aquí hay un artículo de referencia que enumera las limitaciones de la jurisdicción de tamaño de clave máxima que estaban vigentes a partir de Java 1.4 (es probable que no hayan cambiado, a menos que la ley también haya cambiado, consulte a continuación).

Si está operando en un país que tiene restricciones criptográficas de exportación / importación, tendría que consultar la ley de su país, pero es probable que en estas situaciones sea seguro asumir que no tiene disponible una criptografía de fuerza ilimitada (de forma predeterminada) en tu JVM. Dicho de otra manera, asumiendo que está utilizando la JVM oficial de Oracle , y que vive en una nación contra la cual los Estados Unidos ha nivelado las restricciones de exportación para la criptografía (y dado que Oracle es una compañía de los Estados Unidos, estaría sujeto a estas restricciones), entonces también podría asumir en este caso que no tiene una fuerza ilimitada disponible.

Por supuesto, eso no le impide construir su propio y, por lo tanto, otorgarse una fuerza ilimitada, pero según las leyes locales, eso podría ser ilegal.

Este artículo describe las restricciones a la exportación a otras naciones, desde los Estados Unidos.


En el mismo espíritu que la respuesta de Dan Cruz, pero con una sola línea de código y sin pasar por excepciones:

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

Así que un programa completo podría ser:

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


Esta es una versión completa de copiar y pegar para permitir la prueba

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

Correr

javac Test.java

java Test

Si JCE no está funcionando, la salida: 128 JCE está funcionando algo como: 2147483647


Hace poco tuve que agregar un cheque JCE y mi solución evolucionó al siguiente fragmento de código. Este fue un script maravilloso, pero debería ser fácil de convertir al método Java estándar con un retén de prueba. Esto ha sido probado con Java 7 y 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


La forma de verificar si se aplican restricciones se documenta en el método Cipher.getMaxAllowedKeyLength :

Si se instalan los archivos de políticas de jurisdicción de fuerza ilimitada de JCE, se devolverá Integer.MAX_VALUE .

Esto significa que si se devuelve cualquier valor que no sea (o incluso menor que) Integer.MAX_VALUE se aplican restricciones.

Aún más información está en el JavaDoc del método a continuación:

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

Tenga en cuenta que, desde Java 9, las políticas criptográficas ilimitadas se instalan de forma predeterminada (en cambio, las que están afectadas por las regulaciones de importación / exportación tienen que instalar las políticas criptográficas limitadas ). Por lo tanto, este código se requeriría principalmente para la compatibilidad hacia atrás y / u otros tiempos de ejecución.


Puedes comprobarlo en un paso desde la línea de comando usando groovy:

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

Si el resultado es 2147483647 , tiene criptografía ilimitada.

En la versión anterior de groovy, debes eliminar el -e :

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


Si está en Linux y ha instalado el JDK (pero Beanshell no está disponible), puede verificar con el comando de runscript proporcionado con el JDK.

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

Esto devuelve un código de estado 0 si la Criptografía ilimitada está disponible, o 1 si no está disponible. Cero es el valor de retorno de ''éxito'' correcto para las funciones de shell y un valor distinto de cero indica un error.


Si está usando Linux, puede verificarlo fácilmente con este comando

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

Si la salida es algo así, la criptografía de fuerza ilimitada no está disponible

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


NOTA : Utilice la respuesta de jefflunt o la respuesta de KonstantinSpirov . Esta respuesta no es una respuesta válida, ya que siempre devolverá true . Estoy dejando esta respuesta aquí solo porque está referenciada en otras partes en respuestas y comentarios y es útil solo como referencia.

Podría usar lo siguiente para inicializar un static final boolean algún lugar que luego pueda usar para probar la compatibilidad con criptografía ilimitada (ya que AES de 256 bits solo es compatible si la política no restringida está instalada).

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;