C#中的HMAC SHA256与Swift中的HMAC SHA256不匹配 [英] HMAC SHA256 in C# vs HMAC SHA256 in Swift don't match
问题描述
在dotnetcore C#中使用标准" HMACSHA256技术,我可以生成散列字符串,如下所示:
Using the 'standard' HMACSHA256 technique in dotnetcore C# I can produce a hashed string as follows:
private static void Test()
{
var hmac = new HMACSHA256(Encoding.UTF8.GetBytes("testingkey"));
var theHash = hmac.ComputeHash(Encoding.UTF8.GetBytes("testingstringtohash"));
string signature = Convert.ToBase64String(theHash);
Console.WriteLine(signature);
}
//Produces yg/9NCAm5IIwGKJK80PyUeBWkzEUwZswvC3OVnTnT80=
迅速地做到这一点(此答案似乎是人们使用的标准")
To do the same in swift (solution from this answer seems to be the 'standard' that people are using)
func HashTest() {
let hash = "testingstringtohash".hmac(algorithm: .SHA256, key: "testingkey")
//hash ca0ffd342026e4823018a24af343f251e056933114c19b30bc2dce5674e74fcd
let hexData = hash.data(using: String.Encoding.utf8)
let signature = hexData?.base64EncodedString()
print(signature!)
}
//Produces Y2EwZmZkMzQyMDI2ZTQ4MjMwMThhMjRhZjM0M2YyNTFlMDU2OTMzMTE0YzE5YjMwYmMyZGNlNTY3NGU3NGZjZA==
我在这里很愚蠢吗?或者这两个值应该是相同的,因为它是相同的加密算法,并且相同的密钥代表相同的值.据我所知,C#示例产生了正确"的结果,因为使用该示例产生的值的Web服务可以正常工作,但是swift版本产生的值却失败了.
Am I being stupid here... or should these two values be the same, as it is the same encryption algorithm, and the same key for the same value. As far as I can tell the C# example produces the 'correct' result, as a webservice that is consuming a value produced with that example works fine, but the value that the swift version produces is failing.
推荐答案
这里的问题似乎是给定的swift解决方案和C#解决方案之间的base64字符串不同.
The issue here seems to be a difference in the base64 strings between the given swift solution and then C# solution.
哈希算法的输出在字节级别上是相同的,但是在返回之前已通过各种字符串转换对其进行了处理.
The output of the hash algorithm was the same at a byte level but it was being manipulated through various string conversions before being returned.
功能
private func stringFromResult(result: UnsafeMutablePointer<CUnsignedChar>, length: Int) -> String {
let hash = NSMutableString()
for i in 0..<length {
hash.appendFormat("%02x", result[i])
}
return String(hash).lowercased()
}
该解决方案的一部分将原始哈希数据转换为字符串,然后将其转换回调用类中的数据对象,然后将其转换为base64字符串以返回.当我们得到返回的字符串的base64字符串而不是原始字节时,我认为这就是问题所在.
Which is part of the solution converts the raw hashed data to a string, which is then converted back to a data object in the calling class, which is then cast into a base64 string to be returned. As we are getting a base64 string of of the string that was returned and not the raw bytes, I think this is where the issue was.
通过将hmac代码从解决方案更改为此,我们可以将has的原始输出转换为base64字符串,并避免其他步骤.这与C#值匹配.
By changing the hmac code from the solution to this, we can cast the raw output of the has to a base64 string and avoid the other steps. This matches the C# value.
func hmac(algorithm: CryptoAlgorithm, key: String) -> String {
let str = self.cString(using: String.Encoding.utf8)
let strLen = Int(self.lengthOfBytes(using: String.Encoding.utf8))
let digestLen = algorithm.digestLength
let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
let keyStr = key.cString(using: String.Encoding.utf8)
let keyLen = Int(key.lengthOfBytes(using: String.Encoding.utf8))
CCHmac(algorithm.HMACAlgorithm, keyStr!, keyLen, str!, strLen, result)
let a = UnsafeMutableBufferPointer(start: result, count: digestLen)
let b = Data(a)
result.deallocate()
let digest = b.base64EncodedString()
return digest
}
这篇关于C#中的HMAC SHA256与Swift中的HMAC SHA256不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!