Sécurité Java: taille de clé illégale ou paramètres par défaut?

409

J'avais posé une question à ce sujet plus tôt, mais cela n'a pas été répondu correctement et n'a mené nulle part.

J'ai donc clarifié quelques détails sur le problème et j'aimerais vraiment entendre vos idées sur la façon de résoudre ce problème ou que dois-je essayer.

J'ai Java 1.6.0.12 installé sur mon serveur Linux et le code ci-dessous fonctionne parfaitement.

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

Aujourd'hui, j'ai installé Java 1.6.0.26 sur mon utilisateur de serveur et lorsque j'essaie d'exécuter mon application, j'obtiens l'exception suivante. Je suppose que cela a quelque chose à voir avec la configuration d'installation de Java car cela fonctionne dans la première, mais ne fonctionne pas dans la version ultérieure.

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 ligne 25 est: c.init(Cipher.DECRYPT_MODE, secretKeySpec);

Remarques:
* java.security sur le répertoire java 1.6.0.12 du serveur correspond presque complètement au fichier java.security 1.6.0.26. Il n'y a pas de fournisseurs supplémentaires dans le premier.
* La question précédente est ici .

Rihards
la source
4
Cela peut également être généré comme une erreur: Caused by: java.security.InvalidKeyException: Illegal key size(sans les "ou paramètres par défaut") dans Java 8
hackajar
Utilisez simplement OpenJDK et cela fonctionnera.
Rodrigo Asensio
@RodrigoAsensio: J'utilise OpenJDK et cela ne fonctionne pas avec. Vous devez installer les fichiers jar des fichiers de stratégie de compétence de force illimités. Et puis ça marchera.
anjanb
5
Mise à jour de la réponse @AniketThakur. Depuis Java 9 et Java 8u151, il n'est plus nécessaire de télécharger et d'installer manuellement les fichiers de stratégie de juridiction. Pour activer la cryptographie illimitée, on peut utiliser la nouvelle propriété de sécurité crypto.policy. Si la nouvelle propriété Security (crypto.policy) est définie dans le fichier java.security, ou a été définie dynamiquement à l'aide de l'appel Security.setProperty () avant l'initialisation de l'infrastructure JCE, ce paramètre sera honoré. Par défaut, la propriété ne sera pas définie.
Marcin Kłopotek

Réponses:

722

Vous n'avez probablement pas le fichier de force illimitée installé maintenant.

Vous devrez peut-être télécharger ce fichier:

Fichiers de stratégie de juridiction de force illimitée JCE (Java Cryptography Extension) 6

Java Cryptography Extension (JCE) Fichiers de stratégie de juridiction de force illimitée 7 Télécharger

Extension de cryptographie Java (JCE) Fichiers de stratégie de juridiction de force illimitée 8 Téléchargement (requis uniquement pour les versions antérieures à Java 8 u162)

Extrayez les fichiers jar du zip et enregistrez-les ${java.home}/jre/lib/security/.

James Black
la source
2
@JamesBlack - Oui, et pour vous assurer que toutes les bases étaient couvertes je mets le sous du JAR Java/jre/lib/security, Java/jdk/lib/securityet Java/jdk/jre/lib/security. L'exécution de 'java -version' renvoie les détails attendus.
2012 à 4h02
5
Pour le SDK d'IBM (par exemple, WebSphere), téléchargez les fichiers de stratégie de juridiction illimitée à partir de www14.software.ibm.com/webapp/iwm/web/preLogin.do?source=jcesdk
quietmint
4
Depuis Java 9 et Java 8u151, il n'est plus nécessaire de télécharger et d'installer manuellement les fichiers de stratégie de juridiction. Pour activer la cryptographie illimitée, on peut utiliser la nouvelle propriété de sécurité crypto.policy. Si la nouvelle propriété Security (crypto.policy) est définie dans le fichier java.security, ou a été définie dynamiquement à l'aide de l'appel Security.setProperty () avant l'initialisation de l'infrastructure JCE, ce paramètre sera honoré. Par défaut, la propriété ne sera pas définie.
Marcin Kłopotek
4
Donc, cette réponse votée est désormais obsolète et obsolète. Comment voter ou supprimer cette réponse pour que stackoverflow.com/a/46857694/2808798 puisse être la réponse "acceptée"?
Jesse Adelman
3
@JesseAdelman - Malheureusement, cela fait presque 7 ans, il n'y a pas grand-chose à faire. Celui qui a demandé devrait le changer.
James Black
54

Les fichiers de juridiction JRE / JDK / Java 8 se trouvent ici:

Java Cryptography Extension (JCE) Fichiers de stratégie de juridiction de force illimitée 8 Télécharger

Comme James l'a dit plus haut:
installez les fichiers dans ${java.home}/jre/lib/security/.

Saad Malik
la source
2
J'ai essayé d'utiliser 6 et 7, mais cela n'a pas fonctionné. J'ai dû installer 8. Merci.
Jason Kim
9
Nouvelle version JDK 8u151 a "Nouvelle propriété de sécurité pour contrôler la politique de cryptage". Maintenant, c'est un changement de propriété à changer. En bout de ligne: supprimez le "#" de la ligne "# crypto.policy = unlimited" dans "lib \ security \ java.security" pour activer l'utilisation de clés 256 bits. oracle.com/technetwork/java/javase/8u151-relnotes-3850493.html
hemisphire
1
Merci! Comme il s'agit d'une propriété de sécurité, vous pouvez également appeler Security.setProperty ("crypto.policy", "unlimited"). Source: lien de
@hemisphire
42

Pour JAVA 7, le lien de téléchargement est jce-7-download

Copiez les deux fichiers jar téléchargés dans Java \ jdk1.7.0_10 \ jre \ lib \ security
Faites une sauvegarde des fichiers jars plus anciens pour être plus sûr.

Pour JAVA 8, le lien de téléchargement est jce-8-download
Copiez les fichiers jars téléchargés dans Java \ jdk1.8.0_45 \ jre \ lib \ security
Faites une sauvegarde des fichiers jars plus anciens pour être plus sûr.

C Deepak
la source
39

Avec Java 9, Java 8u161 , Java 7u171 et Java 6u181, la limitation est désormais désactivée par défaut. Voir le problème dans la base de données Java Bug .


À partir de Java 8u151, vous pouvez désactiver la limitation par programme.

Dans les versions antérieures, les fichiers de juridiction JCE devaient être téléchargés et installés séparément pour permettre au cryptage illimité d'être utilisé par le JDK. Les étapes de téléchargement et d'installation ne sont plus nécessaires.

Au lieu de cela, vous pouvez maintenant appeler la ligne suivante avant la première utilisation des classes JCE (c'est-à-dire de préférence juste après le démarrage de l'application):

Security.setProperty("crypto.policy", "unlimited");
Sebastian S
la source
Et sur Android? À quel niveau d'API ces méthodes de restriction peuvent-elles être résolues?
TheRealChx101
31

Il s'agit d'une solution uniquement codée . Pas besoin de télécharger ou de jouer avec les fichiers de configuration.

C'est une solution basée sur la réflexion, testée sur java 8

Appelez cette méthode une fois, au début de votre programme.

//Importations

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

//méthode

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
}

Crédits: Delthas

Jako
la source
4
Veuillez noter que cela peut violer l'accord de licence Java SE: D. RESTRICTIONS TECHNOLOGIQUES JAVA. Vous ne pouvez pas créer, modifier ou changer le comportement de, ou autoriser vos titulaires de licence à créer, modifier ou changer le comportement de classes, interfaces ou sous-packages qui sont identifiés de quelque manière que ce soit "java", "javax", " javafx "," sun "," oracle "ou convention similaire comme spécifié par Oracle dans toute désignation de convention de dénomination. [...] source
SimMac
Merci beaucoup
16

J'ai rencontré la même erreur lors de l'utilisation de Windows 7 x64, Eclipse et JDK 1.6.0_30. Le dossier d'installation de JDK contient un jredossier. Cela m'a dérouté au début alors que j'ajoutais les pots susmentionnés au dossier lib / security du JDK sans aucune chance. Chemin complet:

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

