数据加密——aes-基于mbedTLS库

本文介绍了如何在RT-Thread嵌入式操作系统中使用mbedTLS库实现AES-128 CBC加密和解密功能,包括数据加密函数和解密函数的详细代码,以及如何在实际应用中操作加密数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据加密——aes-基于mbedTLS库

mbedTLS(前身 PolarSSL)是一个由 ARM 公司开源和维护的 SSL/TLS 算法库。其使用 C 编程语言以最小的编码占用空间实现了 SSL/TLS 功能及各种加密算法,易于理解、使用、集成和扩展,方便开发人员轻松地在嵌入式产品中使用 SSL/TLS 功能

下面讲解在rt_thread国产实时操作系统中的使用,此处是对UDP的数据内容进行加密

1. 安装这个软件包

在这里插入图片描述
2. 添加自己的.c和.h文件

//crypto.c文件
#include <stdio.h>
#include <string.h>
#include <mbedtls/aes.h>
#include <mbedtls/arc4.h>
#include <mbedtls/md5.h>
#include <mbedtls/sha1.h>
#include <mbedtls/sha256.h>
#include <mbedtls/sha512.h>
#include "crypto.h"

static int __aes_cbc_encrypt(uint8_t *data, int len,
        const uint8_t *key, const uint8_t *iv,
        int key_size, int pad_type)
{
    int i, length;
    uint8_t ivcpy[16];
    uint8_t pad = 0;
    mbedtls_aes_context ctx;

    length = (len + 0x0f) & (~0x0f);

    if (pad_type == CRYPTO_AES_PADDING_NOPADDING && (len & 0x0f))
        return -1;

    if ((len & 0x0f) == 0 && pad_type == CRYPTO_AES_PADDING_PKCS5PADDING)
        length += 16;

    if (pad_type == CRYPTO_AES_PADDING_PKCS5PADDING)
        pad = length - len;

    for (i=0; i<length - len; i++)
        data[len + i] = pad;

    len = length;

    memcpy(ivcpy, iv, 16);

    mbedtls_aes_init(&ctx);
    mbedtls_aes_setkey_enc(&ctx, key, key_size);
    while (length > 0) {
        for (i=0; i<16; i++)
            data[i] ^= ivcpy[i];
        mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, data, data);
        memcpy(ivcpy, data, 16);
        data += 16; length -= 16;
    }
    mbedtls_aes_free(&ctx);

    return len;
}

static int __aes_cbc_decrypt(uint8_t *data, int len,
        const uint8_t *key, const uint8_t *iv,
        int key_size, int pad_type)
{
    int i, length;
    uint8_t ivcpy[16];
    uint8_t *ptr = data;
    uint8_t pad;
    mbedtls_aes_context ctx;

    if (len & 0xf)
        return -1;

    length = len;

    memcpy(ivcpy, iv, 16);

    mbedtls_aes_init(&ctx);
    mbedtls_aes_setkey_dec(&ctx, key, key_size);

    while (length > 0) {
        uint8_t tmp[16];

        memcpy(tmp, data, 16);
        mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_DECRYPT, data, data);
        for (i=0; i<16; i++)
            data[i] ^= ivcpy[i];
        memcpy(ivcpy, tmp, 16);
        data += 16; length -= 16;
    }

    mbedtls_aes_free(&ctx);

    if (pad_type == CRYPTO_AES_PADDING_NOPADDING || \
            pad_type == CRYPTO_AES_PADDING_ZEROPADDING)
        return len;

    pad = ptr[len - 1];
    if (pad < 1 || pad > 16)
        return -1;
    
    for (i=1; i<=pad; i++) {
        if (ptr[len - i] != pad)
            return -1;
        ptr[len - i] = 0;
    }

    return len - pad;
}

