与 Objective C 相比,Swift SHA256 加密返回不同的加密字符串

标签 swift macos cocoa encryption sha256

我正在将一些代码从 Objective C 迁移到 Swift。我想在 swift 中使用 SHA 256 算法用 key 加密字符串。但与 Objective C 实现的 swift 代码相比,返回不同的加密字符串。两个代码看起来相同,只是语法不同。有人可以帮助我在 swift 中得到与在 Objective C 中得到的结果相同的结果吗?以下是两种语言的代码示例。

objective-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()

最佳答案

问题是 cKeycData 包含字符串的终止空字符,并且在 Swift 版本中计入 cKey.countcData.count,而在 Objective-C 版本中 strlen(cKey)strlen(cData) 计算字符串的终止空字符。

正在做

 CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), cKey, strlen(key), cData, strlen("message", &digest)

相反,可以解决示例中的问题,但对于非 ASCII 字符不安全。

我实际上要做的是将字符串转换为具有 UTF-8 表示形式的 Data 值(不包括终止空字节)。然后将底层字节缓冲区传递给加密方法:

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()

这会产生与 Objective-C 代码相同的结果 ZNjnsz2Uv5L0PvWIJjSh0BrOovuRXOSFWQ0s1Rd8VSM=

关于与 Objective C 相比,Swift SHA256 加密返回不同的加密字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56288419/

相关文章:

java - 如何使用 Swift (iOS) 执行以下架构。添加了 Java 代码示例

ios - 滚动到表格底部时表格跳动

objective-c - 弹出式按钮单元使用 Cocoa Binding 返回 bool 值

php - 服务器上不同版本的 PHP 与 CLI

iphone - 'bezierPathWithOvalInRect' 错误的参数 1 的类型不兼容

xcode - 在上一个 View 上居中弹出窗口

ios - 如何将 SpriteKit 中的单个游戏场景添加到普通的 Single View Swift 应用程序中

objective-c - 以编程方式禁用 Mac 上的所有通知中心横幅

class - 快速更改类中变量的值

objective-c - Cocoa Bindings,我应该只使用 KVO 吗?