0

我们都知道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

谁能帮助我并解释错误消息的含义是什么?谢谢。

4

3 回答 3

0

您需要通过调用 来完成加密mbedtls_cipher_finish

的原因finish来自需要添加填充,什么是没有做的update。即使源数据有N * BlockSize长度,PKCS7 填充方案(默认使用)总是添加一些内容。

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

于 2020-06-13T07:41:04.557 回答
0

您可以使用 加密您的完整缓冲区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 字节的输入并不安全,并且您的函数应该尽可能通用以支持大字符串。

于 2018-03-27T11:29:29.963 回答
0

解释:

CIPHER - 块的解密需要一个完整的块
谁能帮我解释一下错误消息的含义是什么?

AES 是一种分组密码,这意味着它被实施为当时加密 128 位块。不多也不少。

因此,如果您的源数据比单个块短,则需要使用一些填充来确保将数据延长到所需的长度。

通常我们使用操作模式来加密任何长度的数据。有些不需要任何填充(CTR、CFB、OFB、..)

您的加密仍然远非安全 - 您将需要 IV (salt) 和authentication tag

我们都知道mbedtls库是一个非常轻量级的c库

显然 mbedtls 已经支持多种操作模式,由您选择

于 2017-12-07T09:45:03.623 回答