如何在iOS中使用Openssl工具解密使用AES128加密的数据
我有很多代码片段,它们使用 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
它告诉我坏解密
请帮忙。
I have many snippets of code, which encrypt the data with AES128 (If you provide your working implementation I will be very thankfull) For example this one:
- (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;
}
After it the data is base64 encoded, with online tool I save it to data.bin
The thing I want to do is to decrypt this data with OpenSSl.
But, when I call
openssl enc -aes-128-ecb -in data.bin -out out.bin -d -pass pass:0123456789123456
It tolds me bad magic number
In case I use
openssl enc -aes-128-ecb -in data.bin -out out.bin -d -pass pass:0123456789123456 -nosalt
It tolds me bad decrypt
Please help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这里有几个问题。首先,您使用 CBC 模式(这是 CCCrypt 的默认模式)进行加密,但使用 ECB 模式进行解密。很少有理由使用 ECB 模式。
您使用字符串(我假设为“0123456789123456”)作为密钥而不是密码进行加密。这些是不同的事情。我不确定 openssl 如何将密码转换为密钥。我在
enc(1)
页面上没有看到对此的解释。我假设它使用 PBKDF2,但不清楚(并且没有给出迭代次数)。您应该使用-K
选项传递实际密钥。在这种情况下,您还需要显式传递 IV。您没有正确生成静脉注射或盐。你应该是,然后你应该将它们传递给 openssl。要了解如何正确加密,请参阅通过 CommonCrypto 使用 AES 正确加密。一旦你有了正确加密的东西,你就应该有一个正确的密钥、一个盐和一个 IV。使用 aes-128-cbc(假设 128 位 AES)将所有这些交给 enc,它应该可以工作。
编辑
这里值得说明的是:如果双方使用相同的工具包,加密/解密会容易得多。为了完成您想要做的事情,您确实必须了解 CCCrypt() 和 OpenSSL 的具体细节,这就是我讨论它们的原因。即使您发现“似乎有效”的东西,安全性也很容易在您没有意识到的情况下变得非常差。
AES128EncryptWithKey:
就是一个例子;它看起来不错并且“有效”,但它有几个安全问题。如果可能的话,我要么在两侧使用 OpenSSL,要么在两侧使用 CCCrypt。There are several problems here. First, you're encrypting with CBC mode (which is the default for
CCCrypt
) but decrypting in ECB mode. There is very seldom reason to use ECB mode.You're encrypting with a string (I assume "0123456789123456") as the key, not the password. These are different things. I'm not certain how
openssl
translates a password into a key. I don't see an explanation of that on theenc(1)
page. I assume it uses PBKDF2, but it's not clear (and the number of iterations isn't given). You should be passing the actual key with the-K
option. In that case, you also need to pass the IV explicitly. You're not correctly generating an IV, or a salt. You should be, and you then should be passing them to openssl.To understand how to encrypt this correctly, see Properly encrypting with AES with CommonCrypto. Once you have something properly encrypted, you should then have a proper key, a salt, and an IV. Hand all of these to
enc
, usingaes-128-cbc
(assuming 128-bit AES), and it should work.EDIT
It's worth stating the obvious here: Encryption/decryption is much easier if you use the same toolkit on both sides. To do what you're trying to do, you really do have to understand the nuts and bolts of both CCCrypt() and OpenSSL, which is why I'm discussing them. Even if you find something that "seems to work," the security can easily be very poor without you realizing it.
AES128EncryptWithKey:
is an example of this; it looks fine and it "works," but it has several security problems. If possible, I'd either use OpenSSL on both sides, or CCCrypt on both sides.