Je dois implémenter le cryptage AES 256 bits, mais tous les exemples que j'ai trouvés en ligne utilisent un "KeyGenerator" pour générer une clé 256 bits, mais je voudrais utiliser ma propre clé d'accès. Comment puis-je créer ma propre clé? J'ai essayé de le remplir à 256 bits, mais je reçois une erreur indiquant que la clé est trop longue. J'ai le correctif de juridiction illimité installé, donc ce n'est pas le problème :)
C'est à dire. Le KeyGenerator ressemble à ceci ...
// Get the KeyGenerator
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128); // 192 and 256 bits may not be available
// Generate the secret key specs.
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
ÉDITER
En fait, je remplissais le mot de passe à 256 octets, pas des bits, ce qui est trop long. Ce qui suit est un code que j'utilise maintenant que j'ai plus d'expérience avec cela.
byte[] key = null; // TODO
byte[] input = null; // TODO
byte[] output = null;
SecretKeySpec keySpec = null;
keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
output = cipher.doFinal(input)
Les bits "TODO" que vous devez faire vous-même :-)
java
encryption
cryptography
passwords
aes
Nippysaurus
la source
la source
Réponses:
Partagez le
password
(achar[]
) etsalt
(a -byte[]
8 octets sélectionnés par unSecureRandom
fait un bon sel - qui n'a pas besoin d'être gardé secret) avec le destinataire hors bande. Ensuite, pour dériver une bonne clé de ces informations:Les nombres magiques (qui pourraient être définis comme des constantes quelque part) 65536 et 256 sont le nombre d'itérations de dérivation de clé et la taille de clé, respectivement.
La fonction de dérivation de clé est itérée pour exiger un effort de calcul important, et cela empêche les attaquants d'essayer rapidement de nombreux mots de passe différents. Le nombre d'itérations peut être modifié en fonction des ressources informatiques disponibles.
La taille de la clé peut être réduite à 128 bits, ce qui est toujours considéré comme un cryptage "fort", mais cela ne donne pas beaucoup de marge de sécurité si l'on découvre des attaques qui affaiblissent AES.
Utilisée avec un mode de chaînage de blocs approprié, la même clé dérivée peut être utilisée pour crypter de nombreux messages. Dans Cipher Block Chaining (CBC) , un vecteur d'initialisation aléatoire (IV) est généré pour chaque message, produisant un texte chiffré différent même si le texte brut est identique. CBC n'est peut-être pas le mode le plus sûr à votre disposition (voir AEAD ci-dessous); il existe de nombreux autres modes avec des propriétés de sécurité différentes, mais ils utilisent tous une entrée aléatoire similaire. Dans tous les cas, les sorties de chaque opération de chiffrement sont le texte chiffré et le vecteur d'initialisation:
Stockez le
ciphertext
et leiv
. Lors du déchiffrement, leSecretKey
est régénéré exactement de la même manière, en utilisant le mot de passe avec les mêmes paramètres de sel et d'itération. Initialisez le chiffrement avec cette clé et le vecteur d'initialisation stocké avec le message:Java 7 incluait la prise en charge de l' API pour les modes de chiffrement AEAD , et le fournisseur "SunJCE" inclus avec les distributions OpenJDK et Oracle les implémente à partir de Java 8. L'un de ces modes est fortement recommandé à la place de CBC; il protégera l'intégrité des données ainsi que leur confidentialité.
Un
java.security.InvalidKeyException
avec le message "Taille de clé illégale ou paramètres par défaut" signifie que la puissance de cryptographie est limitée; les fichiers de politique de compétence de force illimitée ne sont pas au bon endroit. Dans un JDK, ils doivent être placés sous${jdk}/jre/lib/security
D'après la description du problème, il semble que les fichiers de stratégie ne soient pas correctement installés. Les systèmes peuvent facilement avoir plusieurs runtimes Java; revérifiez pour vous assurer que l'emplacement correct est utilisé.
la source
PBEwith<prf>and<encryption>
algorithmes; par exemple, le SunJCE ne fournit pas et PBE pour AES. Deuxièmement, l'activation de jasypt n'est pas un objectif. Un paquet qui prétend offrir la sécurité sans exiger une compréhension des principes sous-jacents semble dangereux à première vue.tmp.getEncoded()
comme hachage. Vous devez également stocker lessalt
itérations et (65536 dans cet exemple) afin de pouvoir recalculer le hachage lorsque quelqu'un essaie de s'authentifier. Dans ce cas, générez le sel avec un générateur de nombres aléatoires cryptographiques à chaque changement de mot de passe.Pensez à utiliser le module Spring Security Crypto
Il fournit une abstraction simple pour le chiffrement et semble correspondre à ce qui est requis ici,
Un regard sur les internes révèle une structure similaire à la réponse d' Erickson .
Comme indiqué dans la question, cela nécessite également la politique de juridiction de force illimitée JCE (Java Cryptography Extension) (sinon vous rencontrerez
InvalidKeyException: Illegal Key Size
). Il est téléchargeable pour Java 6 , Java 7 et Java 8 .Exemple d'utilisation
Et un échantillon de sortie,
la source
NULL_IV_GENERATOR
utilitaire Spring n'est pas sécurisé. Si l'application ne fournit pas de IV, laissez le fournisseur le choisir et interrogez-le après l'initialisation.Après avoir lu les suggestions d'Erickson et glané ce que je pouvais de quelques autres publications et de cet exemple ici , j'ai essayé de mettre à jour le code de Doug avec les changements recommandés. N'hésitez pas à modifier pour le rendre meilleur.
Quelques remarques: Cela utilise une clé de cryptage 128 bits - java ne fera apparemment pas de cryptage 256 bits prêt à l'emploi. L'implémentation de 256 nécessite l'installation de fichiers supplémentaires dans le répertoire d'installation java.
De plus, je ne suis pas un crypto. Prenez garde.
la source
printStackTrace()
CipherInputStream
etCipherOutputStream
n'est pas vraiment un problème. Mélanger toutes les exceptions sous le tableau est un problème. Le fait que le sel soit soudainement devenu un champ et que la perfusion intraveineuse soit nécessaire est un problème. Le fait qu'il ne respecte pas les conventions de codage Java est un problème. Et le fait que cela ne fonctionne que sur les fichiers alors qu'il n'a pas été demandé est un problème. Et que le reste du code est fondamentalement une copie n'aide pas non plus. Mais peut-être que je vais l'ajuster pour l'améliorer, comme suggéré ...Générer votre propre clé à partir d'un tableau d'octets est simple:
Mais la création d'une clé 256 bits n'est pas suffisante. Si le générateur de clés ne peut pas générer de clés 256 bits pour vous, le
Cipher
classe ne prend probablement pas en charge AES 256 bits non plus. Vous dites que le patch de juridiction illimitée est installé, donc le chiffrement AES-256 devrait être pris en charge (mais les clés 256 bits devraient l'être aussi, donc cela pourrait être un problème de configuration).Une solution de contournement en raison du manque de prise en charge de l'AES-256 consiste à prendre une implémentation librement disponible de l'AES-256 et à l'utiliser comme fournisseur personnalisé. Cela implique de créer votre propre
Provider
sous-classe et de l'utiliser avecCipher.getInstance(String, Provider)
. Mais cela peut être un processus complexe.la source
Cipher
, pas dans le fournisseur lui-même. Vous pouvez utiliser AES-256 dans Java 8 et versions antérieures, mais vous devez utiliser une API propriétaire. Ou un runtime qui ne pose pas de restrictions sur la taille de la clé bien sûr.Ce que j'ai fait dans le passé, c'est hacher la clé via quelque chose comme SHA256, puis extraire les octets du hachage dans l'octet de clé [].
Une fois que vous avez votre octet [], vous pouvez simplement faire:
la source
Cipher aes256 = Cipher.getInstance("AES/OFB/NoPadding"); MessageDigest keyDigest = MessageDigest.getInstance("SHA-256"); byte[] keyHash = keyDigest.digest(secret.getBytes("UTF-8")); SecretKeySpec key = new SecretKeySpec(keyHash, "AES"); aes256.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(initializationVector));
Je fais aussi la même chose que suggéré dans votre réponse, mais je me retrouve toujours avec cette java.security.InvalidKeyException: taille de clé illégale Le téléchargement du fichier de stratégie JCE est-il obligatoire?Ajout aux modifications de @ Wufoo, la version suivante utilise InputStreams plutôt que des fichiers pour faciliter le travail avec une variété de fichiers. Il stocke également l'IV et le sel au début du fichier, ce qui fait que seul le mot de passe doit être suivi. Étant donné que l'IV et le sel n'ont pas besoin d'être secrets, cela rend la vie un peu plus facile.
la source
(Peut-être utile pour d'autres ayant une exigence similaire)
J'avais une exigence similaire pour utiliser le
AES-256-CBC
cryptage et le décryptage en Java.Pour obtenir (ou spécifier) le cryptage / décryptage de 256 octets, la
Java Cryptography Extension (JCE)
stratégie doit être définie sur"Unlimited"
Il peut être défini dans le
java.security
fichier sous$JAVA_HOME/jre/lib/security
(pour JDK) ou$JAVA_HOME/lib/security
(pour JRE)crypto.policy=unlimited
Ou dans le code comme
Java 9 et les versions ultérieures ont cette option activée par défaut.
la source
Pensez à utiliser Encryptor4j dont je suis l'auteur.
Assurez-vous d'abord que les fichiers de stratégie de juridiction de force illimitée sont installés avant de continuer afin de pouvoir utiliser des clés AES 256 bits.
Procédez ensuite comme suit:
Vous pouvez maintenant utiliser le crypteur pour crypter votre message. Vous pouvez également effectuer un chiffrement en streaming si vous le souhaitez. Il génère et ajoute automatiquement un IV sécurisé pour votre commodité.
Si c'est un fichier que vous souhaitez compresser, jetez un œil à cette réponse Crypter un gros fichier avec AES en utilisant JAVA pour une approche encore plus simple.
la source
Utilisez cette classe pour le chiffrement. Ça marche.
Et ce sont des ivBytes et une clé aléatoire;
la source