• 基于mbedtls的AES加密(C/C++)


    环境

    操作系统:WSL2-Ubuntu22.04

    加密库:mbedtlsBase64

    在线AES计算网站:SSLeye

    代码中需要用到mbedtls和Base64,可以根据上述链接获取



    简介

    高级加密标准(Advanced Encryption Standard,AES),是一种对称加密方式。AES支持三种加密方式:AES128,AES192,AES256,AES128标识密钥长度为128bit,AES128运算速度最快,AES256安全性最佳,三种方式的本质区别是加密轮数不同。



    模式

    一共有4种加密模式,即ECB、CBC、CFB、OFB,本文仅讲解最常见的ECB、CBC模式,有机会更新后续两种。

    ECB模式:

    优点:1.简单;2.有利于并行计算;3.误差不会被传送
    缺点: 1.不能隐藏明文的模式(例如加密一张图片,虽然看不到原图,但是可能看到其轮廓);2.可能对明文进行主动攻击

    CBC模式:

    优点:1.不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准
    缺点:1.不利于并行计算;2.误差传递;3.需要初始化向量IV



    API简介

    初始化/释放句柄

    void mbedtls_aes_init( mbedtls_aes_context *ctx );
    void mbedtls_aes_free( mbedtls_aes_context *ctx );
    
    • 1
    • 2



    生成加/解密的密钥

    int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits );
    int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits );
    
    • 1
    • 2

    ctx:句柄

    key:密钥,必须16、24或32Bytes

    keybits:密钥长度,128、192或256bit




    ECB加/解密,每次执行一个块,一个块为16Bytes,明文不足一个块的需要进行补位

    int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
                        int mode,
                        const unsigned char input[16],
                        unsigned char output[16] );
    
    • 1
    • 2
    • 3
    • 4

    ctx:句柄

    mode:MBEDTLS_AES_ENCRYPT或MBEDTLS_AES_DECRYPT

    input:输入指针,长度不足一个块16Bytes的需要进行补位

    output:输出指针,长度为一个块16Bytes




    CBC加/解密,可以加密任意长度的明文(必须补齐为16的整倍数)

    int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
                        int mode,
                        size_t length,
                        unsigned char iv[16],
                        const unsigned char *input,
                        unsigned char *output );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    ctx:句柄

    mode:MBEDTLS_AES_ENCRYPT或MBEDTLS_AES_DECRYPT

    length:输入长度(必须补齐为16的整倍数)

    iv:初始化向量,必须为16字节且可读写。每个块运算完之后会生成新的向量传给下一个块运算,所以加密完成后此值会改变,解密时应该重新赋值。

    input:输入指针

    output:输出指针



    ECB加/解密DEMO

    #include 
    #include 
    #include "mbedtls/aes.h"
    #include "base64.h"
    
    int main(void)
    {
        mbedtls_aes_context aes_ctx;
        unsigned char aes_in[16] = "123456789abcdef";
        unsigned char aes_out[16];
        unsigned char b64_out[1024] = {0};
    
        mbedtls_aes_init(&aes_ctx);
    
    /****************************加密****************************/    
        // 加载加密密钥
        mbedtls_aes_setkey_enc(&aes_ctx, "1234567890123456", 128);
    
        // 加密 一次执行一个块即16BYTE
        mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, aes_in, aes_out);
        
        // 以base64编码形式打印
        base64_encode(aes_out, 16, b64_out);
        printf("%s\r\n", b64_out);
        // ahBLMYUa/tgH+sxQNzZxyw==
    
    /****************************解密****************************/
        memset(aes_in, 0, 16);
    
        // 加载解密密钥
        mbedtls_aes_setkey_dec(&aes_ctx, "1234567890123456", 128);
    
        // 解密
        mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_DECRYPT, aes_out, aes_in);
    
        printf("%s\r\n", aes_in);
        // 123456789abcdef
    
    /****************************End****************************/
        mbedtls_aes_free(&aes_ctx);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41



    CBC加/解密DEMO

    #include 
    #include 
    #include "mbedtls/aes.h"
    #include "base64.h"
    
    int main(void)
    {
        mbedtls_aes_context aes_ctx;
        unsigned char ivec[16] = "1234567890123456";
        unsigned char aes_in[32] = "1234567890123456789";
        unsigned char aes_out[32];
        unsigned char b64_out[1024] = {0};
    
        mbedtls_aes_init(&aes_ctx);
    
    /****************************加密****************************/    
        // 加载加密密钥
        mbedtls_aes_setkey_enc(&aes_ctx, "1234567890123456", 128);
    
        // 加密
        mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_ENCRYPT, 32, ivec, aes_in, aes_out);
        
        // 以base64编码形式打印
        base64_encode(aes_out, 32, b64_out);
        printf("%s\r\n", b64_out);
        // 2LWYSMdnDJSym1TSN54uer0JwNlyHlQcjnl1uQ7ofOw=
    
    /****************************解密****************************/
        memset(aes_in, 0, 32);
    
        // 加载解密密钥
        mbedtls_aes_setkey_dec(&aes_ctx, "1234567890123456", 128);
    
        memcpy(ivec, "1234567890123456", 16);
    
        // 解密
        mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_DECRYPT, 32, ivec, aes_out, aes_in);
    
        printf("%s\r\n", aes_in);
        // 1234567890123456789
        
    /****************************End****************************/
        mbedtls_aes_free(&aes_ctx);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
  • 相关阅读:
    Cisco ASA基础——安全算法与基本配置
    循环结构 ----- for/in 语句 与 for/of语句
    MySQL数据库基本操作
    008 怎么取消隐藏文件扩展名
    什么是RBAC?
    错误消息 “Column ‘device_id‘ in field list is ambiguous“
    弹跳的小球
    C++入门(1)
    ragflow 大模型RAG知识库使用案例
    解决:Navicat导入sql脚本时报2006
  • 原文地址:https://blog.csdn.net/qq_36973838/article/details/128203684