经典 ASP 中的各种 HMAC_SHA256 函数给出了不同的结果
Various HMAC_SHA256 functions in classic ASP gives different results
我需要以某种方式在 Classic ASP 中生成一个散列,它等同于 PHP 的以下函数的输出:
$hash = hash_hmac('SHA256', $message, pack('H*', $secret));
其中 $message = 'Whosebug'; $secret = '1234567890ABCDEF';
。我在网上尝试了很多方法,但 none 匹配 PHP 结果:
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
可以找到脚本here。此方法给出:
c8375cf0c0db721ecc9c9b3a034284117d778ee8594285196c41d5020917f78c
方法二:纯经典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
方法三:使用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 here。此方法给出(与方法 1 相同的结果):
c8375cf0c0db721ecc9c9b3a034284117d778ee8594285196c41d5020917f78c
我认为问题出在 pack()
部分,它将十六进制字符串更改为二进制。因此,我找到了一种在 ASP:
中重现 pack()
函数的方法
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 个字符添加 space。通过将 secret
替换为 binstr
,这些方法现在生成:
Method 1: 8ab9e595eab259acb10aa18df7fdf0ecc5ec593f97572d3a4e09f05fdd3aeb8f
Method 2: d23fcafb41d7b581fdae8c2a4a65bc3b19276a4bd367eda9e8e3de43b6a4d355
Method 3: 8ab9e595eab259acb10aa18df7fdf0ecc5ec593f97572d3a4e09f05fdd3aeb8f
None 以上结果与 PHP 相同。我现在错过了什么?
查看以下示例。
此方法的唯一要求是 Microsoft .Net Framework 2.0(从 Windows Server 2003 R2 开始预装)以使用 Com Interops。
我试图在评论中进行描述,但请随时提出问题。
'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 = "Whosebug"
binary_hash = HashHmacSha256(message, packed_secret)
string_hash = BinToHex(binary_hash)
Response.Write string_hash
我需要以某种方式在 Classic ASP 中生成一个散列,它等同于 PHP 的以下函数的输出:
$hash = hash_hmac('SHA256', $message, pack('H*', $secret));
其中 $message = 'Whosebug'; $secret = '1234567890ABCDEF';
。我在网上尝试了很多方法,但 none 匹配 PHP 结果:
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
可以找到脚本here。此方法给出:
c8375cf0c0db721ecc9c9b3a034284117d778ee8594285196c41d5020917f78c
方法二:纯经典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
方法三:使用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 here。此方法给出(与方法 1 相同的结果):
c8375cf0c0db721ecc9c9b3a034284117d778ee8594285196c41d5020917f78c
我认为问题出在 pack()
部分,它将十六进制字符串更改为二进制。因此,我找到了一种在 ASP:
pack()
函数的方法
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 个字符添加 space。通过将 secret
替换为 binstr
,这些方法现在生成:
Method 1: 8ab9e595eab259acb10aa18df7fdf0ecc5ec593f97572d3a4e09f05fdd3aeb8f
Method 2: d23fcafb41d7b581fdae8c2a4a65bc3b19276a4bd367eda9e8e3de43b6a4d355
Method 3: 8ab9e595eab259acb10aa18df7fdf0ecc5ec593f97572d3a4e09f05fdd3aeb8f
None 以上结果与 PHP 相同。我现在错过了什么?
查看以下示例。
此方法的唯一要求是 Microsoft .Net Framework 2.0(从 Windows Server 2003 R2 开始预装)以使用 Com Interops。
我试图在评论中进行描述,但请随时提出问题。
'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 = "Whosebug"
binary_hash = HashHmacSha256(message, packed_secret)
string_hash = BinToHex(binary_hash)
Response.Write string_hash