经典ASP中的各种HMAC_SHA256函数给出不同的结果 [英] Various HMAC_SHA256 functions in classic ASP gives different results
问题描述
我需要以某种方式在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屋!