int crypto_aes_cbc_encrypt(const uint8_t *input, int len,
        uint8_t *output, const uint8_t *key, const uint8_t *iv,
        int key_size, int pad_type)
{
    if (key_size != CRYPTO_AES_KEY_128BITS && \
            key_size != CRYPTO_AES_KEY_256BITS)
        return -1;

    if (pad_type != CRYPTO_AES_PADDING_NOPADDING && \
            pad_type != CRYPTO_AES_PADDING_ZEROPADDING && \
            pad_type != CRYPTO_AES_PADDING_PKCS5PADDING)
        return -1;

    memcpy(output, input, len);

    return __aes_cbc_encrypt(output, len, key, iv, key_size, pad_type);
}

int crypto_aes_cbc_decrypt(const uint8_t *input, int len,
        uint8_t *output, const uint8_t *key, const uint8_t *iv,
        int key_size, int pad_type)
{
    if (key_size != CRYPTO_AES_KEY_128BITS && \
            key_size != CRYPTO_AES_KEY_256BITS)
        return -1;

    if (pad_type != CRYPTO_AES_PADDING_NOPADDING && \
            pad_type != CRYPTO_AES_PADDING_ZEROPADDING && \
            pad_type != CRYPTO_AES_PADDING_PKCS5PADDING)
        return -1;

    memcpy(output, input, len);

    return __aes_cbc_decrypt(output, len, key, iv, key_size, pad_type);
}

int crypto_aes_ecb_encrypt(const uint8_t *input, int len, 
        uint8_t *output, const uint8_t *key, int keybits)
{
    int i, cnt;
    mbedtls_aes_context ctx;

    if (len % 16)
        return -1;

    cnt = len / 16;

    if (keybits != CRYPTO_AES_KEY_128BITS && \
            keybits != CRYPTO_AES_KEY_256BITS)
        return -1;

    mbedtls_aes_init(&ctx);
    mbedtls_aes_setkey_enc(&ctx, key, keybits);
    for (i=0; i<cnt; i++)
        mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, \
                input + (i << 4), output + (i << 4));
    
    return len;
}

int crypto_aes_ecb_decrypt(const uint8_t *input, int len,
        uint8_t *output, const uint8_t *key, int keybits)
{
    int i, cnt;
    mbedtls_aes_context ctx;

    if (len % 16)
        return -1;

    cnt = len / 16;

    if (keybits != CRYPTO_AES_KEY_128BITS && \
            keybits != CRYPTO_AES_KEY_256BITS)
        return -1;

    mbedtls_aes_init(&ctx);
    mbedtls_aes_setkey_dec(&ctx, key, keybits);
    for (i=0; i<cnt; i++)
        mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_DECRYPT, \
                input + (i << 4), output + (i << 4));
    
    return len;
}

int crypto_rc4(const uint8_t *input, int len, 
        uint8_t *output, const uint8_t *key, int key_size)
{
    mbedtls_arc4_context ctx;

    mbedtls_arc4_init(&ctx);
    mbedtls_arc4_setup(&ctx, key, key_size);
    mbedtls_arc4_crypt(&ctx, len, input, output);
    mbedtls_arc4_free(&ctx);

    return len;
}

int crypto_md5(uint8_t *data, int len, uint8_t dest[16])
{
    mbedtls_md5(data, len, dest);

    return 16;
}

int crypto_sha1(uint8_t *data, int len, uint8_t dest[20])
{
    mbedtls_sha1(data, len, dest);

    return 20;
}

int crypto_sha224(uint8_t *data, int len, uint8_t dest[28])
{
    mbedtls_sha256(data, len, dest, 1);

    return 28;
}

int crypto_sha256(uint8_t *data, int len, uint8_t dest[32])
{
    mbedtls_sha256(data, len, dest, 0);
    
    return 32;
}

int crypto_sha384(uint8_t *data, int len, uint8_t dest[48])
{
    mbedtls_sha512(data, len, dest, 1);

    return 48;
}

