如何使用MessageDigest,Base64进行解码

时间:2010-08-13 16:55:46

标签: java hash 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;
    }
}

4 个答案:

答案 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结果)。然后,为了进行比较,您解密每个值并执行您想要的工作

一个重要的注意事项是,如果操作不当,以任何可以反转的形式存储用户密码都会很危险。