ColdFusion hmac() returns 使用 toBase64 和 binaryEncode 的不同值
ColdFusion hmac() returns different values with toBase64 and binaryEncode
我正在尝试使用 ColdFusion 的 hmac() function to calculate an HMAC value using binaryEncode(binaryObj,'Base64')
instead of toBase64(),因为该功能已被弃用。它与 toBase64()
完美兼容,但与 binaryEncode()
不兼容。文档不是很有用。有人可以帮助我理解为什么我不能使用 binaryEncode
获得相同的值吗?
据我了解,hmac()
函数 returns 的结果为十六进制格式。 binaryEncode()
需要二进制值,因此 hmac()
结果必须先从十六进制转换为二进制,然后才能转换为 base64。
<cfset string = "1234567890" />
<cfset secretKey = "abcdefghijklmnopqrstuvwxyz" />
<!--- Get Hex results from HMAC() --->
<cfset hmacHex = hmac(string,secretKey,'HMACSHA256') />
<!--- Decode the binary value from hex --->
<cfset hmacAsBinary = binaryDecode(hmacHex,'hex') />
<!--- Convert binary object to Base64 --->
<cfset hmacBase64 = binaryEncode(hmacAsBinary, 'base64') />
<cfoutput>
<!--- incorrect hmac signature --->
hmacBase64: #hmacBase64#<br>
<!--- correct hmac signature --->
toBase64: #toBase64(hmac(string,secretKey,'HMACSHA256'))#<br>
</cfoutput>
结果是:
hmacBase64: VEVGNnqg9b0eURaDCsA4yIOz5c+QtoJqIPInEZOuRm4=
toBase64: NTQ0NTQ2MzY3QUEwRjVCRDFFNTExNjgzMEFDMDM4Qzg4M0IzRTVDRjkwQjY4MjZBMjBGMjI3MTE5M0FFNDY2RQ==
我注意到的一件事是使用 toBase64()
时结果要长得多。我似乎无法弄清楚为什么我不能使用 binaryEncode()
。但是,我想这样做,因为 toBase64()
已被弃用。非常感谢任何见解。谢谢!
根据评论更新:
好吧,使用 ToBase64(Hmac(...))
不是 将十六进制字符串转换为 base64 的正确方法 ;-) 但是,听起来 API 需要一些东西除了直接转换。如果是这样,只需执行 ToBase64(hmac(...))
代码正在执行的操作即可。 ie 将十六进制字符串解码为 UTF8 并将其重新编码为 base64:
matchingResult = binaryEncode(charsetDecode(hmacHex, "utf-8"), "base64")
简答:
这两种方法编码的值完全不同。这就是结果不匹配的原因。将十六进制字符串转换为 base64 的正确方法是使用 BinaryEncode/Decode().
更长的答案:
<!--- correct hmac signature --->
toBase64: #toBase64(hmac(string,secretKey,'HMACSHA256'))#<br>
实际上,不是将十六进制转换为 base64 的正确方法。
十六进制和 Base64 只是表示 二进制 值的不同方式。为了获得相同的结果,这两种方法需要从相同的二进制文件开始。在这种情况下,实际上编码的是完全不同的值。因此结果不同。
对于十六进制字符串,每个字节由两个字符表示。所以 binary 将是原始字符串大小的 half。对于 HMAC(HMACSHA256),生成的十六进制字符串的长度为 64 个字符。所以 binary 值应该是 32 字节。要获得正确的二进制值,必须将字符串 解码为十六进制 :
original string length = #len(hmacHex)#
binary size = #arrayLen(binaryDecode(hmacHex, "hex"))#
ToBase64 的问题在于它对字符串的解码不正确。它将输入视为 UTF8 并解码字符串中的字符 单独 。所以二进制值是它应该的大小的两倍。注意到它是 64 字节,而不是 32 字节吗?这就是为什么最后的字符串也更长。
UTF8 binary size = #arrayLen(charsetDecode(hmacHex, "utf-8"))#
ToBase64 binary size = #arrayLen(binaryDecode(toBase64(hmacHex), "base64"))#
同样,这两种方法产生不同的结果,因为它们编码的值完全不同。但是,严格来说,只有第一种方法是正确的。要将十六进制字符串重新编码为 base64,请使用 binaryEncode/binaryDecode:
correctResult = binaryEncode(binaryDecode(hmacHex, "hex"), "base64")
我正在尝试使用 ColdFusion 的 hmac() function to calculate an HMAC value using binaryEncode(binaryObj,'Base64')
instead of toBase64(),因为该功能已被弃用。它与 toBase64()
完美兼容,但与 binaryEncode()
不兼容。文档不是很有用。有人可以帮助我理解为什么我不能使用 binaryEncode
获得相同的值吗?
据我了解,hmac()
函数 returns 的结果为十六进制格式。 binaryEncode()
需要二进制值,因此 hmac()
结果必须先从十六进制转换为二进制,然后才能转换为 base64。
<cfset string = "1234567890" />
<cfset secretKey = "abcdefghijklmnopqrstuvwxyz" />
<!--- Get Hex results from HMAC() --->
<cfset hmacHex = hmac(string,secretKey,'HMACSHA256') />
<!--- Decode the binary value from hex --->
<cfset hmacAsBinary = binaryDecode(hmacHex,'hex') />
<!--- Convert binary object to Base64 --->
<cfset hmacBase64 = binaryEncode(hmacAsBinary, 'base64') />
<cfoutput>
<!--- incorrect hmac signature --->
hmacBase64: #hmacBase64#<br>
<!--- correct hmac signature --->
toBase64: #toBase64(hmac(string,secretKey,'HMACSHA256'))#<br>
</cfoutput>
结果是:
hmacBase64: VEVGNnqg9b0eURaDCsA4yIOz5c+QtoJqIPInEZOuRm4=
toBase64: NTQ0NTQ2MzY3QUEwRjVCRDFFNTExNjgzMEFDMDM4Qzg4M0IzRTVDRjkwQjY4MjZBMjBGMjI3MTE5M0FFNDY2RQ==
我注意到的一件事是使用 toBase64()
时结果要长得多。我似乎无法弄清楚为什么我不能使用 binaryEncode()
。但是,我想这样做,因为 toBase64()
已被弃用。非常感谢任何见解。谢谢!
根据评论更新:
好吧,使用 ToBase64(Hmac(...))
不是 将十六进制字符串转换为 base64 的正确方法 ;-) 但是,听起来 API 需要一些东西除了直接转换。如果是这样,只需执行 ToBase64(hmac(...))
代码正在执行的操作即可。 ie 将十六进制字符串解码为 UTF8 并将其重新编码为 base64:
matchingResult = binaryEncode(charsetDecode(hmacHex, "utf-8"), "base64")
简答:
这两种方法编码的值完全不同。这就是结果不匹配的原因。将十六进制字符串转换为 base64 的正确方法是使用 BinaryEncode/Decode().
更长的答案:
<!--- correct hmac signature --->
toBase64: #toBase64(hmac(string,secretKey,'HMACSHA256'))#<br>
实际上,不是将十六进制转换为 base64 的正确方法。
十六进制和 Base64 只是表示 二进制 值的不同方式。为了获得相同的结果,这两种方法需要从相同的二进制文件开始。在这种情况下,实际上编码的是完全不同的值。因此结果不同。
对于十六进制字符串,每个字节由两个字符表示。所以 binary 将是原始字符串大小的 half。对于 HMAC(HMACSHA256),生成的十六进制字符串的长度为 64 个字符。所以 binary 值应该是 32 字节。要获得正确的二进制值,必须将字符串 解码为十六进制 :
original string length = #len(hmacHex)#
binary size = #arrayLen(binaryDecode(hmacHex, "hex"))#
ToBase64 的问题在于它对字符串的解码不正确。它将输入视为 UTF8 并解码字符串中的字符 单独 。所以二进制值是它应该的大小的两倍。注意到它是 64 字节,而不是 32 字节吗?这就是为什么最后的字符串也更长。
UTF8 binary size = #arrayLen(charsetDecode(hmacHex, "utf-8"))#
ToBase64 binary size = #arrayLen(binaryDecode(toBase64(hmacHex), "base64"))#
同样,这两种方法产生不同的结果,因为它们编码的值完全不同。但是,严格来说,只有第一种方法是正确的。要将十六进制字符串重新编码为 base64,请使用 binaryEncode/binaryDecode:
correctResult = binaryEncode(binaryDecode(hmacHex, "hex"), "base64")