int crypto_sha512(uint8_t *data, int len, uint8_t dest[64])
{
    mbedtls_sha512(data, len, dest, 0);

    return 64;
}

//crypto.h文件
#ifndef __CRYPTO_H__
#define __CRYPTO_H__

#include <stdint.h>

#define CRYPTO_RC4_KEY_SIZE                    16
#define CRYPTO_AES_KEY_128BITS                 128
#define CRYPTO_AES_KEY_256BITS                 256
#define CRYPTO_AES_PADDING_NOPADDING           0
#define CRYPTO_AES_PADDING_ZEROPADDING         1
#define CRYPTO_AES_PADDING_PKCS5PADDING        2

#ifdef __cplusplus
extern "C" {
#endif  /* __cplusplus */

int crypto_aes_cbc_encrypt(const uint8_t *input, int len,
        uint8_t *output, const uint8_t *key, const uint8_t *iv,
        int keybits, int pad_type);

int crypto_aes_cbc_decrypt(const uint8_t *input, int len,
        uint8_t *output, const uint8_t *key, const uint8_t *iv,
        int keybits, int pad_type);

int crypto_aes_ecb_encrypt(const uint8_t *input, int len, 
        uint8_t *output, const uint8_t *key, int keybits);

int crypto_aes_ecb_decrypt(const uint8_t *data, int len,
        uint8_t *output, const uint8_t *key, int keybits);

int crypto_rc4(const uint8_t *data, int len, uint8_t *output,
        const uint8_t *key, int key_size);

int crypto_md5(uint8_t *data, int len, uint8_t dest[16]);

int crypto_sha1(uint8_t *data, int len, uint8_t dest[20]);

int crypto_sha224(uint8_t *data, int len, uint8_t dest[28]);

int crypto_sha256(uint8_t *data, int len, uint8_t dest[32]);

int crypto_sha384(uint8_t *data, int len, uint8_t dest[48]);

int crypto_sha512(uint8_t *data, int len, uint8_t dest[64]);

#ifdef __cplusplus
}
#endif  /* __cplusplus */

#endif  /* __CRYPTO_H__ */



3. 添加头文件 #include "crypto.h"
在这里插入图片描述
3.对数据进行加密

static int protocol_data_encrypt(uint8_t *data,uint8_t *output,int len)//加密函数
{
    int encrypt;
    encrypt = (len + 0xf) & (~0xf);

    encrypt = crypto_aes_cbc_encrypt(data, len, output, pub_aes_key, initial_vector, \
            CRYPTO_AES_KEY_128BITS, CRYPTO_AES_PADDING_PKCS5PADDING);

    return encrypt;
}

需要加密时候对该函数进行引用,加密数据前是明文,加密后不可见
encrypt_data_lenth = protocol_data_encrypt((uint8_t *)payload ,data_encrypt ,rt_strlen(payload));
#encrypt_data_lenth 表示加密之后的数据长度
#payload 需要加密的数据
#data_encrypt 加密之后的数据(一般用数组保存)
#rt_strlen(payload) 传入加密数据的长度

4.解密数据

static int protocol_data_decrypt(uint8_t *intput,uint8_t *output, int len)//解密函数
{
    int decrypt = len;

    if (len & 0x0f)
        return -1;

    decrypt = crypto_aes_cbc_decrypt(intput, len, output, pub_aes_key, initial_vector, \
            CRYPTO_AES_KEY_128BITS, CRYPTO_AES_PADDING_PKCS5PADDING);
    if (decrypt < 0)
        return -1;

    return decrypt;
}

需要解密的时候对该函数进行引用,解密之后变成明文
decrypt_data_lenth = protocol_data_decrypt(data_ , data_decrypt , htons(packet_->length));
#decrypt_data_lenth 表示解密之后的数据长度
#data_ 表示需要被解密的数据
#data_decrypt 解密后的数据(一般使用数组进行保存)
#htons(packet_->length) 传入解密数据的长度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HX科技

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值