簡體   English   中英

生成MD5哈希

[英]Generating MD5 Hash

我有一個發送給我的密碼,使用基於數字ID的MD5哈希使用AES對其進行加密

從請求中,我可以獲取數據庫中具有其他屬性的ID,因此在服務器端,我需要獲取ID,根據該ID獲取MD5哈希,並使用AES算法和生成的MD5解密密碼哈希。

我正在使用以下代碼來獲取MD5哈希

 try {
        byte[] bytesOfMessage = id.getBytes("UTF-8");
        log.error "bytesOfMessage length: " + bytesOfMessage.length
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] thedigest = md.digest(bytesOfMessage);

        md5Value = new String(thedigest);
        log.error "md5Value length: " + md5Value.length()
        log.error "md5Value bytes length: " + md5Value.getBytes().length
    } catch (UnsupportedEncodingException e) {
        log.error "[getMD5EncryptionKey]UnsupportedEncodingException: " + e;
    } catch (NoSuchAlgorithmException e) {
        log.error "[getMD5EncryptionKey]NoSuchAlgorithmException: " + e;
    }

md5Value的長度是基於ID 1的16,但是當我從md5value獲取字節時,有34個字節

當我使用此MD5哈希和javax.crypto.Cipher庫解密密碼時,收到以下消息

java.security.InvalidKeyException:無效的AES密鑰長度:34個字節

有什么想法我在這里做錯了嗎?

我用來解密消息的代碼如下

  try {
        byte [] encryptionKeyBytes = md5EncryptionKey.getBytes("UTF-8");
        Key key = new SecretKeySpec(encryptionKeyBytes, "AES");
        Cipher c = Cipher.getInstance("AES");
        c.init(Cipher.DECRYPT_MODE, key);
        byte[] decodedValue = new Base64().decode(encryptedData);
        byte[] decValue = c.doFinal(decodedValue);
        String decryptedValue = new String(decValue);
        return decryptedValue;
    } catch (InvalidKeyException e) {
        log.error "[getDecryptedValue] InvalidKeyException: " + e
    } catch (IllegalBlockSizeException e) {
        log.error "[getDecryptedValue] InvalidKeyException: " + e
    } catch (BadPaddingException e) {
        log.error "[getDecryptedValue] InvalidKeyException: " + e
    } catch (NoSuchAlgorithmException e) {
        log.error "[getDecryptedValue] InvalidKeyException: " + e
    } catch (NoSuchPaddingException e) {
        log.error "[getDecryptedValue] InvalidKeyException: " + e
    } catch (Exception e) {
        log.error "[getDecryptedValue] InvalidKeyException: " + e
    }

您獲得的字節數組是md5-hash,但具有十六進制值。

您不能只將數組轉換為字符串。 您必須使用采用這些六值並提供適當字符串的算法來對其進行轉換。

在下面,您可以看到獲取32位MD5Hash-String的算法,這可能會有所幫助:

public String createHashString(String s)
{

    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] bytesOfMessage = s.getBytes("UTF-8");
        byte[] thedigest = md.digest(bytesOfMessage);


        String hexString = "";
        for(byte bi : thedigest)
        {
            String hex = Integer.toHexString(0xFF & bi);
            if (hex.length() == 1) {

                hexString += "0";
            }
            hexString += (hex);
        }

        return hexString;

    } 
    catch (Exception e) {
        return "";
    }
}

這個md5Value = new String(thedigest)是您的問題。 thedigest是二進制的,並且String類無法確定其編碼(因為沒有編碼),當您嘗試將其從String中找回時,這會導致二進制值被修飾。 這就是為什么md5Value.getBytes().length為34個字節的原因。 直接從thedigest創建SecretKeySpec

Key key = new SecretKeySpec(thedigest, "AES");

AES密鑰必須是MD5哈希的實際16字節二進制值。

還要注意, new String(someBinaryByteArray).getBytes() 有時會返回您輸入的相同字節,但是這完全取決於輸入。 您的輸入id值說明了這一點。 另一個例子:

String id = "test";
byte[] bytesOfMessage = id.getBytes("UTF-8");
System.out.println("bytesOfMessage length: " + bytesOfMessage.length);
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(bytesOfMessage);
System.out.println("thedigest Hex: " + Hex.encodeHexString(thedigest));
String md5Value = new String(thedigest);
System.out.println("md5Value length: " + md5Value.length());
System.out.println("md5Value bytes length: " + md5Value.getBytes().length);
System.out.println("md5Value Hex: " + Hex.encodeHexString(md5Value.getBytes()));

Output:
bytesOfMessage length: 4
thedigest Hex: 098f6bcd4621d373cade4e832627b4f6
md5Value length: 16
md5Value bytes length: 16
md5Value Hex: 093f6bcd4621d373cade4e832627b4f6

098f6bcd4621d373cade4e832627b4f6 != 093f6bcd4621d373cade4e832627b4f6

問題在於字符串是十六進制的。 我建議您使用apache commons代碼包。 那里有一個哈希實用程序類。

http://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/digest/DigestUtils.html

然后,您可以使用以下代碼:

String md5 = DigestUtils.md5Hex(id);
// or
byte[] md5 = DigestUtils.md5(id);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM