Verifica se la crittografia illimitata è disponibile

Come posso verificare, in codice Java, se la JVM corrente ha crittografia a forza illimitata disponibile?

Penso che potresti probabilmente usare Cipher.getMaxAllowedKeyLength () , mentre paragoni anche la cifra che stai utilizzando agli elenchi noti di “buoni”, cyphers sicuri, come AES.

Ecco un articolo di riferimento in cui sono elencate le limitazioni della giurisdizione della dimensione massima della chiave che erano attuali a partire da Java 1.4 (queste probabilmente non sono cambiate, a meno che anche la legge non sia cambiata – vedi sotto).

Se stai operando in una nazione che ha restrizioni crittografiche di esportazione / importazione, dovresti consultare la legge nella tua nazione, ma probabilmente è sicuro assumere in queste situazioni che non si disponga di crittografia a forza illimitata (di default) nella tua JVM. Mettendola in un altro modo, supponendo che tu stia utilizzando la JVM ufficiale di Oracle e ti capiti di vivere in una nazione contro cui gli Stati Uniti hanno livellato le restrizioni all’esportazione per la crittografia (e poiché Oracle è una società statunitense, sarebbe soggetta a questi restrizioni), in questo caso si potrebbe anche supporre che non si disponga di forza illimitata.

Naturalmente, questo non ti impedisce di costruirti da solo , e quindi garantirti una forza illimitata, ma a seconda delle leggi locali potrebbe essere illegale.

Questo articolo delinea le restrizioni all’esportazione verso altre nazioni, dagli Stati Uniti.

Nello stesso spirito della risposta di Dan Cruz, ma con una sola riga di codice e senza andare oltre le eccezioni:

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

Quindi un programma completo potrebbe essere:

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

Se si utilizza Linux e si è installato JDK (ma Beanshell non è disponibile), è ansible verificare con il comando runscript fornito con JDK.

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

Restituisce un codice di stato 0 se è disponibile Crittografia illimitata o 1 se non disponibile. Zero è il valore di ritorno “success” corretto per le funzioni di shell e zero indica un errore.

Il modo in cui verificare se vengono applicate le restrizioni è documentato nel metodo Cipher.getMaxAllowedKeyLength :

Se vengono installati file di criteri di giurisdizione con forza illimitata, verrà restituito Integer.MAX_VALUE .

Ciò significa che se viene restituito qualsiasi valore diverso da (o effettivamente inferiore a) Integer.MAX_VALUE si applicano restrizioni.

Ancora più informazioni sono nel JavaDoc del metodo seguente:

 /** * 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 "AES/CBC/PKCS5Padding" as this is an often used algorithm that is an implementation requirement for Java SE. * * @return true if restrictions apply, false 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); } } 

Si noti che da Java 9 le policy di crittografia illimitate vengono installate di default (con quelle interessate dai regolamenti di importazione / esportazione che devono invece installare i criteri crittografici limitati ). Quindi questo codice dovrebbe essere principalmente richiesto per la retrocompatibilità e / o altri runtime.

Questa è una versione di copia e incolla completa per consentire il test

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

Correre

javac Test.java

java Test

Se JCE non funziona in uscita: 128 JCE funziona come: 2147483647

Se stai usando Linux, puoi controllarlo facilmente con questo 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 

Se l’output è qualcosa del genere, la crittografia a forza illimitata non è disponibile

 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 

Puoi controllarlo in un solo passaggio dalla riga di comando usando groovy:

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

Se il risultato è 2147483647 , hai crittografia illimitata.

Nella versione precedente di groovy, devi rimuovere -e :

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

NOTA : per favore usa la risposta di jefflunt o la risposta di KonstantinSpirov . Questa risposta non è una risposta valida poiché restituirà sempre true . Lascio questa risposta qui solo perché viene citata altrove in risposte e commenti ed è utile solo come riferimento.


È ansible utilizzare quanto segue per inizializzare un static final boolean da qualche parte che è ansible utilizzare per testare il supporto crittografico illimitato (poiché AES 256-bit è supportato solo se è installata la politica senza restrizioni).

 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; 

Di recente ho dovuto aggiungere un controllo JCE e la mia soluzione si è evoluta nel seguente snippet. Questo era uno script groovy, ma dovrebbe essere facile da convertire in un metodo java standard con un catch di prova. Questo è stato testato con Java 7 e 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