Swift SHA256加密返回与Objective C相比不同的加密字符串 [英] Swift SHA256 encryption returns different encrypted string compare to Objective C

查看:391
本文介绍了Swift SHA256加密返回与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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