【问题标题】:How to decrypt data with Openssl tool encrypted with AES128 in iOS如何在 iOS 中使用用 AES128 加密的 Openssl 工具解密数据
【发布时间】:2011-11-24 00:44:23
【问题描述】:

我有许多 sn-ps 代码,它们使用 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

它告诉我解密错误

请帮忙。

【问题讨论】:

    标签: objective-c ios openssl aes


    【解决方案1】:

    这里有几个问题。首先,您使用 CBC 模式(CCCrypt 的默认设置)进行加密,但使用 ECB 模式进行解密。很少有理由使用 ECB 模式。

    您使用字符串(我假设“0123456789123456”)作为密钥而不是密码进行加密。这些是不同的东西。我不确定openssl 如何将密码转换为密钥。我在enc(1) 页面上没有看到对此的解释。我假设它使用 PBKDF2,但不清楚(并且没有给出迭代次数)。您应该使用 -K 选项传递实际密钥。在这种情况下,您还需要显式传递 IV。您没有正确生成 IV 或盐。你应该是,然后你应该将它们传递给 openssl。

    要了解如何正确加密,请参阅Properly encrypting with AES with CommonCrypto。一旦你有正确加密的东西,你就应该有一个正确的密钥、一个盐和一个 IV。将所有这些交给enc,使用aes-128-cbc(假设是128位AES),它应该可以工作。

    编辑

    这里有一点很明显:如果在双方都使用相同的工具包,加密/解密会容易得多。要做你想做的事,你真的必须了解 CCCrypt() 和 OpenSSL 的具体细节,这就是我讨论它们的原因。即使您发现某些“似乎有效”的东西,安全性也很容易在您没有意识到的情况下变得非常差。 AES128EncryptWithKey: 就是一个例子;它看起来很好并且“有效”,但它有几个安全问题。如果可能的话,我会在两边都使用 OpenSSL,或者在两边都使用 CCCrypt。

    【讨论】:

    • OpenSSL enc 根据摘要使用 PKCS#5 1.5 或非标准密钥派生函数(-md arg,默认情况下为 MD5)。和 1 次迭代。 KDF 是 EVP_BytesToKey:openssl.org/docs/crypto/EVP_BytesToKey.html
    • @Rob 在提供的代码中我使用 kCCOptionECBMode。感谢我已经看到它的链接,但它返回了相同的错误
    • 您将密钥作为一系列十六进制数字传递给 -K,代表“0123456789123456”的 UTF8 编码(假设您的原始代码)?你相信你现在已经很好地理解了密钥和密码之间的区别了吗?你能用你现在实际测试的内容更新你的问题吗?
    • @indiv,谢谢。这是在任何地方记录的,还是只是通过阅读源代码?我的意思是:使用enc 的开发人员可以依赖它使用 EVP_BytesToKey 而不是 PKCS#5v2 吗?或者这只是当前的行为?
    • @Rob:我从源代码中得到的绝对是未记录的行为。如果他们改变它,我们将看到这是一场多么可怕的兼容性噩梦。
    猜你喜欢
    • 2011-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-25
    • 1970-01-01
    • 2014-04-01
    • 1970-01-01
    • 2019-04-13
    相关资源
    最近更新 更多