如何将该加密功能从Swift转换为Objective-C?

安德里亚·科西尼(Andrea Corsini)

我正在为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();
}

此函数的工作原理类似于超级按钮,并使用密钥对字符串Hello World进行加密,ABCDEFGHIJKLMNOP结果是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 Wold,则Hello Worod分别得到

翻译时我做错了什么?

谢谢你的热心帮助!

奔威

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

根据Wikipedia(https://en.wikipedia.org/wiki/Initialization_vector)的规定,IV的长度通常是“密码的块大小”。

所以基本上,当你做的时候

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

ivData.bytes属性现在将指向某个位置,在最佳情况下,该位置的全长为0x00,但很可能没有。CCCrypt()函数将从您正在传递的内存地址(指向空数组的指针)开始,并继续使用其在其中找到的任何随机数据读取下一个[IV Length]字节。

要解决此问题,您需要确保以某种方式将指针传递给包含期望的全零内容的缓冲区。

我只是这样做

void* ivBuffer = calloc(1, kCCBlockSizeAES128);

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

您对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;
}

它将数据截断为您要使用的部分。取决于您,因为结果与您已有的结果相同。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何将Objective-C App委托转换为Swift?

Objective-C如何将NSURL转换为NSString?

如何将整个文件夹或程序包从Java转换为Objective-C?

如何将此Swift语法转换为Objective C?

如何将C ++排序函数转换为Swift?

如何将此加密功能从PHP转换为Javascript

将Mosquitto主题匹配功能从C转换为C#

如何将Objective-C`sortedArrayUsingSelector:NSSelectorFromString`转换为swift?

如何将Objective-C工厂方法转换为Swift便捷初始化程序?

如何将iOS Objective-C类别接口代码转换为RubyMotion?

从Objective-C转换为Swift(TestFlight)

如何将目标c中的NSDictionary转换为Swift?

我如何将其从Objective-C转换为Swift

使用扩展和追加功能将Swift方法转换为Objective-C

从Objective-C转换为Swift

Objective-C如何将击键转换为ASCII字符代码?

如何将此NSTimeInterval行从Swift转换为Objective-C

如何将此Swift语法转换为Objective-C?

如何将Swift类转换为UnsafePointer,例如Objective-C中的__bridge

如何将Objective-C块转换为Swift闭包?

如何将Swift代码转换为目标C代码

如何将使用GKAchievement的简单方法从Objective-C转换为C#?

如何将Objective-C代码转换为Swift代码-错误处理,iOS

将此功能从VB转换为C#

将代码从 Swift 转换为 Objective C?

如何将 HEXString (NSString) 转换为 ByteArray Objective-C

将 Swift 转换为 Objective C

如何将VB6加密代码转换为c#.net代码

如何将node js代码转换为c#加密