Swift SHA256加密返回与Objective C相比不同的加密字符串 [英] Swift SHA256 encryption returns different encrypted string compare to Objective C
问题描述
我正在将一些代码从目标c迁移到迅捷。我想快速使用SHA 256算法使用密钥对字符串进行加密。但是,与Objective C实现相比,快速代码返回了不同的加密字符串。两种代码看起来相同,只是语法不同。有人可以帮助我迅速获得与过去获得目标C相同的结果吗?下面是两种语言的代码示例。
I am migrating some codes from objective c to swift. I want to encrypt a string with a key using SHA 256 algorithm in swift. But comparing to Objective C implementation swift code returns different encrypted string. Both codes looks same only the syntax is different. Can someone help me get the same result in swift as I used to get in Objective C? Below are the code samples from both languages.
目标C:
NSString* key = @"1234567890123456789012345678901234567890123456789012345678901234";
const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [@"message" cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
NSData *hash = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
NSString* encryptedString = hash.base64Encoding;
Swift:
let key = "1234567890123456789012345678901234567890123456789012345678901234"
let cKey = key.cString(using: .ascii)!
let cData = "message".cString(using: .ascii)!
var digest = [CUnsignedChar](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), cKey, cKey.count, cData, cData.count, &digest)
let hash = Data(digest)
let encryptedString = hash.base64EncodedString()
推荐答案
问题是 cKey
和 cData
包含以下字符的终止空字符:字符串,在 cKey.count
和 cData.count
中计算的Swift版本中,而在Objective中-C版本 strlen(cKey)
和 strlen(cData)
做不计算终止字符字符串的空字符。
The problem is that cKey
and cData
include the terminating null character of the strings, and in the Swift version that is counted in cKey.count
and cData.count
, whereas in the Objective-C version strlen(cKey)
and strlen(cData)
do not count the terminating null character of the strings.
正在执行
CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), cKey, strlen(key), cData, strlen("message", &digest)
反而可以解决您的示例中的问题,但是对于非ASCII字符而言并不安全。
instead would fix the issue in your example, but is not safe for non-ASCII characters.
实际的做法是将字符串转换为具有UTF-8表示形式的 Data
值(不包括终止的空字节)。然后将基础字节缓冲区传递给加密方法:
What I actually would do is to convert the strings to Data
values (which do not include a terminating null byte) with the UTF-8 representation. Then pass the underlying byte buffers to the encryption method:
let key = "1234567890123456789012345678901234567890123456789012345678901234"
let cKey = Data(key.utf8)
let cData = Data("message".utf8)
var digest = [CUnsignedChar](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
cKey.withUnsafeBytes { keyPtr in
cData.withUnsafeBytes { dataPtr in
CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), keyPtr.baseAddress, cKey.count, dataPtr.baseAddress, cData.count, &digest)
}
}
let hash = Data(digest)
let encryptedString = hash.base64EncodedString()
这会产生与目标C代码相同的结果 ZNjnsz2Uv5L0PvWIJjSh0BrOovuRXOSFWQ0s1Rd8VSM =
。
This produces the same result ZNjnsz2Uv5L0PvWIJjSh0BrOovuRXOSFWQ0s1Rd8VSM=
as your Objective-C code.
这篇关于Swift SHA256加密返回与Objective C相比不同的加密字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!