经典 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
方法一:在线使用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:使用亚马逊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
相关文章