57 votes

Java calcule un sha1 d'une chaîne

Les gars, je stocke le mot de passe de l'utilisateur sur la base de données sous forme de hash sha1.

Malheureusement, je reçois des réponses étranges.

Je stocke la chaîne 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 ça ->

aff -> "0c05aa56405c447e6678b7f3127febde5c3a9238"

plutôt que

aff -> �V @ \ D ~ fx���� \: 8

102voto

altumano Points 1201

Utilisation de la bibliothèque de codecs commune Apache:

 DigestUtils.sha1Hex("aff")
 

Le résultat est 0c05aa56405c447e6678b7f3127febde5c3a9238

C'est tout :)

40voto

Jason Nichols Points 5055

Cela se produit car cript.digest () renvoie un tableau d'octets que vous essayez d'imprimer sous forme de chaîne de caractères. Vous voulez le convertir en une chaîne hexagonale imprimable.

Solution simple: utilisez la bibliothèque commons-codec d' Apache:

 String password = new String(Hex.encodeHex(cript.digest()),
                             CharSet.forName("UTF-8"));
 

24voto

erickson Points 127945

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écimal String est le BigInteger classe:

String passwordHash = new BigInteger(1, cript.digest()).toString(16);

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().)

5voto

cyber-monk Points 2597

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.

Pour convertir en toute sécurité un octet hex utiliser ceci:

// %1$ == arg 1
// 02  == pad with 0's
// x   == convert to hex
String hex = String.format("%1$02x", byteValue);

Cet extrait de code peut être utilisé pour la conversion d'un char à l'hex:

/*
 * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Oracle or the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */ 
import java.io.*;

public class UnicodeFormatter  {

   static public String byteToHex(byte b) {
      // Returns hex String representation of byte b
      char hexDigit[] = {
         '0', '1', '2', '3', '4', '5', '6', '7',
         '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
      };
      char[] array = { hexDigit[(b >> 4) & 0x0f], hexDigit[b & 0x0f] };
      return new String(array);
   }

   static public String charToHex(char c) {
      // Returns hex String representation of char c
      byte hi = (byte) (c >>> 8);
      byte lo = (byte) (c & 0xff);
      return byteToHex(hi) + byteToHex(lo);
   }
}

Notez que le fait de travailler avec des octets en Java est très sujettes à erreur. Je double tout vérifier et de tester certains cas étranges.

En outre, vous devriez envisager d'utiliser quelque chose de plus fort que SHA-1. http://csrc.nist.gov/groups/ST/hash/statement.html

2voto

Vedran Points 2107

Si vous utilisez Spring c'est assez simple:

 MessageDigestPasswordEncoder encoder = new MessageDigestPasswordEncoder("SHA-1");
String hash = encoder.encodePassword(password, "salt goes here");
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by: