如何使用MessageDigest,Base64进行解码

我目前正在编码密码。 我必须解码密码。 这是要编码的代码。 我想把原始密码比作一下。 我研究过MessageDigest,它说这是一种单向方法。 不知道如何获取原始邮件。 我们有一个解码方法,但它没有给我原始密码 – Base64.decode。

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

您无法获得原始密码。 请记住,摘要和Base64编码完成两件完全不同的事情。 MD5摘要创建提供给它的数据的加密哈希。 这是不可逆转的。 Base64是一种编码机制,用于将数据(可能包含不可打印的二进制数据)转换为保证仅包含可打印字符的字符串。 这一步是可逆的。

检查密码的标准方法不是解码原始密码并比较纯文本。 您需要做的是对原始密码进行编码(MD5哈希,然后是Base64编码)并将其应用于新提供的密码。 然后将存储的编码版本与新编码的版本进行比较。 如果它们相同则密码匹配。

这种设计比存储可解码的密码更安全。 这样,如果有人窃取您的密码数据库,他们就不会自动访问您用户的所有密码。 为了进入系统,他们仍然需要找到编码为相同值的密码。 像MD5这样的密码哈希的目的是使这非常困难。 另一方面,MD5不再被认为是非常安全的哈希。 您最好使用SHA1或SHA256(但请记住,您不能将现有存储的密码从其MD5哈希更改为另一个哈希而没有您没有的原始密码,即您不能只转换您的密码存储密码数据库)。

带MD5的MessageDigest是单向散列。 那么,为什么不使用可以轻松加密和解密的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="password@123"; 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); } } 

与所有哈希算法一样,MD5哈希算法是单向的。 恢复原始密码的唯一方法是尝试各种可能性,直到获得MD5哈希与您收到的密码相匹配的密码。

如果您尝试将新密码的内容与旧密码进行比较,则无法使用MD5哈希。 正如Jherico所说,MD5(和所有哈希)都是单向的,意味着你无法获得原始文本。

为了进行比较,您必须将密码的原始值保留在某处。 最好的方法可能是在将数据存储到数据库之前加密(和base64结果)。 然后,为了进行比较,您解密每个值并执行所需的工作

一个重要的注意事项是,如果没有正确完成,以任何可以反转的forms存储用户密码都是危险的。