c++ - 如何正确使用 mbedtls 的 aes cbc api

标签 c++ aes mbedtls

根据 golang 的 aes 实现检查,我当前的方法甚至无法生成正确的加密数据。它也不会解密回原始明文,但如果加密步骤无法正常工作,这是预期的。我最好的猜测是我以某种方式滥用了 api。这是一个独立的示例,可以按原样运行。

#include <mbedtls/aes.h>

#include <vector>

void LogVec(const std::vector<uint8_t>& bin)
{
    printf("(size: %i) ", bin.size());
    printf("{");
    for (auto& b : bin)
    {
        printf("%#02x, ", b);
    }
    printf("}\n");
}

mbedtls_aes_context AesContext;

std::vector<uint8_t> EncryptAes(std::vector<uint8_t>& iv, std::vector<uint8_t>& data)
{
    std::vector<uint8_t> ivCpy(iv);

    uint8_t padByte = 16 - (data.size() % 16);
    for (int i = 0; i < padByte; i++)
        data.push_back(padByte);

    std::vector<uint8_t> ret(data.size());
    mbedtls_aes_crypt_cbc(&AesContext, MBEDTLS_AES_ENCRYPT, data.size(), ivCpy.data(), data.data(), ret.data());

    return ret;
}

std::vector<uint8_t> DecryptAes(const std::vector<uint8_t>& iv, std::vector<uint8_t>& data)
{
    std::vector<uint8_t> ivCpy(iv);

    std::vector<uint8_t> ret(data.size());
    mbedtls_aes_crypt_cbc(&AesContext, MBEDTLS_AES_DECRYPT, data.size(), ivCpy.data(), data.data(), ret.data());

    ret.resize(ret.size() - ret[ret.size() - 1]);
    
    return ret;
}

int main() 
{
    mbedtls_aes_init(&AesContext);

    std::vector<uint8_t> data = { 0x3b, 0xb1, 0x99, 0x3, 0x67, 0xf3, 0x2e, 0x1f, 0x00, 0x67, 0x38, 0xc9, 0x53, 0x92, 0xa4 };

    std::vector<uint8_t> key = { 0x15, 0x1, 0xc0, 0xd0, 0xe4, 0xfd, 0xdf, 0xd7, 0x7a, 0x65, 0xf1, 0x2f, 0x45, 0x61, 0xb, 
        0x59, 0xd9, 0xa, 0x9c, 0x61, 0xc, 0x4, 0x76, 0xdb, 0xb, 0xbe, 0x9e, 0xe4, 0x7f, 0x8d, 0xe1, 0x46 };

    std::vector<uint8_t> iv = { 0xa2, 0x78, 0xc9, 0xa4, 0xd8, 0x34, 0x88, 0x9b, 0x28, 0xdc, 0xb9, 0xe2, 0xc0, 0x58, 0x8c, 0xbc };

    mbedtls_aes_setkey_enc(&AesContext, key.data(), 256);
    mbedtls_aes_setkey_dec(&AesContext, key.data(), 256);

    std::vector<uint8_t> dataEnc = EncryptAes(iv, data);
    printf("Encrypted data: ");
    LogVec(dataEnc);

    //std::vector<uint8_t> dataDec = DecryptAes(iv, dataEnc);
    //printf("Decrypted data: ");
    //LogVec(dataDec);

    getchar();
    return 1;
}

输出:

Encrypted data: (size: 16) {0x5d, 0x1c, 0x9, 0x2e, 0x92, 0x8e, 0x24, 0x43, 0xfa, 0xaf, 0xb3, 0xf5, 0x37, 0x8, 0x99, 0x93, }

在 golang 中使用相同的键 iv、数据的预期输出:

Encrypted: 34730cba3543e5facf4b94ba9dc8a275

最佳答案

在调用mbedtls_aes_crypt_cbc进行加密之前,您应该调用mbedtls_aes_setkey_enc,在调用mbedtls_aes_crypt_cbc进行解密之前,您应该调用mbedtls_aes_setkey_dec 。当两者在初始化时(如代码中)被调用时,后一个对 setkey_dec 的调用将覆盖加密所需的 setkey_enc 设置的上下文结构中的重要数据。

关于c++ - 如何正确使用 mbedtls 的 aes cbc api,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63927837/

相关文章:

asp-classic - 如何使用 AES 在 VBScript 中加密?

java - BouncyCasTLe 和 AES-GCM

c - libtomcrypt 的 RSA 签名验证失败

c - mbedtls 版本之间有什么区别? Mbed TLS 2.xx.x 和 2.x.xx

ssl - Tls 握手失败,即使密码套件是通用的

c++ - 我如何指示 extconf.rb 使用额外的 g++ 优化标志,哪些是可取的?

c++ - 集合的有效交集?

c++ - 如何初始化 std::map 项的 std::vector?

c++ - 在Qt中集成一个Bullet简单demo

c# - 尝试用另一种语言解密时 AES 解密错误