如何使用iOS中使用AES128加密的Openssl工具解密数据

时间:2011-09-23 22:34:47

标签: objective-c ios openssl aes

我有很多代码片段,用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

它告诉我糟糕的解密

请帮忙。

1 个答案:

答案 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。