2010-08-13 318 views
4

我目前正在編碼密碼。我必須解碼密碼。這是要編碼的代碼。我正在嘗試獲取原始密碼進行比較。我研究了MessageDigest,它說這是一種單向方法。不知道如何獲得原始信息。我們有一個解碼方法,但它不給我原來的密碼 - Base64.decode。如何解碼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; 
    } 
} 

回答

8

您無法獲取原始密碼。請記住,摘要和Base64編碼完成兩個完全不同的事情。 MD5摘要創建提供給它的數據的加密哈希。這是不可逆轉的。 Base64是一種編碼機制,用於將數據(可能包含不可打印的二進制數據)轉換爲保證僅包含可打印字符的字符串。這一步是可逆的。

檢查密碼的標準方法不是解碼原始密碼並比較純文本。你需要做的是對原始密碼進行編碼(MD5哈希,然後Base64編碼),並將其應用於新提供的密碼。然後將存儲的編碼版本與新編碼的版本進行比較。如果它們相同,那麼密碼匹配。

這種設計比存儲可以解碼的密碼更安全。這樣,如果有人竊取您的密碼數據庫,他們不會自動訪問您的用戶的所有密碼。爲了打入系統,他們仍然需要找到一個編碼爲相同值的密碼。像MD5這樣的密碼哈希值就是爲了讓這非常困難。另一方面,MD5不再被認爲是一個非常安全的散列。您最好使用SHA1或SHA256(但請記住,您不能將原有存儲的密碼從其MD5哈希值更改爲另一個哈希值,而不使用原始密碼,這是您沒有的,也就是說,您不能將其轉換爲存儲的密碼數據庫)。

+0

嗨Jherico。 問題是我想比較當前密碼中以前的密碼沒有4個連續的字符,所以試圖讓MD5 Base64的模式出現不正確。所以我試圖回到原始密碼進行比較。 – Perry 2010-08-13 18:07:26

+0

我想知道如果我應該只解碼以前的密碼,用新密碼創建MD5,只是比較MD5的創建?只是不確定我該怎麼做。 :) – Perry 2010-08-13 18:14:27

+0

它不可能。密碼散列的要點是每個輸出位都可能受到每個輸入位的影響。沒有辦法與您所擁有的數據進行比較。 – Jherico 2010-08-13 23:43:56

3

MD5哈希算法就像所有哈希算法一樣。恢復原始密碼的唯一方法是嘗試每種可能性,直到獲得其MD5哈希符合您所收到的密碼。

+2

這不會(必然)實際找到原始密碼。相反,你會發現哈希碰撞。當然,由於哈希值是128位,並且常用密碼域的大小可能遠不及此值,因此您可能會發現實際的密碼 – Jherico 2010-08-13 17:17:33

1

如果您嘗試將新密碼的內容與舊密碼進行比較,則無法使用MD5散列。正如Jherico所指出的,MD5(和所有哈希)是單向的,意味着你無法獲得原始文本。

爲了做比較,你必須保持密碼的原始值在某個地方。最好的方法是在將數據存儲到數據庫之前加密(並將結果base64)。然後,爲了進行比較,您需要解密每個值並執行所需的工作。

一個重要的注意事項是,如果未正確完成,存儲用戶密碼的方式可能會顛倒過來。

5

MessageDigest with MD5 is one way hash。那麼,爲什麼不使用javax.crypto可以輕鬆加密和解密。這裏是例子:

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); 

    } 
}