我有一个 iOS 移动应用程序,它加密数据并将其存储在应用程序沙箱中的文件中。文件使用 CCCrypt() 加密如下:

    CCCryptorStatus aCryptStatus = CCCrypt(kCCEncrypt,
                                       kCCAlgorithmAES128,
                                       kCCOptionPKCS7Padding,
                                       aKeyPtr,
                                       kCCKeySizeAES256,
                                       aIVPtr,
                                       [self bytes],
                                       aDataLength,
                                       aBuffer,
                                       aBufferSize,
                                       &aNumBytesEncrypted);

key 长 256 位,IV 长 128 位。我不是加密专家,但这应该使用 CBC 模式(CCCrypt() 的默认模式),据我所知,此处指定的 PKCS#7 填充选项等效于 openssl 的 PKCS#5 填充。

数据写入文件如下:
     NSData* aSerializedData = [[self serialize]  dataUsingEncoding:NSUTF8StringEncoding];
     NSData* aEncryptedData = [aSerializedData AES256EncryptWithKey:ENCKey
                                               InitializationVector:ENCIv];
     NSFileManager* aFileManager = [[NSFileManager alloc] init];
     BOOL aFileWritten = [aFileManager createFileAtPath:aFilePath
                                               contents:aEncryptedData
                                             attributes:nil];

我尝试使用 openssl 解密文件,如下所示(key 和 iv 替换为 0):
$ openssl enc -aes-128-cbc -d -K 00000000000000000000000000000000 -iv 0000000000000000 -in encrypted.dat -out decrypted.txt


$ openssl enc -aes-256-cbc -d -K 00000000000000000000000000000000 -iv 0000000000000000 -in encrypted.dat -out decrypted.txt

两者都返回相同的错误:



我还尝试了其他模式和其他选项,例如 -nosalt 和 -a。没有人返回明文。

我花了几个小时试图找到一个如何在网上任何地方执行此操作的示例,但没有任何帮助我解决问题。帮助将不胜感激。

==========

答:CCCrypt 中的 key 是一个 32 字符的字符串,它被转换为 256 位。 openssl 期望的 key 是来自该字符串的二进制表示的 64 位十六进制数字。同样,CCCrypt 中的 iv 是一个 16 个字符的字符串,它被转换为 128 位。 openssl 期望的 iv 是该字符串的十六进制表示。一旦我使用了这两个的十六进制表示,它就很容易解密。

最佳答案

使用 -K 和 -iv 指定的 openssl key 和 iv 被指定为二进制数据的十六进制表示。
从 openssl 文档:



示例中的两个 openssl key 都是 128 位,对于 AES 256,它们需要是 256 位。 iv 必须是块大小,128 位,但在上面的例子中,iv 只有 64 位。

我测试过,这有效:

uint8_t *zeros     = calloc(1, 256);
NSData  *keyData   = [NSData dataWithBytes:zeros length:16];
NSData  *ivData    = [NSData dataWithBytes:zeros length:16];
NSData  *clearData = [@"0123456789abcdef" dataUsingEncoding:NSUTF8StringEncoding];

NSData *encryptedData = [AESTest doCipher:clearData iv:ivData key:keyData context:kCCEncrypt error:&error];
[encryptedData writeToFile:@"/Users/dan/Desktop/encrypted.dat" atomically:YES];

openssl enc -aes-128-cbc -d -K 00000000000000000000000000000000 -iv 00000000000000000000000000000000-in/Users/encrypt/Deskatcrypt/Deskatcrypt/Deskat

cat/Users/dan/Desktop/decrypted.txt
0123456789abcdef

对于 doCipher 方法,请参阅此 SO answer

关于ios - 如何使用openssl解密使用CCCrypt在Objective-C中创建的文件?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23664545/

10-13 04:29