我目前正在编码密码。我必须解码密码。这是要编码的代码。我想把原始密码比作一下。我研究过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;
}
}
答案 0 :(得分:10)
您无法获取原始密码。请记住,摘要和Base64编码完成两件完全不同的事情。 MD5摘要创建提供给它的数据的加密哈希。这是不可逆转的。 Base64是一种编码机制,用于将数据(可能包含不可打印的二进制数据)转换为保证仅包含可打印字符的字符串。这一步是可逆的。
检查密码的标准方法不是解码原始密码并比较纯文本。您需要做的是对原始密码进行编码(MD5哈希,然后是Base64编码),并将其应用于新提供的密码。然后将存储的编码版本与新编码的版本进行比较。如果它们相同则密码匹配。
这种设计比存储可解码的密码更安全。这样,如果有人窃取您的密码数据库,他们就不会自动访问您用户的所有密码。为了进入系统,他们仍然必须找到编码为相同值的密码。像MD5这样的加密哈希点就是非常困难。另一方面,MD5不再被认为是非常安全的哈希。您最好使用SHA1或SHA256(但请记住,您不能将现有存储的密码从其MD5哈希更改为另一个哈希而没有您没有的原始密码,即您不能只转换您的密码存储密码数据库)。
答案 1 :(得分:8)
带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);
}
}
答案 2 :(得分:3)
与所有哈希算法一样,MD5哈希算法是单向的。恢复原始密码的唯一方法是尝试各种可能性,直到获得MD5哈希值与您收到的密码匹配的那个。
答案 3 :(得分:1)
如果您尝试将新密码的内容与旧密码进行比较,则无法使用MD5哈希。正如Jherico所说,MD5(以及所有哈希)都是单向的,意味着你无法获得原始文本。
为了进行比较,您必须将密码的原始值保留在某处。最好的方法是在将数据存储到数据库之前对其进行加密(和base64结果)。然后,为了进行比较,您解密每个值并执行您想要的工作
一个重要的注意事项是,如果操作不当,以任何可以反转的形式存储用户密码都会很危险。