gpt4 book ai didi

iphone - iOS 上的 AES-256 加密不会产生与 openssl 相同的结果

转载 作者:行者123 更新时间:2023-12-03 19:55:31 24 4
gpt4 key购买 nike

我已经看了好几个小时了。我拼命尝试让 iOS 使用 AES-256 加密来加密一小段文本,然后可以通过 openssl 解密。

直接前进?不。

我找到的 iOS 代码与 openssl 的 key 和 IV 不兼容,因此我必须对其进行调整,但它显然不起作用。

所以这是我正在使用的加密代码...传递一个字符串来加密(dataString)字符串 key (key)和字符串初始化向量(iv)...

- (NSData *)AES256Encrypt:(NSString *)dataString WithKey:(NSString *)key iv:(NSString *)iv {

// 'key' should be 32 bytes for AES256, will be null-padded otherwise
//char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused)
//bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)

// fetch key data
//[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

//NSLog(@"keyPtr: '%s'", keyPtr);

NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"keyPtr: '%s'", keyData.bytes);
NSData *dataToEncrypt = [dataString dataUsingEncoding:NSUTF8StringEncoding];
NSData *ivData = [iv dataUsingEncoding:NSUTF8StringEncoding];

NSUInteger dataLength = [dataToEncrypt length];

//See the doc: For block ciphers, the output size will always be less than or
//equal to the input size plus the size of one block.
//That's why we need to add the size of one block here
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);

size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyData.bytes, kCCKeySizeAES256,
ivData.bytes, // initialisation vector
dataToEncrypt.bytes,
dataToEncrypt.length, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}

free(buffer); //free the buffer;
return nil;
}

对于要编码的相同字符串,这不会产生与使用具有相同 key 和 iv 的 openssl 时相同的值...例如这个命令行:

openssl enc -aes-256-cbc -e -in secrets.txt -a -iv 0000 -K 0000 -p

secrets.txt 只是一个包含要加密的字符串的文本文件

输出如下:

salt=3C66000000000000
key=0000000000000000000000000000000000000000000000000000000000000000
iv =00000000000000000000000000000000
qTMfgtAxbF8Yyh27ZDrcIQ==

要解密,请执行相反的操作(假设上面加密的最后一行数据位于 test.secrets.out 中)

openssl enc -aes-256-cbc -d -in test.secrets.out -a -iv 0000 -K 0000 -p 
salt=3C66000000000000
key=0000000000000000000000000000000000000000000000000000000000000000
iv =00000000000000000000000000000000
< text of the secrets.txt file >

现在,如果我使用 4 个字符的 key 和 iv,则在 iOS 中无法正确编码。如果我使用全长 key 和 iv,这也无法正确编码。

基本上,这是一项检查,以确定我是否发送一段加密数据,它是否是正确的数据。

我错过了什么?

我浏览了一些代码试图找到答案......

http://robnapier.net/blog/aes-commoncrypto-564

https://github.com/rnapier/RNCryptor

http://pastie.org/426530

在这里也进行了大量搜索,但找不到答案。

感谢任何帮助。

最佳答案

OpenSSL 有一种独特的(读作“不接近任何标准,也不是特别安全”)的方法来将密码转换为 IV 和 key 。如果你看RNOpenSSLCryptor ,您将看到使用的算法:

// For aes-128:
//
// key = MD5(password + salt)
// IV = MD5(Key + password + salt)

//
// For aes-256:
//
// Hash0 = ''
// Hash1 = MD5(Hash0 + Password + Salt)
// Hash2 = MD5(Hash1 + Password + Salt)
// Hash3 = MD5(Hash2 + Password + Salt)
// Hash4 = MD5(Hash3 + Password + Salt)
//
// Key = Hash1 + Hash2
// IV = Hash3 + Hash4
//

// File Format:
//
// |Salted___|<salt>|<ciphertext>|
//

使用RNOpenSSLCryptor允许RNCryptor支持OpenSSL格式。我目前正在 async 上重新编写此代码。分支来支持异步操作,并且该分支尚不支持 OpenSSL,但我确实计划很快(到 2012 年 7 月中旬)重新设计该分支。

如果您想要实现此功能的代码供您自己使用,请查看 keyForPassword:salt:IVForKey:password:salt:

请注意,OpenSSL 文件格式存在多个安全问题,如果您可以避免,我不建议您使用它。它没有使用非常好的 KDF 来生成 key ,没有应有的随机 IV,并且不提供 HMAC 进行身份验证。这些安全问题就是我设计different file format的原因,就像我讨厌创建“另一个不兼容的容器”一样。

关于iphone - iOS 上的 AES-256 加密不会产生与 openssl 相同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10900278/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com