簡體   English   中英

有關Hmac SHA256不同編程語言的問題

[英]Issue regarding Hmac SHA256 in different programming languages

嘗試在不同的編程語言中集成HMACSHA256(哈希)時遇到問題。 我嘗試使用Java和C#中的標准預定義方法來實現標准算法,並且使用不同的語言會得到不同的結果。 請在下面查看我在Java和C#中的實現:

Java的:

    public static String convertSHAWithSalt(String value, String salt)
                throws NoSuchAlgorithmException, InvalidKeyException {
            String data = "";
            try {
                MessageDigest md = MessageDigest.getInstance("SHA-256");
                md.update(salt.getBytes(StandardCharsets.UTF_8));
                byte[] bytes = md.digest(value.getBytes(StandardCharsets.UTF_8));
                StringBuilder sb = new StringBuilder();
                for (byte b : bytes) {
                    sb.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
                }
                data = sb.toString();
                System.out.println(data);
                } catch (NoSuchAlgorithmException e) {
                  e.printStackTrace();
               }
            }

字符串值'abcd'和空鹽值的結果: 88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589

C#:

       public static string createHash(string message, string secret)
        {

            byte[] keyByte = System.Text.Encoding.UTF8.GetBytes(secret);

            byte[] messageBytes = System.Text.Encoding.UTF8.GetBytes(message);

            HMACSHA256  hmacsha256 = new HMACSHA256(keyByte);
            byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
            return BitConverter.ToString(hashmessage).Replace("-", "").ToLower();
        }

字符串值'abcd'和空鹽值的結果: 527ff4c28c22a090fe39908139363e81b8fb10d0695a135518006abfa21cf5a2

請說明為什么兩個結果都不同。 我也在Java中嘗試了以下實現,但不適用於空鹽值:

public static String convertSHAWithSalt(String value, String salt)
            throws NoSuchAlgorithmException, InvalidKeyException {
        String data = "";
        Mac sha256Hmac = Mac.getInstance("HmacSHA256");
            SecretKeySpec secretkey = new SecretKeySpec(salt.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
            sha256Hmac.init(secretkey);
            data = bytesToHex(sha256Hmac.doFinal(data.getBytes(StandardCharsets.UTF_8)));
            System.out.println(data);
    }

SHA-256HMAC-SHA-256之間有區別 HMAC-SHA-256 (另請參見HMAC )是一種使用SHA-256 -hash算法生成MAC的算法。

第一個Java代碼和C#代碼的結果不同,因為Java代碼使用SHA-256和C#代碼HMAC-SHA-256

由於您要使用HMAC-SHA-256我將重點放在此方面,而忽略第一個Java代碼。

文本的C#代碼結果

This is an arbitrary text!

用鑰匙

1234567890

25583e6e0b6c2c3a5c50ebd9ea48138a960a7ca2a215fae2b4b82ee99734deb4

第二個Java代碼也使用HMAC-SHA-256 如果您更換線

data = bytesToHex(sha256Hmac.doFinal(data.getBytes(StandardCharsets.UTF_8)));
System.out.println(data);

data = bytesToHex(sha256Hmac.doFinal(value.getBytes(StandardCharsets.UTF_8)));
return data;

然后,輸出是相同的(前提是您的(未發布的) bytesToHex方法以正確的方式工作,請參見例如, 如何在Java中將字節數組轉換為十六進制字符串? )。

順便說一句,在第二個Java代碼中,您應該將標簽的salt更改為類似於key因為這是MAC上下文中的常用措辭。 通常與第一個Java代碼中的密碼哈希結合使用。

注意:在Java代碼中,不允許將空字節數組用作SecretKeySpec -input。 這將引發IllegalArgumentException (Empty key) 但是,C#代碼中的HMACSHA256 -ctor接受一個空字節數組,並在內部用0值填充。 因此,關於您的測試用例(文本: abcd ,空鍵),您可以用包含單個0值的字節數組在Java代碼中模擬空字節數組。 然后,Java代碼的輸出等於C#代碼的輸出。 當然,空鍵只能用於該測試用例。

暫無
暫無

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

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