我有很多代码片段,用AES128加密数据(如果你提供你的工作实现,我将非常感谢)例如这一个:
- (NSData*)AES128EncryptWithKey:(NSString*)key {
// 'key' should be 16 bytes for AES128, will be null-padded otherwise
char keyPtr[kCCKeySizeAES128 + 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];
NSUInteger dataLength = [self 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, kCCOptionECBMode + kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES128,
NULL /* initialization vector (optional) */,
[self bytes], dataLength, /* 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;
}
之后数据是base64编码的,使用在线工具我将其保存到 data.bin
我想要做的是用OpenSSl解密这些数据。 但是,当我打电话时
openssl enc -aes-128-ecb -in data.bin -out out.bin -d -pass pass:0123456789123456
它告诉我坏幻数
如果我使用
openssl enc -aes-128-ecb -in data.bin -out out.bin -d -pass pass:0123456789123456 -nosalt
它告诉我糟糕的解密
请帮忙。
答案 0 :(得分:5)
这里有几个问题。首先,您使用CBC模式加密(这是CCCrypt
的默认值),但在ECB模式下进行解密。很少有理由使用ECB模式。
您使用字符串(我假设为“0123456789123456”)加密密钥,而不是密码。这些是不同的东西。我不确定openssl
如何将密码转换为密钥。我在enc(1)
页面上没有看到相关说明。我假设它使用PBKDF2,但它不清楚(并且没有给出迭代次数)。您应该使用-K
选项传递实际密钥。在这种情况下,您还需要明确传递IV。你没有正确地产生静脉注射或盐。你应该是,然后你应该将它们传递给openssl。
要了解如何正确加密,请参阅Properly encrypting with AES with CommonCrypto。一旦你有正确加密的东西,你应该有一个正确的密钥,盐和IV。使用enc
(假设128位AES)将所有这些内容传递给aes-128-cbc
,它应该可以正常工作。
修改强>
值得注意的是:如果您在双方使用相同的工具包,加密/解密会更容易。为了做你想做的事,你真的必须要理解CCCrypt()和OpenSSL的细节,这就是我讨论它们的原因。即使你发现某些“似乎有效”的东西,如果你没有意识到,安全性很容易变得非常糟糕。 AES128EncryptWithKey:
就是一个例子;它看起来很好并且“有效”,但它有几个安全问题。如果可能的话,我要么双方使用OpenSSL,要么双方使用CCCrypt。