我如何将这个加密函数从Swift转换到Objective-C?



我正在为iOS Objective-C应用程序编写辅助函数它应该使用AES-128算法用所提供的密钥加密字符串

我已经在Swift中实现了这个函数。,但我正在努力翻译Objective-C。该函数不考虑任何初始化向量,它被硬编码为空字符串:这是有意的。

Swift按预期工作的代码:

@objc func AES128(_ string: String, withKey: String) -> String {
let data = string.data(using: String.Encoding.utf8)!
let keyData = withKey.data(using: String.Encoding.utf8)!
let ivData = "".data(using: String.Encoding.utf8)!

let cryptLength = size_t(data.count + kCCBlockSizeAES128)
var cryptData = Data(count: cryptLength)
let keyLength = size_t(kCCKeySizeAES128)
let options = CCOptions(kCCOptionPKCS7Padding)
var numBytesEncrypted: size_t = 0
let cryptStatus = cryptData.withUnsafeMutableBytes { cryptBytes in
data.withUnsafeBytes { dataBytes in
ivData.withUnsafeBytes { ivBytes in
keyData.withUnsafeBytes { keyBytes in
CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmAES), options, keyBytes, keyLength, ivBytes, dataBytes, data.count, cryptBytes, cryptLength, &numBytesEncrypted)
}
}
}
}
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)
}
return cryptData.base64EncodedString();
}

这个函数就像一个魔符,用密钥ABCDEFGHIJKLMNOP加密字符串Hello World得到一个base64编码的字符串3G4OU62dM9zXhkbXy8pmuA==

我把它翻译成Objective-C:

+(NSString *)AES128:(NSString *)string withKey:(NSString *)key {
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
NSData *ivData = [@"" dataUsingEncoding:NSUTF8StringEncoding];

size_t cryptLength  = data.length + kCCBlockSizeAES128;
NSMutableData *cryptData = [NSMutableData dataWithLength:cryptLength];
size_t keyLength = kCCKeySizeAES128;
CCOptions options = kCCOptionPKCS7Padding;
size_t numBytesEncrypted = 0;

CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES, options, keyData.bytes, keyLength, ivData.bytes, data.bytes, data.length, cryptData.mutableBytes, cryptLength, &numBytesEncrypted);

if (cryptStatus == kCCSuccess) {
[cryptData replaceBytesInRange:NSMakeRange(numBytesEncrypted, cryptData.length - numBytesEncrypted) withBytes:NULL length:0];
}
return [cryptData base64EncodedStringWithOptions:0];
}

问题是Objective-C版本提供了错误的结果,我会说随机结果,为Hello World+ABCDEFGHIJKLMNOP的相同组合产生不同的加密值。7m+HH5NusyA1VAfZ78KYCw==NY5p8XtYLoAE/4VbCCrPIg==是其中一些错误的值。如果您解密这些字符串,您将分别得到Hello WoldHello Worod

我在翻译时做错了什么?

谢谢你的帮助!

这似乎是您处理初始化向量的问题。如果您注意到,CCCrypt函数接受指向IV的字节缓冲区内容的指针,但是您没有提供长度参数。这意味着缓冲区的长度是已知的。

根据维基百科(https://en.wikipedia.org/wiki/Initialization_vector), IV的长度"通常是密码的块大小"。

基本上,当你做

NSData *ivData = [@"" dataUsingEncoding:NSUTF8StringEncoding];

ivData。Bytes属性现在将指向某个地方,在最好的情况下,它的完整长度将为0x00,但很可能不是。CCCrypt()函数将从您正在传递的内存地址(指向空数组的指针)开始,并继续读取下一个[IV Length]字节,使用它在那里找到的任何随机数据。

要解决这个问题,你需要以某种方式确保,你正在传递一个指针,指向一个包含所有0的预期内容的缓冲区。

我用

简单地做了这个
void* ivBuffer = calloc(1, kCCBlockSizeAES128);

,它分配一个128位(16字节)的单个块,并将其初始化为全0。

你对CCCrypt()的调用变成

CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES, options, keyData.bytes, keyLength, ivBuffer, data.bytes, data.length, cryptData.mutableBytes, cryptLength, &numBytesEncrypted);

,你只需要记住调用free(ivBuffer)来释放分配给这个缓冲区的内存。

同样,当你处理成功状态时,你可以只执行

if (cryptStatus == kCCSuccess)
{
cryptData.length = numBytesEncrypted;
}

,它将截断数据,只保留您想要使用的部分。这取决于你,因为结果和你已经拥有的是一样的。

相关内容

  • 没有找到相关文章

最新更新