2010-08-13 11 views
4

Je suis actuellement en train d'encoder un mot de passe. Je dois déchiffrer le mot de passe. Voici le code à encoder. J'essaye d'obtenir le mot de passe original le compare. J'ai recherché sur MessageDigest qui dit que c'est une méthode à sens unique. Je ne sais pas comment obtenir le message original. Nous avons une méthode de décodage mais elle ne me donne pas le mot de passe original - Base64.decode.Comment décoder avec MessageDigest, Base64

public static synchronized String getMD5_Base64(String input) { 
     if (!isInited) { 
      isInited = true; 
      try { 
       digest = MessageDigest.getInstance("MD5"); 
      } catch (Exception ex) { 
      } 
     } 
     if (digest == null) 
      return input; 

     // now everything is ok, go ahead 
     try { 
      digest.update(input.getBytes("UTF-8")); 
     } catch (java.io.UnsupportedEncodingException ex) { 
     } 
     byte[] rawData = digest.digest(); 
     byte[] encoded = Base64.encode(rawData); 
     String retValue = new String(encoded); 
     return retValue; 
    } 
} 

Répondre

8

Vous ne pouvez pas obtenir le mot de passe d'origine. Gardez à l'esprit que le digest et l'encodage Base64 font deux choses complètement différentes. Le résumé MD5 crée un hachage cryptographique des données qui lui sont fournies. C'est irréversible. Base64 est un mécanisme de codage pour convertir les données (qui peuvent contenir des données binaires non imprimables) en une chaîne qui ne contient que des caractères imprimables. Cette étape est réversible.

La manière standard de vérifier un mot de passe n'est pas de décoder le mot de passe original et de comparer le texte brut. Ce que vous devez faire est de prendre l'encodage (codage MD5 puis encodage Base64) que vous avez fait sur le mot de passe original et l'appliquer au nouveau mot de passe. Comparez ensuite la version codée stockée avec la version nouvellement codée. Si ce sont les mêmes, les mots de passe correspondent.

Cette conception est un mécanisme plus sûr que le stockage de mots de passe susceptibles d'être décodés. Ainsi, si quelqu'un vole votre base de données de mots de passe, il n'a pas automatiquement accès à tous les mots de passe de vos utilisateurs. Pour pénétrer dans le système, ils doivent toujours trouver un mot de passe codé à la même valeur. Le point des hachages cryptographiques comme MD5 est de rendre cela très difficile. D'autre part, MD5 n'est plus considéré comme un hachage très sécurisé. Vous feriez mieux d'utiliser SHA1 ou SHA256 (mais rappelez-vous, vous ne pouvez pas changer les mots de passe stockés de leur hachage MD5 en un autre hachage sans le mot de passe original, ce que vous n'avez pas, c'est-à-dire base de données de mots de passe stockés).

+0

Salut Jherico. Le problème est que j'essaie de comparer qu'il n'y a pas 4 caractères consécutifs des mots de passe précédents dans le mot de passe actuel essayant ainsi d'obtenir le modèle du MD5 Base64 sort incorrectement. J'essayais donc de revenir aux mots de passe origianl pour les comparer. – Perry

+0

Je me demande si je devrais juste décoder les pwds précédents, créer MD5 avec un nouveau mot de passe et juste comparer ce que le MD5 a créé? Je ne sais pas vraiment comment je devrais faire ça. :) – Perry

+0

C'est impossible. Le point d'un hachage cryptographique est que chaque bit de sortie est potentiellement influencé par chaque bit d'entrée.Il n'y a aucun moyen de faire le genre de comparaison que vous suggérez avec les données que vous avez. – Jherico

3

L'algorithme de hachage MD5 est, comme tous les algorithmes de hachage, unidirectionnel. La seule façon de récupérer le mot de passe d'origine est d'essayer toutes les possibilités jusqu'à ce que vous obteniez celui dont le hachage MD5 correspond à ce que vous avez reçu.

+2

Cela ne trouvera pas (nécessairement) le mot de passe original. Au contraire, vous aurez trouvé une collision de hachage. Accordé, puisque le hachage est 128 bits et la taille du domaine des mots de passe communément utilisés vient probablement loin que le capot probable est que vous aurez trouvé le mot de passe réel – Jherico

1

Si vous essayez de comparer le contenu du nouveau mot de passe avec les anciens mots de passe, vous ne pouvez pas utiliser un hachage MD5. Comme l'a noté Jherico, MD5 (et tous les hashs) sont à sens unique, ce qui signifie que vous ne pouvez pas obtenir le texte original.

Afin de faire la comparaison, vous devrez conserver la valeur d'origine du mot de passe quelque part. Le meilleur moyen est probablement de chiffrer (et de base64 le résultat) avant de le stocker dans la base de données. Ensuite, afin de faire la comparaison, vous décrypter chacune des valeurs et faire le travail que vous voulez

Une note importante est que le stockage des mots de passe de l'utilisateur sous une forme qui peut être inversée peut être dangereux s'il n'est pas fait correctement.

5

MessageDigest avec MD5 est un hachage à sens unique. Donc, pourquoi n'utilisez-vous pas javax.crypto qui peut crypter et décrypter facilement. Voici l'exemple:

import java.security.spec.KeySpec; 
import javax.crypto.Cipher; 
import javax.crypto.SecretKey; 
import javax.crypto.SecretKeyFactory; 
import javax.crypto.spec.DESedeKeySpec; 
import org.apache.commons.codec.binary.Base64; 

public class EncryptDecrypt { 
    private static final String UNICODE_FORMAT = "UTF8"; 
    public static final String DESEDE_ENCRYPTION_SCHEME = "DESede"; 
    private KeySpec ks; 
    private SecretKeyFactory skf; 
    private Cipher cipher; 
    byte[] arrayBytes; 
    private String myEncryptionKey; 
    private String myEncryptionScheme; 
    SecretKey key; 

    public EncryptDecrypt() throws Exception { 
     myEncryptionKey = "ThisIsSpartaThisIsSparta"; 
     myEncryptionScheme = DESEDE_ENCRYPTION_SCHEME; 
     arrayBytes = myEncryptionKey.getBytes(UNICODE_FORMAT); 
     ks = new DESedeKeySpec(arrayBytes); 
     skf = SecretKeyFactory.getInstance(myEncryptionScheme); 
     cipher = Cipher.getInstance(myEncryptionScheme); 
     key = skf.generateSecret(ks); 
    } 


    public String encrypt(String unencryptedString) { 
     String encryptedString = null; 
     try { 
      cipher.init(Cipher.ENCRYPT_MODE, key); 
      byte[] plainText = unencryptedString.getBytes(UNICODE_FORMAT); 
      byte[] encryptedText = cipher.doFinal(plainText); 
      encryptedString = new String(Base64.encodeBase64(encryptedText)); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return encryptedString; 
    } 


    public String decrypt(String encryptedString) { 
     String decryptedText=null; 
     try { 
      cipher.init(Cipher.DECRYPT_MODE, key); 
      byte[] encryptedText = Base64.decodeBase64(encryptedString.getBytes()); 
      byte[] plainText = cipher.doFinal(encryptedText); 
      decryptedText= new String(plainText); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return decryptedText; 
    } 


    public static void main(String args []) throws Exception 
    { 
     EncryptDecrypt td= new EncryptDecrypt(); 

     String target="[email protected]"; 
     String encrypted=td.encrypt(target); 
     String decrypted=td.decrypt(encrypted); 

     System.out.println("String To Encrypt: "+ target); 
     System.out.println("Encrypted String: " + encrypted); 
     System.out.println("Decrypted String: " + decrypted); 

    } 
}