Téléchargez et extrayez les fichiers contenus dans le jcedossier de cette archive dans ce dossier.

Brian Bowman
la source
16

En Java, par défaut, AES prend en charge une clé de 128 bits, si vous prévoyez d'utiliser une clé de 192 bits ou 256 bits, java complier lèvera une exception de taille de clé illégale, que vous obtenez.

La solution est comme l'a suggéré Victor & James, vous devrez télécharger JCE (Java Cryptography Extension) selon votre version JRE (java6, java7 ou java8).

Le zip JCE contient le fichier JAR suivant:

  1. local_policy.jar
  2. US_export_policy.jar

Vous devez remplacer ces pots de votre <JAVA_HOME>/jre/lib/security. si vous êtes sur un système unix, le/home/urs/usr/lib/jvm/java-<version>-oracle/

Parfois, le simple remplacement de local_policy.jar, US_export_policy.jar dans le dossier de sécurité ne fonctionne pas sous Unix, je suggère donc de copier d'abord le dossier de sécurité sur votre bureau, de remplacer le dossier @ Desktop / security du pot, de supprimer le dossier de sécurité de / jre / lib / & déplacez le dossier de sécurité du bureau vers / jre / lib /.

par exemple :: sudo mv security /usr/lib/jvm/java-7-oracle/jre/lib

Ketan Vishwakarma
la source
5

Il y a une brève discussion sur ce qui semble être ce problème ici . La page vers laquelle il renvoie semble avoir disparu, mais l'une des réponses pourrait être celle dont vous avez besoin:

En effet, la copie de US_export_policy.jar et local_policy.jar de core / lib / jce vers $ JAVA_HOME / jre / lib / security a aidé. Merci.

RHSeeger
la source
Merci, mais je l' avais US_export_policy.jaret local_policy.jardans mon dossier lib / security déjà installé une fois que je Java .. Et je ne pouvais pas trouver core / lib / jce par le chemin dans mon dossier d'installation de Java.
Rihards
5

le problème est le contenu du fichier default_local.policy dans local_policy.jar dans le dossier jre \ lib \ security , si vous installez le 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;
};

si vous n'avez pas besoin de paramètres valides dans le monde entier, vous pouvez simplement modifier ce fichier et changer le contenu en

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

c'est ce que vous obtenez si vous téléchargez le JCE à partir d'Oracle.

max
la source
4

J'ai également eu le problème mais après avoir remplacé celui existant par celui téléchargé (à partir de JCE), on a résolu le problème. Les nouveaux fichiers cryptographiques ont fourni une force illimitée.

Dev G
la source
2

Par défaut, Java prend uniquement en charge les tailles de clé AES 128 bits (16 octets) pour le chiffrement. Si vous n'avez pas besoin de plus que la prise en charge par défaut, vous pouvez couper la clé à la bonne taille avant de l'utiliser Cipher. Voir javadoc pour les clés prises en charge par défaut.

Il s'agit d'un exemple de génération d'une clé qui fonctionnerait avec n'importe quelle version de JVM sans modifier les fichiers de stratégie. Utilisez à votre discrétion.

Voici un bon article pour savoir si la taille des clés 128 à 256 est importante sur le blog 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);
}
keaplogik
la source
La documentation des classes de chiffrement pointe vers des tailles de clé valides pour chaque type de chiffrement .
keaplogik
Voir le document Oracle Cipher (Encryption) Algorithms AES: Advanced Encryption Standard tel que spécifié par NIST dans FIPS 197. Également connu sous le nom d'algorithme Rijndael par Joan Daemen et Vincent Rijmen, AES est un chiffrement par bloc de 128 bits prenant en charge les clés de 128, 192, et 256 bits.
zaph
Cela peut être vrai, mais il est uniquement requis par chaque version Java pour prendre en charge 128 bits comme spécifié dans la documentation de classe. Testez-le vous-même et vous constaterez que vous aurez besoin du pot de politique de la réponse de James Black pour faire d'autres tailles de clés
keaplogik
Toute implémentation AES qui ne prend pas en charge les clés 256 bits serait essentiellement inutile car elle ne serait pas en mesure de décrypter un nombre important de cryptages AES à l'aide de clés 256 bits.
zaph
1
Si une clé 256 bits est nécessaire, la meilleure solution, peut-être la seule solution, consiste à installer le fichier de stratégie si nécessaire, à ne pas tronquer la clé, ce qui pourrait affaiblir la sécurité et pourrait ne pas être possible en cas d'interopérabilité.
zaph
2

