Sicurezza Java: dimensione della chiave illegale o parametri predefiniti?


409

Avevo già posto una domanda al riguardo, ma non mi è stata data risposta e non ho portato da nessuna parte.

Quindi ho chiarito alcuni dettagli sul problema e mi piacerebbe davvero sentire le tue idee su come potrei risolvere questo o cosa dovrei provare.

Ho Java 1.6.0.12 installato sul mio server Linux e il codice seguente funziona perfettamente.

String key = "av45k1pfb024xa3bl359vsb4esortvks74sksr5oy4s5serondry84jsrryuhsr5ys49y5seri5shrdliheuirdygliurguiy5ru";
try {
    Cipher c = Cipher.getInstance("ARCFOUR");

    SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "ARCFOUR");
    c.init(Cipher.DECRYPT_MODE, secretKeySpec);

    return new String(c.doFinal(Hex.decodeHex(data.toCharArray())), "UTF-8");

} catch (InvalidKeyException e) {
    throw new CryptoException(e);
}

Oggi ho installato Java 1.6.0.26 sul mio utente del server e quando provo a eseguire la mia applicazione, ottengo la seguente eccezione. La mia ipotesi sarebbe che abbia qualcosa a che fare con la configurazione dell'installazione Java perché funziona nella prima, ma non nella versione successiva.

Caused by: java.security.InvalidKeyException: Illegal key size or default parameters
    at javax.crypto.Cipher.a(DashoA13*..) ~[na:1.6]
    at javax.crypto.Cipher.a(DashoA13*..) ~[na:1.6]
    at javax.crypto.Cipher.a(DashoA13*..) ~[na:1.6]
    at javax.crypto.Cipher.init(DashoA13*..) ~[na:1.6]
    at javax.crypto.Cipher.init(DashoA13*..) ~[na:1.6]
    at my.package.Something.decode(RC4Decoder.java:25) ~[my.package.jar:na]
    ... 5 common frames omitted

La linea 25 è: c.init(Cipher.DECRYPT_MODE, secretKeySpec);

Note:
* java.security nella directory java 1.6.0.12 del server corrisponde quasi completamente al file java.security 1.6.0.26 . Non ci sono provider aggiuntivi nel primo.
* La domanda precedente è qui .



4
Questo può anche essere generato come errore: Caused by: java.security.InvalidKeyException: Illegal key size(senza "o parametri predefiniti") in Java 8
hackajar

Basta usare OpenJDK e funzionerà.
Rodrigo Asensio,

@RodrigoAsensio: sto usando OpenJDK e non funziona con esso. È necessario installare i file jar dei file dei criteri di giurisdizione di forza illimitati. E poi funzionerà.
Anjanb,

5
Aggiorna alla risposta @AniketThakur. Da Java 9 e Java 8u151 non è più necessario scaricare e installare manualmente i file delle politiche sulla giurisdizione. Per abilitare la crittografia illimitata, è possibile utilizzare la nuova proprietà di sicurezza crypto.policy. Se la nuova proprietà Security (crypto.policy) è impostata nel file java.security o è stata impostata dinamicamente utilizzando la chiamata Security.setProperty () prima che il framework JCE fosse inizializzato, tale impostazione verrà rispettata. Per impostazione predefinita, la proprietà non sarà definita.
Marcin Kłopotek,

Risposte:


722

Molto probabilmente non hai installato il file di resistenza illimitato ora.

Potrebbe essere necessario scaricare questo file:

File della politica di giurisdizione di forza illimitata JCE (Java Cryptography Extension) 6

Download dei file della politica di giurisdizione di forza illimitata di Java Cryptography Extension (JCE) 7

Download dei file delle norme sulla giurisdizione di JMP (Java Cryptography Extension) illimitati (richiesto solo per le versioni precedenti a Java 8 u162)

Estrarre i file jar dalla zip e salvarli in ${java.home}/jre/lib/security/.


