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

发布于 2024-12-06 01:07:27 字数 2038 浏览 1 评论 0原文

我有很多代码片段,它们使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

长途伴 2024-12-13 01:07:27

这里有几个问题。首先,您使用 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 the enc(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, using aes-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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文