À partir de Java 9 ou 8u151, vous pouvez utiliser commenter une ligne dans le fichier:

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

Et changer:

#crypto.policy=unlimited

à

crypto.policy=unlimited
Ahmed Ashour
la source
2

Si vous utilisez la distribution Linux avec apt et que vous avez ajouté webupd8 PPA, vous pouvez simplement exécuter la commande

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

Autres mises à jour:

  1. Les fichiers de stratégie de juridiction de force illimitée sont inclus avec Java 9 et utilisés par défaut
  2. Commençant par la mise à jour 161 de Java 8, Java 8 utilise par défaut la stratégie de juridiction de force illimitée.
  3. À partir de Java 8 Update 151 , la stratégie de juridiction de force illimitée est incluse avec Java 8 mais n'est pas utilisée par défaut. Pour l'activer, vous devez modifier le fichier java.security dans <java_home>/jre/lib/security(pour JDK) ou <java_home>/lib/security(pour JRE). Décommenter (ou inclure) la ligne

    crypto.policy=unlimited

    Assurez-vous de modifier le fichier à l'aide d'un éditeur exécuté en tant qu'administrateur. Le changement de stratégie ne prend effet qu'après redémarrage de la JVM

Avant la mise à jour 151 de Java 8 autres réponses sont valides. Téléchargez et remplacez les fichiers de stratégie JCE Unlimited Strength Jurisdiction.

Pour plus de détails, vous pouvez consulter mon billet de blog personnel ci-dessous - Comment installer les fichiers de politique de compétence de force illimitée Java Cryptography Extension (JCE)

Aniket Thakur
la source
1

il existe deux options pour résoudre ce problème

option numéro 1: utiliser un certificat de moindre longueur RSA 2048

option numéro 2: vous mettrez à jour deux jars dans jre\lib\security ce que vous utilisez java http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html

ou vous utilisez IBM Websphere ou tout serveur d'applications utilisant sa java. le principal problème que j'ai rencontré j'ai utilisé la certification avec une longueur maximale, lorsque j'ai déployé des oreilles sur la websphere, la même exception est levée

Java Security: Illegal key size or default parameters?

J'ai mis à jour le dossier InSalled Java dans la sphère Web avec deux pots https://www14.software.ibm.com/webapp/iwm/web/reg/pick.do?source=jcesdk&lang=en_US

vous pouvez vérifier la référence dans le lien https://www-01.ibm.com/support/docview.wss?uid=swg21663373

Shaaban Ebrahim
la source
1

Assurez-vous d'utiliser la dernière version de JDK / JRE .

Dans mon cas, j'avais mis JCE dans le dossier JRE, mais cela n'a pas aidé. Cela est arrivé parce que j'exécutais mon projet directement depuis l'IDE (en utilisant JDK).

J'ai ensuite mis à jour mon JDK et JRE vers la dernière version (1.8.0_211) et le problème avait disparu.

Plus de détails: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8170157

Ruslan Sheremet
la source
1

Le JDK par défaut prend en charge le chiffrement uniquement via des clés de 128 bits en raison des restrictions américaines. Donc, pour prendre en charge le cryptage à partir d'une clé longue de 256 bits, nous devons remplacer local_policy.jaret US_export_policy.jarsdans le $JAVA_HOME/java-8-oracle/jre/lib/securitydossier, sinon cela donnera:

java.security.InvalidKeyException: taille de clé illégale ou valeur par défaut

Sulabh Jain
la source
0

Tu dois y aller

/jdk1.8.0_152 | / jre | / lib | / sécurité | java.security et décommenter le

#crypto.policy=unlimited

à

crypto.policy=unlimited
Fzum
la source