Java calculer représentation hexadécimale d'un condensé SHA-1 d'une Chaîne
Je suis stocker le mot de passe utilisateur sur la db comme un hash sha1.
Malheureusement, je reçois étrange réponses.
Je suis stocker la chaîne de caractères comme ceci:
MessageDigest cript = MessageDigest.getInstance("SHA-1");
cript.reset();
cript.update(userPass.getBytes("utf8"));
this.password = new String(cript.digest());
Je voulais quelque chose comme ceci -->
aff --> "0c05aa56405c447e6678b7f3127febde5c3a9238"
plutôt que
aff --> �V@\D~fx����:�8
- Remarque: vous ne devriez pas utiliser
sha1
ou comme hachage hachage des mots de passe. Vous devez utiliser un hachage de mot de passe commebcrypt
ouscrypt
. - Remarque: vous ne devez pas être le hachage des mots de passe sans sel.
- Remarque: vous devez envisager d'utiliser des char[] au lieu de Chaîne de caractères pour le mot de passe et d'en éliminer le plus tôt possible après l'utilisation
Vous devez vous connecter pour publier un commentaire.
Ce qui se passe parce que cript.digest() renvoie un tableau d'octets, qui vous essayez d'imprimer une Chaîne de caractère. Vous voulez convertir à un imprimable Chaîne Hexadécimale.
Solution simple: Utiliser Apache communes-bibliothèque de codecs:
À l'aide d'apache codec commun de la bibliothèque:
Le résultat est 0c05aa56405c447e6678b7f3127febde5c3a9238
C'est tout 🙂
String sha1password = DigestUtils.sha1Hex(password);
echo aff|sha1sum
-->c4d21f9a4f09a6645eb25089d39857bc45739ef7
?echo -n "aff" | sha1sum
produire le bon de sortie (echo insère un saut de ligne par défaut)Une itération de l'algorithme de hachage n'est pas sécurisé. C'est trop rapide. Vous devez effectuer les principales renforcement par l'itération de la valeur de hachage de nombreuses fois.
En outre, vous n'êtes pas saler le mot de passe. Cela crée une vulnérabilité à la pré-calculé les dictionnaires, comme "rainbow tables".
Au lieu d'essayer de passer votre propre code (ou à l'aide de quelques croquis tiers inutilités) pour ce faire correctement, vous pouvez utiliser le code intégré à Java runtime. Voir cette réponse pour plus de détails.
Une fois que vous avez haché et le mot de passe correctement, vous aurez un
byte[]
. Un moyen facile de convertir cette hexadécimalString
est avec leBigInteger
classe:Si vous voulez vous assurer que votre chaîne a toujours 40 caractères, vous deviez faire un peu de remplissage avec des zéros sur la gauche (vous pouvez le faire avec
String.format()
.)String hex = String.format("%040x", new BigInteger(1, cript.digest()));
Si vous ne voulez pas de place supplémentaire dépendances de votre projet, vous pouvez également utiliser
La crypte.digest() la méthode retourne un byte[]. Ce tableau d'octets est la bonne SHA-1 en somme, mais crypto hachages sont généralement affichés à l'homme en forme hexagonale. Chaque octet dans votre hash entraîne deux chiffres hexadécimaux.
En toute sécurité convertir un octet hex utiliser ceci:
Cet extrait de code peut être utilisé pour la conversion d'un char à l'hex:
Remarque que le travail avec des octets en Java est très sujettes à erreur. Je double tout vérifier et de tester certaines étrange cas ainsi.
Aussi, vous devriez envisager d'utiliser quelque chose de plus fort que SHA-1.
http://csrc.nist.gov/groups/ST/hash/statement.html
Si vous utilisez Printemps, son assez simple:
Il n'y a plus qu'un simple standard algorithmes de hachage impliqués dans le stockage des mots de passe non réversible.
Pour plus d'info, voir, par exemple,
Vous pouvez également utiliser un http://en.wikipedia.org/wiki/Password-authenticated_key_agreement méthode pour éviter de transmettre le mot de passe en clair sur le serveur.
Vous pouvez utiliser Google Goyave:
Maven:
Exemple:
digest() renvoie un tableau d'octets, dont vous êtes la conversion d'une chaîne en utilisant le codage par défaut. Ce que vous voulez faire est de l'encoder en base64.
Pour utiliser l'UTF-8, ce faire:
Et pour obtenir un Base64 Chaîne à partir de l'empreinte, vous pouvez faire quelque chose comme ceci:
Depuis
MessageDigest.digest()
renvoie un tableau d'octets, vous pouvez le convertir en Chaîne à l'aide de Apache Codage Hexadécimal (plus simple).E. g.
Comment convertir byte[] pour base64 chaîne?
vous pouvez utiliser ce code trop(à partir de crackstation.net):
private static String toHex(byte[] array)
{
BigInteger bi = new BigInteger(1, array);
String hex = bi.toString(16);
int paddingLength = (array.length * 2) - hex.length();
if(paddingLength > 0)
return String.format("%0" + paddingLength + "d", 0) + hex;
else
return hex;
}
echo-n "aff" | sha1sum produire le bon de sortie (echo insère un saut de ligne par défaut)
Vous devez hex encoder le résultat de la première.
MessageDigest
renvoie une "brute" de hachage, plutôt que de un, lisible par un.Edit:
@thejh fourni un lien vers le code qui devrait fonctionner. Personnellement, je vous conseille d'utiliser soit Bouncycastle ou Apache Commons Codec pour faire le travail. Bouncycastle serait une bonne chose si vous voulez d'autres crypto-opérations liées.