Lors du chargement de clés de chiffrement en Java, une expection InvalidKeyException avec le message "Illegal key size" peut être levée en raison des restrictions imposées par les politiques de cryptographie JCE (Java Cryptography Extension) dans certaines versions de Java. Ces limitations découlent de contraintes légales sur la force du chiffrement.
Plusieurs approches permettent de contourner ce problème :
- Mettre à niveau vers Java 8u162 ou supérieur, où la politique de cryptographie illimitée est activée par défaut.
- Pour les versions Java 8u151 et 8u152, configurer la propriété de sécurité directement dans l'application.
- Pour les versions antérieures, télécharger et appliquer les fichiers de politique de sécurité illimitée en remplaçant les fichiers dans le répertoire
$JAVA_HOME/lib/security. - À partir de Java 9, aucune restriction n'est appliquée.
- Modifier dynamiquement la politique de sécurité au chargement de la classe.
Exemple pour configurer la propriété dans Java 8u151/8u152 :
Security.setProperty("crypto.policy", "unlimited");
Voici une implémentation Java qui désactive les restrictions de cryptographie de manière dynamique :
public class DesactiverRestrictionsCrypto {
static {
try {
Security.setProperty("crypto.policy", "limited");
leverLesRestrictions();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void leverLesRestrictions() throws Exception {
Class> securiteJce = obtenirClasse("javax.crypto.JceSecurity");
Class> permissionsCrypto = obtenirClasse("javax.crypto.CryptoPermissions");
Class> toutePermission = obtenirClasse("javax.crypto.CryptoAllPermission");
if (securiteJce != null) {
definirValeurStatiqueFinale(securiteJce, "isRestricted", false);
PermissionCollection politiqueDefaut = (PermissionCollection) obtenirValeurChamp(securiteJce, "defaultPolicy", null, PermissionCollection.class);
if (permissionsCrypto != null) {
Map, ?> cartePermissions = (Map) obtenirValeurChamp(permissionsCrypto, "perms", politiqueDefaut, Map.class);
cartePermissions.clear();
}
if (toutePermission != null) {
Permission permissionAccord = (Permission) obtenirValeurChamp(toutePermission, "INSTANCE", null, Permission.class);
politiqueDefaut.add(permissionAccord);
}
}
}
private static Class> obtenirClasse(String nomClasse) {
Class> classe = null;
try {
classe = Class.forName(nomClasse);
} catch (Exception e) {
// Exception ignorée
}
return classe;
}
private static void definirValeurStatiqueFinale(Class> classeSource, String nomChamp, Object valeur) throws Exception {
Field champ = classeSource.getDeclaredField(nomChamp);
champ.setAccessible(true);
Field champModificateurs = Field.class.getDeclaredField("modifiers");
champModificateurs.setAccessible(true);
champModificateurs.setInt(champ, champ.getModifiers() & ~java.lang.reflect.Modifier.FINAL);
champ.set(null, valeur);
}
private static <T> T obtenirValeurChamp(Class> classeSource, String nomChamp, Object proprietaire, Class<T> typeDestination) throws Exception {
Field champ = classeSource.getDeclaredField(nomChamp);
champ.setAccessible(true);
return typeDestination.cast(champ.get(proprietaire));
}
}