经典ASP中的各种HMAC_SHA256函数给出不同的结果 [英] Various HMAC_SHA256 functions in classic ASP gives different results

查看:155
本文介绍了经典ASP中的各种HMAC_SHA256函数给出不同的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要以某种方式在Classic ASP中生成一个哈希,该哈希等效于PHP的以下函数的输出:

Somehow I need to generate a hash in Classic ASP which is equivalent to PHP's following function's output:

$hash = hash_hmac('SHA256', $message, pack('H*', $secret));

其中$message = 'stackoverflow'; $secret = '1234567890ABCDEF';.我在网上尝试了很多方法,但是没有一种方法与PHP结果相符:

where $message = 'stackoverflow'; $secret = '1234567890ABCDEF';. I tried quite a lot approaches online, but none matches the PHP result:

bcb3452cd48c0f9048e64258ca24d0f3399563971d4a5dcdc531a7806b059e36

方法1:在线使用dvim_brix_crypto-js-master_VB.asp(使用CrytoJS)

Function mac256(ent, key) 
    Dim encWA
    Set encWA = ConvertUtf8StrToWordArray(ent)
    Dim keyWA
    Set keyWA = ConvertUtf8StrToWordArray(key)
    Dim resWA
    Set resWA = CryptoJS.HmacSHA256(encWA, key)
    Set mac256 = resWA
End Function

Function ConvertUtf8StrToWordArray(data)
    If (typename(data) = "String") Then
        Set ConvertUtf8StrToWordArray = CryptoJS.enc.Utf8.parse(data)
    Elseif (typename(data) = "JScriptTypeInfo") Then
        On error resume next
        'Set ConvertUtf8StrToWordArray = CryptoJS.enc.Utf8.parse(data.toString(CryptoJS.enc.Utf8)) 
        Set ConvertUtf8StrToWordArray = CryptoJS.lib.WordArray.create().concat(data) 'Just assert that data is WordArray
        If Err.number>0 Then
            Set ConvertUtf8StrToWordArray = Nothing
        End if
        On error goto 0
    Else
        Set ConvertUtf8StrToWordArray = Nothing
    End if
End Function

可以在此处找到该脚本.此方法给出:

The script can be found here. This method gives:

c8375cf0c0db721ecc9c9b3a034284117d778ee8594285196c41d5020917f78c


方法2:纯经典的ASP方法

Public Function HMAC_SHA256(prmKey, prmData)
    Dim theKey : theKey = prmKey
    Dim Block_Size, O_Pad, I_Pad
    Block_Size = 64
    O_Pad = 92 'HEX: 5c'
    I_Pad = 54 'HEX: 36'

    Dim iter, iter2
    If Len(theKey) < Block_Size Then
        For iter = 1 to Block_Size - Len(theKey)
            theKey = theKey & chr(0)
        Next
    ElseIf Len(theKey) > Block_Size Then
        theKey = SHA256(theKey)
    End If

    Dim o_key_pad : o_key_pad = ""
    Dim i_key_pad : i_key_pad = ""
    For iter = 1 to Block_Size
        o_key_pad = o_key_pad & Chr(Asc(Mid(theKey,iter,1)) xor O_Pad)
        i_key_pad = i_key_pad & Chr(Asc(Mid(theKey,iter,1)) xor I_Pad)
    Next

    HMAC_SHA256 = SHA256(o_key_pad & SHA256(i_key_pad & prmData))
End Function
result = HMAC_SHA256(secret, message)

此方法给出:

bc0511316791176484c7d80bc8faaecd8388b75fb97516181ba6b361fd032531


方法3:使用Amazon AWS的sha256.wsc(使用CrytoJS)

Dim sha
Set sha = GetObject( "script:" & Server.MapPath("sha256.wsc") )
sha.hexcase = 0
result = sha.b64_hmac_sha256(secret, message)

可以找到该WSC 这里.此方法给出的结果(与方法1相同):

The WSC can be found here. This method gives (same result as Method 1):

c8375cf0c0db721ecc9c9b3a034284117d778ee8594285196c41d5020917f78c


我认为问题出在pack()部分,该部分将十六进制字符串更改为二进制.因此,我找到了一种在ASP中重现pack()函数的方法:


I think the problem is the pack() part, which changes the Hex string to binary. Therefore, I found a way to reproduce the pack() function in ASP:

Dim key2, hexarr, binstr
key2 = "12 34 56 78 90 AB CD EF"
hexarr = Split(key2)
ReDim binarr(UBound(hexarr))

For i = 0 To UBound(hexarr)
  binarr(i) = Chr(CInt("&h" & hexarr(i)))
Next

binstr = Join(binarr, "")

,其中key2是原始机密,每2个字符中添加一个空格.通过将secret替换为binstr,这些方法现在会产生:

where the key2 is the original secret with space added in every 2 characters. By replacing the secret with binstr, the methods now produce:

Method 1: 8ab9e595eab259acb10aa18df7fdf0ecc5ec593f97572d3a4e09f05fdd3aeb8f
Method 2: d23fcafb41d7b581fdae8c2a4a65bc3b19276a4bd367eda9e8e3de43b6a4d355
Method 3: 8ab9e595eab259acb10aa18df7fdf0ecc5ec593f97572d3a4e09f05fdd3aeb8f

以上结果均与PHP相同.我现在想念什么?

None of the above results is identical to PHP's one. What did I miss now?

推荐答案

查看以下示例.

此方法的唯一要求是Microsoft .Net Framework 2.0(从Windows Server 2003 R2开始预安装)以使用Com Interops.

The only requirement with this approach is Microsoft .Net Framework 2.0 (preinstalled starting from Windows Server 2003 R2) to use Com Interops.

我试图在评论中进行描述,但随时可以提出疑问.

I tried to be descriptive in the comments but feel free to ask questions about it.

'Returns Byte(), UTF-8 bytes of unicode string
Function Utf8Bytes(text)
    With Server.CreateObject("System.Text.UTF8Encoding")
        Utf8Bytes = .GetBytes_4(text)
    End With
End Function

'Returns String, sequential hexadecimal digits per byte
'data As Byte()
Function BinToHex(data)
    With Server.CreateObject("MSXML2.DomDocument").CreateElement("b64")
        .dataType = "bin.hex"
        .nodeTypedValue = data
        BinToHex = .text
    End With
End Function

'Returns Byte(), a keyed hash generated using SHA256 method
'data As String, key As Byte()
Function HashHmacSha256(data, key)
    With Server.CreateObject("System.Security.Cryptography.HMACSHA256")
        .Key = key
        HashHmacSha256 = .ComputeHash_2(UTF8Bytes(data))
    End With
End Function

'Returns Byte(), of a packed hexadecimal string
'instead of PHP's pack('H*'
Function HexToBin(data)
    With Server.CreateObject("MSXML2.DomDocument").CreateElement("b64")
        .dataType = "bin.hex"
        .text = data
        HexToBin = .nodeTypedValue
    End With
End Function

packed_secret = HexToBin("1234567890ABCDEF")
message = "stackoverflow"
binary_hash = HashHmacSha256(message, packed_secret)
string_hash = BinToHex(binary_hash)

Response.Write string_hash

这篇关于经典ASP中的各种HMAC_SHA256函数给出不同的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