2
@JamesBlack - Sì, e per assicurarsi che tutte le basi sono state coperte ho messo sotto del JAR Java/jre/lib/security, Java/jdk/lib/securitye Java/jdk/jre/lib/security. L'esecuzione di 'java -version' restituisce i dettagli previsti.
aroth,

5
Per l'SDK di IBM (ad es. WebSphere), scaricare i file delle politiche di giurisdizione illimitate da www14.software.ibm.com/webapp/iwm/web/preLogin.do?source=jcesdk
quietmint

4
Da Java 9 e Java 8u151 non è più necessario scaricare e installare manualmente i file delle politiche sulla giurisdizione. Per abilitare la crittografia illimitata, è possibile utilizzare la nuova proprietà di sicurezza crypto.policy. Se la nuova proprietà Security (crypto.policy) è impostata nel file java.security o è stata impostata dinamicamente utilizzando la chiamata Security.setProperty () prima che il framework JCE fosse inizializzato, tale impostazione verrà rispettata. Per impostazione predefinita, la proprietà non sarà definita.
Marcin Kłopotek,

4
Quindi, questa risposta aggiornata non è più aggiornata e obsoleta. Come possiamo votare o sopprimere questa risposta in modo che stackoverflow.com/a/46857694/2808798 possa essere la risposta "accettata"?
Jesse Adelman,

3
@JesseAdelman - Purtroppo ha quasi 7 anni, non si può fare molto. Chiunque chiedesse avrebbe bisogno di cambiarlo.
James Black,

54

I file delle giurisdizioni JRE / JDK / Java 8 sono disponibili qui:

Download dei file della politica di giurisdizione per la forza illimitata di Java Cryptography Extension (JCE) 8

Come James ha detto sopra:
installa i file in ${java.home}/jre/lib/security/.


2
Ho provato usando 6 e 7, ma non hanno funzionato. Ho dovuto installare 8. Grazie.
Jason Kim,

9
Nuova versione JDK 8u151 ha "Nuova proprietà di sicurezza per controllare la politica di crittografia". Ora è un cambio di proprietà da cambiare. La linea di fondo: rimuovere "#" dalla riga "# crypto.policy = unlimited" in "lib \ security \ java.security" per abilitare l'uso delle chiavi a 256 bit. oracle.com/technetwork/java/javase/8u151-relnotes-3850493.html
hemisphire

1
Grazie! Poiché si tratta di una proprietà di sicurezza, è anche possibile chiamare Security.setProperty ("crypto.policy", "unlimited"). Fonte: link di
@hemisphire

42

Per JAVA 7 il link per il download è jce-7-download

Copia i due barattoli scaricati in Java \ jdk1.7.0_10 \ jre \ lib \ security
Effettua un backup dei barattoli più vecchi per renderli più sicuri.

Per JAVA 8 il link per il download è jce-8-download
Copia i barattoli scaricati in Java \ jdk1.8.0_45 \ jre \ lib \ security
Effettua un backup dei barattoli più vecchi per essere più sicuro.


39

Con Java 9, Java 8u161 , Java 7u171 e Java 6u181 la limitazione è ora disabilitata per impostazione predefinita. Vedi problema nel database dei bug Java .


A partire da Java 8u151 è possibile disabilitare la limitazione a livello di codice .

Nelle versioni precedenti, i file della giurisdizione JCE dovevano essere scaricati e installati separatamente per consentire a JDK di utilizzare una crittografia illimitata. I passaggi di download e installazione non sono più necessari.

Invece ora puoi invocare la seguente riga prima del primo utilizzo delle classi JCE (cioè preferibilmente subito dopo l'avvio dell'applicazione):

Security.setProperty("crypto.policy", "unlimited");

Che dire di Android? A quale livello API è possibile risolvere questi metodi di restrizione?
TheRealChx101

31

Questa è una soluzione solo per il codice . Non è necessario scaricare o pasticciare con i file di configurazione.

È una soluzione basata sulla riflessione, testata su Java 8

Chiama questo metodo una volta, all'inizio del programma.

// Importazioni

import javax.crypto.Cipher;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Map;

//metodo

public static void fixKeyLength() {
    String errorString = "Failed manually overriding key-length permissions.";
    int newMaxKeyLength;
    try {
        if ((newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES")) < 256) {
            Class c = Class.forName("javax.crypto.CryptoAllPermissionCollection");
            Constructor con = c.getDeclaredConstructor();
            con.setAccessible(true);
            Object allPermissionCollection = con.newInstance();
            Field f = c.getDeclaredField("all_allowed");
            f.setAccessible(true);
            f.setBoolean(allPermissionCollection, true);

            c = Class.forName("javax.crypto.CryptoPermissions");
            con = c.getDeclaredConstructor();
            con.setAccessible(true);
            Object allPermissions = con.newInstance();
            f = c.getDeclaredField("perms");
            f.setAccessible(true);
            ((Map) f.get(allPermissions)).put("*", allPermissionCollection);

            c = Class.forName("javax.crypto.JceSecurityManager");
            f = c.getDeclaredField("defaultPolicy");
            f.setAccessible(true);
            Field mf = Field.class.getDeclaredField("modifiers");
            mf.setAccessible(true);
            mf.setInt(f, f.getModifiers() & ~Modifier.FINAL);
            f.set(null, allPermissions);

            newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES");
        }
    } catch (Exception e) {
        throw new RuntimeException(errorString, e);
    }
    if (newMaxKeyLength < 256)
        throw new RuntimeException(errorString); // hack failed
}

Crediti: Delthas


4
Si noti che ciò potrebbe violare il contratto di licenza Java SE: D. RESTRIZIONI DELLA TECNOLOGIA JAVA. Non è possibile creare, modificare o cambiare il comportamento o autorizzare i licenziatari a creare, modificare o cambiare il comportamento di classi, interfacce o pacchetti secondari che sono in qualche modo identificati come "java", "javax", " javafx "," sun "," oracle "o convenzione simile come specificato da Oracle in qualsiasi designazione della convenzione di denominazione. [...] fonte
SimMac

Grazie mille


16

Ho riscontrato lo stesso errore durante l'utilizzo di Windows 7 x64, Eclipse e JDK 1.6.0_30. Nella cartella di installazione di JDK è presente una jrecartella. Questo all'inizio mi ha buttato via mentre stavo aggiungendo i vasetti di cui sopra alla cartella lib / security del JDK senza fortuna. Percorso completo:

C:\Program Files\Java\jdk1.6.0_30\jre\lib\security

Scarica ed estrai i file contenuti nella jcecartella di questo archivio in quella cartella.


16

In Java, per impostazione predefinita AES supporta una chiave a 128 bit, se si prevede di utilizzare una chiave a 192 bit o 256 bit, il complier java genererà Eccezione dimensione chiave illegale, che si sta ottenendo.

La soluzione è come ha suggerito victor & James, dovrai scaricare JCE (Java Cryptography Extension) secondo la tua versione JRE (java6, java7 o java8).

La zip JCE contiene il seguente JAR:

  1. local_policy.jar
  2. US_export_policy.jar

Devi sostituire questi vasi dal tuo <JAVA_HOME>/jre/lib/security. se si utilizza un sistema unix, probabilmente si farà riferimento a/home/urs/usr/lib/jvm/java-<version>-oracle/

A volte basta sostituire local_policy.jar, US_export_policy.jar nella cartella di sicurezza non funziona su unix, quindi suggerisco di copiare prima la cartella di sicurezza sul desktop, sostituire la cartella @ Desktop / security del jar, eliminare la cartella di sicurezza da / jre / lib / e sposta la cartella Sicurezza desktop in / jre / lib /.

ad esempio: sudo mv security /usr/lib/jvm/java-7-oracle/jre/lib


5

C'è una breve discussione di ciò che sembra essere questo problema qui . La pagina a cui si collega sembra essere sparita, ma una delle risposte potrebbe essere ciò di cui hai bisogno:

In effetti, è stato utile copiare US_export_policy.jar e local_policy.jar da core / lib / jce a $ JAVA_HOME / jre / lib / security. Grazie.


Grazie, ma avevo US_export_policy.jare local_policy.jarnella mia cartella lib / security già una volta installato Java .. E non sono riuscito a trovare core / lib / jce tra l'altro nella mia cartella di installazione Java.
Rihards,

5

il problema è il contenuto del file default_local.policy in local_policy.jar nella cartella jre \ lib \ security , se si installa JRE:

// Some countries have import limits on crypto strength. This policy file
// is worldwide importable.

grant {
    permission javax.crypto.CryptoPermission "DES", 64;
    permission javax.crypto.CryptoPermission "DESede", *;
    permission javax.crypto.CryptoPermission "RC2", 128,
                                     "javax.crypto.spec.RC2ParameterSpec", 128;
    permission javax.crypto.CryptoPermission "RC4", 128;
    permission javax.crypto.CryptoPermission "RC5", 128,
          "javax.crypto.spec.RC5ParameterSpec", *, 12, *;
    permission javax.crypto.CryptoPermission "RSA", *;
    permission javax.crypto.CryptoPermission *, 128;
};

se non hai bisogno di impostazioni valide in tutto il mondo, puoi semplicemente modificare questo file e cambiare il contenuto in

// Country-specific policy file for countries with no limits on crypto strength.
grant {
    // There is no restriction to any algorithms.
    permission javax.crypto.CryptoAllPermission;
};

questo è ciò che ottieni se scarichi JCE da Oracle.


4

Ho anche riscontrato il problema, ma dopo aver sostituito quello esistente con quello scaricato (da JCE) si è risolto il problema. I nuovi file crittografici hanno fornito forza illimitata.


2

Per impostazione predefinita, Java supporta solo dimensioni di chiave AES a 128 bit (16 byte) per la crittografia. Se non è necessario un supporto superiore a quello predefinito, è possibile tagliare la chiave della dimensione corretta prima dell'uso Cipher. Consulta javadoc per le chiavi supportate predefinite.

Questo è un esempio di generazione di una chiave che funzionerebbe con qualsiasi versione di JVM senza modificare i file delle politiche. Usalo a tua discrezione.

Ecco un buon articolo sul fatto che le dimensioni delle chiavi da 128 a 256 contino sul blog di AgileBits

SecretKeySpec getKey() {
    final pass = "47e7717f0f37ee72cb226278279aebef".getBytes("UTF-8");
    final sha = MessageDigest.getInstance("SHA-256");

    def key = sha.digest(pass);
    // use only first 128 bit (16 bytes). By default Java only supports AES 128 bit key sizes for encryption.
    // Updated jvm policies are required for 256 bit.
    key = Arrays.copyOf(key, 16);
    return new SecretKeySpec(key, AES);
}

La documentazione delle classi di cifratura punta a dimensioni di chiave valide per ciascun tipo di crittografia.
Keaplogik,

Vedi il documento Oracle Cipher (Encryption) Algorithms AES: Advanced Encryption Standard come specificato da NIST in FIPS 197. Conosciuto anche come algoritmo Rijndael di Joan Daemen e Vincent Rijmen, AES è un codice a blocchi di 128 bit che supporta chiavi di 128, 192, e 256 bit.
zaph,

Questo può essere vero, ma è richiesto solo da ciascuna versione Java per supportare 128 bit come specificato nella documentazione di classe. Provalo tu stesso e scoprirai che avrai bisogno del vaso della politica dalla risposta di James Black per fare altre dimensioni chiave
keaplogik

Qualsiasi implementazione AES che non supportava le chiavi a 256 bit sarebbe essenzialmente inutile perché non sarebbe in grado di decrittografare un numero considerevole di crittografie AES utilizzando chiavi a 256 bit.
zaph,

1
Se è necessaria una chiave a 256 bit, la soluzione migliore, forse l'unica soluzione, è installare il file Policy, se necessario, non troncare la chiave che indebolisce potenzialmente la sicurezza e potrebbe non essere possibile in caso di interoperabilità.
zaph,

2

A partire da Java 9 o 8u151, è possibile utilizzare commentare una riga nel file:

<JAVA_HOME>/jre/lib/security/java.security

E cambia:

#crypto.policy=unlimited

per

crypto.policy=unlimited

2

Se stai usando la distribuzione Linux con apt e hai aggiunto webupd8 PPA, puoi semplicemente eseguire il comando

apt-get install oracle-java8-unlimited-jce-policy

Altri aggiornamenti:

  1. I file della politica di giurisdizione di forza illimitata sono inclusi in Java 9 e utilizzati per impostazione predefinita
  2. A partire dall'aggiornamento 161 di Java 8, Java 8 imposta automaticamente la politica di giurisdizione di forza illimitata.
  3. A partire da Java 8 Update 151 , la politica di giurisdizione di forza illimitata è inclusa in Java 8 ma non viene utilizzata per impostazione predefinita. Per abilitarlo, è necessario modificare il file java.security in <java_home>/jre/lib/security(per JDK) o <java_home>/lib/security(per JRE). Rimuovi il commento (o includi) la linea

    crypto.policy=unlimited

    Assicurati di modificare il file usando un editor eseguito come amministratore. La modifica della politica ha effetto solo dopo il riavvio della JVM

Prima dell'aggiornamento 151 di Java 8 il resto delle risposte è valido. Scarica i file della politica di giurisdizione JCE Unlimited Strength e sostituisci.

Per maggiori dettagli, puoi fare riferimento al mio post sul blog personale di seguito - Come installare i file delle politiche di giurisdizione illimitata per Java Cryptography Extension (JCE)


1

ci sono due opzioni per risolvere questo problema

opzione numero 1: utilizzare il certificato con meno lunghezza RSA 2048

opzione numero 2: aggiornerai due vasetti in jre\lib\security qualunque cosa tu usi java http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html

oppure usi IBM websphere o qualsiasi server delle applicazioni che usa java. il problema principale che ho affrontato ho usato la certificazione con la massima lunghezza, quando ho distribuito orecchie su websphere la stessa eccezione è stata lanciata

Java Security: Illegal key size or default parameters?

ho aggiornato la cartella Java installata in websphere con due vasetti https://www14.software.ibm.com/webapp/iwm/web/reg/pick.do?source=jcesdk&lang=en_US

puoi controllare il riferimento nel link https://www-01.ibm.com/support/docview.wss?uid=swg21663373


1

Assicurati di utilizzare l'ultima versione di JDK / JRE .

Nel mio caso, avevo inserito JCE nella cartella JRE, ma non mi è stato di aiuto. È successo perché stavo eseguendo il mio progetto direttamente dall'IDE (usando JDK).

Quindi ho aggiornato il mio JDK e JRE all'ultima versione (1.8.0_211) e il problema era scomparso.

Maggiori dettagli: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8170157


1

JDK predefinito supporta la crittografia solo tramite chiavi a 128 bit a causa delle restrizioni americane. Quindi per supportare la crittografia da una chiave lunga 256 bit dobbiamo sostituire local_policy.jare US_export_policy.jarsnella $JAVA_HOME/java-8-oracle/jre/lib/securitycartella, altrimenti fornirà:

java.security.InvalidKeyException: dimensione della chiave non valida o impostazione predefinita


0

Devi andare lì

/jdk1.8.0_152 | / jre | / lib | / sicurezza | java.security e decommenta il file

#crypto.policy=unlimited

per

crypto.policy=unlimited
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.