Как правильно использовать aes cbc api от 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, }

Ожидаемый результат от использования того же ключа, iv, данных в golang:

Encrypted: 34730cba3543e5facf4b94ba9dc8a275

person Dalton Sandbothe    schedule 16.09.2020    source источник


Ответы (1)


Перед вызовом mbedtls_aes_crypt_cbc для шифрования следует вызвать mbedtls_aes_setkey_enc, а перед вызовом mbedtls_aes_crypt_cbc для расшифровки следует вызвать mbedtls_aes_setkey_dec. Когда оба вызываются при инициализации, как в вашем коде, последний вызов setkey_dec перезапишет важные данные в структуре контекста, установленной setkey_enc, необходимой для шифрования.

person Maxwell Kunes    schedule 17.09.2020