Как зашифровать строку в AES WayWith Mbedtls?

Мы все знаем, что библиотека mbedtls - это очень легкая библиотека c. Я хочу использовать библиотеку для шифрования строки. Итак, у меня есть такая функция:

aes_encrypt.h:

#ifndef AES_ENCRYPT_H
#define AES_ENCRYPT_H

#define BOOL int
#define TRUE 1
#define FALSE 0

extern const unsigned char key[16];

BOOL ENC_STR(unsigned char *plain, size_t plain_len, 
             unsigned char *cipher, size_t *cipher_len);
#endif

и реализация:

const unsigned char KEY[16] = { 0x00, 0x01, 0x02, 0x03,
                                0x04, 0x05, 0x06, 0x07, 
                                0x08, 0x09, 0x0A, 0x0B, 
                                0x0C, 0x0D, 0x0F, 0xA0 };

BOOL ENC_STR(unsigned char *plain, size_t plain_len, unsigned char *cipher, size_t *cipher_len)
{
BOOL ret = FALSE;

// Prepare the cipher context
const mbedtls_cipher_info_t *cipher_info;
mbedtls_cipher_context_t cipher_ctx;
mbedtls_cipher_init(&cipher_ctx);

if ((cipher_info = mbedtls_cipher_info_from_type(AES_PARM)) == NULL)
{
    printf("Cipher Info ERR!\n");
    ret = -1;
    goto EXIT;
}

if ( (ret = mbedtls_cipher_setup(&cipher_ctx, cipher_info)) != 0)
{
    printf("Cipher Setup ERR!\n");
    goto EXIT;
}

if ( (ret = mbedtls_cipher_setkey(&cipher_ctx, KEY, cipher_info->key_bitlen, MBEDTLS_ENCRYPT)) != 0)
{
    printf("Cipher SetKey ERR!\n");
    goto EXIT;
}

// if ( (ret = mbedtls_cipher_set_padding_mode(&cipher_ctx, 1)) != 0) {
//     printf("Cipher SetPadding ERR!\n");
//     goto EXIT;
// }


if ( (ret = mbedtls_cipher_reset(&cipher_ctx)) != 0)
{
    printf("Cipher Reset ERR!\n");
    goto EXIT;
}

// encrypt
if ((ret = mbedtls_cipher_update(&cipher_ctx, plain, plain_len, cipher, cipher_len)) != 0) {
    printf("Cipher Update ERR!\n");
    goto EXIT;
}

EXIT:
    if (ret != TRUE) {
        char buf[1024] = {0};
        mbedtls_strerror(ret, buf, 1024);
        printf("Error Msg:\t%s\n", buf);
    }

    mbedtls_cipher_free(&cipher_ctx);
    return ret;
}

Я называю функцию как ниже:

unsigned char *plain = (unsigned char*)"hello world";
size_t plain_len = 12;
unsigned char cipher[128] = {0};
size_t cipher_len = -1;
printf("the encrypt result is:\t%d\n", ENC_STR(plain, plain_len, cipher, &cipher_len));

И я получаю сообщение об ошибке, как показано ниже:

CIPHER - Decryption of block requires a full block

Может кто-нибудь помочь мне и объяснить, что означает сообщение об ошибке? Благодарю.

2 ответа

Вам необходимо завершить шифрование вызовом mbedtls_cipher_finish.

Причина finish возникает из-за необходимости добавить отступы, что не выполняется update. Схема заполнения PKCS7 (используется по умолчанию) всегда что-то добавляет, даже если исходные данныеN * BlockSize длина.

https://tls.mbed.org/api/cipher_8h.html

Объяснение:

CIPHER - для расшифровки блока требуется полный блок
Может кто-нибудь помочь мне и объяснить, что означает сообщение об ошибке?

AES - блочный шифр, это означает, что он реализован для шифрования 128-битного блока в то время. Не больше, не меньше.

Поэтому, если у вас исходные данные короче, чем один блок, вам нужно будет использовать некоторые отступы, чтобы удлинить ваши данные до необходимой длины.

Обычно для шифрования данных любой длины мы используем режим работы. Есть такие, которые не требуют заполнения (CTR, CFB, OFB, ..)

Тем не менее, ваше шифрование будет далеко не безопасным - вам понадобится IV (соль) и тег аутентификации.

Мы все знаем, что библиотека mbedtls - это очень легкая библиотека c

по-видимому, mbedtls уже поддерживает несколько режимов работы, выбор за вами

Вы можете либо зашифровать свой полный буфер, используя mbedtls_cipher_crypt() или зашифруйте свой буфер в несколько вызовов mbedtls_cipher_update(),
Чтобы добавить отступы, вы должны позвонить mbedtls_cipher_set_padding_mode, Однако, как видно из кода, схема заполнения по умолчанию - PKCS7, если MBEDTLS_CIPHER_PADDING_PKCS7 определено.
Согласно вашему коду, вы, похоже, используете AES ECB(вы не установили IV). AES ECB НЕ поддерживает заполнение, и по соображениям безопасности он принимает только входной размер AES BLOCK (16 байт). Как упомянуто ниже, вам следует рассмотреть возможность использования AES CBC для своей работы, так как AES ECB небезопасен для входных данных длиной более 16 байтов, и ваши функции должны быть настолько универсальными, насколько это возможно, для поддержки больших строк.

Другие вопросы по тегам