C语言利用openSSL库AES模块加密

字符串AES对称加密-openssl命令及C语言实现 用openssl命令和C语言方式实现相同的字符串AES对称加、解密功能。 阅读详情

概述

在密码学里面一共有3中分类:

1.对称加密/解密

对称加密比较常见的有DES/AES。加密方和解密方都持有相同的密钥。对称的意思就是加密和解密都是用相同的密钥。

2.非对称加密/解密

常见的加密算法DSA/RSA。如果做过Google Pay的话,应该不会陌生。非对称意味着加密和解密使用的密钥不是相同的。这种应用的场合是需要保持发起方的权威性,比如Google中一次支付行为,只能Google通过私钥来加密产出来,但是大家都能通过公钥来认证这个是真的。打个更加浅显的比方:私钥可以理解成美联储的印钞机,公钥可以理解成在民间无数的美元验钞机。
还有一个场合也是https使用证书方式登录的时候,也是使用的双向的非对称加密模式来做的。

3.离散

这种只能被称为验签,而不是加密。因为这类算法只能一个方向(将输入数据离散到某个特定的数字,反向解密是无法做到的。)。最常见的算法就是MD5。在写php的时候大量的使用这种验签来做认证。他可以将字符串离散成32byte的16进制的数字。
本次使用AES CBC方式来加密。CBC模式加密是SSL的通讯标准,所以在做游戏的时候经常会使用到。openSSL的基本用法可以参考这个

两个细节

这种加密的需要了解下面两个细节:
1.加密的内存块一般按照16字节(这个也可以调整)对齐;当原始内存块没有对齐字节数的时候,需要填充;
2.加密解密不会引发内存的膨胀或者缩小;
最近在使用python,java,c#都去看过AES的接口,最轻松的是c#,java。当使用C来写,才能明显感受到在这些操作过程中,有多少次内存的分配,多少的内存拼接。啥事都有成本,封装良好的语言损失掉的效率可能来自于这些便利。

准备知识

函数接口

int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
                        AES_KEY *key);
int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
                        AES_KEY *key);
// 设置加密key
AES_KEY aes;
AES_set_encrypt_key(key,128,&aes);// 这里填写的128是bit位,128bit=(128/8)bytes=16bytes,这个换算和32bit对应int为内存指针的原理一样。
// 初始化自己的key
char key[16];

// 加密函数
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
                     size_t length, const AES_KEY *key,
                     unsigned char *ivec, const int enc);

# define AES_BLOCK_SIZE 16 // aes.h 71 lines
# define AES_ENCRYPT     1 // aes.h 63 lines
# define AES_DECRYPT     0 // aes.h 64 lines
// 定义一个加密的初始化向量
unsigned char iv[AES_BLOCK_SIZE];
// 加密
AES_cbc_encrypt(raw_buf,encrypt_buf,buf_size,&aes,iv,AES_ENCRYPT);
// 解密
AES_cbc_encrypt(raw_buf,encrypt_buf,buf_size,&aes,iv,AES_DECRYPT);

字串转换

// 16进制的字串转换成16byte存储起来
// hex string to byte in c
    const char hexstring[] = "deadbeef10203040b00b1e50", *pos = hexstring;
    unsigned char val[12];
    size_t count = 0;

     /* WARNING: no sanitization or error-checking whatsoever */
    for(count = 0; count < sizeof(val)/sizeof(val[0]); count++) {
        sscanf(pos, "%2hhx", &val[count]);
        pos += 2;
    }

    printf("0x");
    for(count = 0; count < sizeof(val)/sizeof(val[0]); count++)
        printf("%02x", val[count]);
    printf("\n");

padding算法

    char *raw_buf = ...;
    int raw_size = ...;
    char *final_buf = NULL;
    int pidding_size = AES_BLOCK_SIZE - (raw_size % AES_BLOCK_SIZE);
    int i;

    final_buf = (char *)malloc(raw_size+pidding_size);
    if (pidding_size!=0) {
        memcpy( final_buf, raw_buf, raw_size);
        for (i =raw_size;i < (raw_size+pidding_size); i++ ) {
            // zero padding算法:
            final_buf[i] = 0;
            or
            // PKCS5Padding算法
            final_buf[i] = pading;
        }
    }

完整的代码

c语言代码

// main.c
#include <aes.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>

unsigned char* str2hex(char *str) {
        unsigned char *ret = NULL;
        int str_len = strlen(str);
        int i = 0;
        assert((str_len%2) == 0);
        ret = (char *)malloc(str_len/2);
        for (i =0;i < str_len; i = i+2 ) {
                sscanf(str+i,"%2hhx",&ret[i/2]);
        }
        return ret;
}

char *padding_buf(char *buf,int size, int *final_size) {
        char *ret = NULL;
        int pidding_size = AES_BLOCK_SIZE - (size % AES_BLOCK_SIZE);
        int i;

        *final_size = size + pidding_size;
        ret = (char *)malloc(size+pidding_size);
        memcpy( ret, buf, size);
        if (pidding_size!=0) {
                for (i =size;i < (size+pidding_size); i++ ) {
                        ret[i] = 0;
                }
        }

        return ret;
}

void printf_buff(char *buff,int size) {
        int i = 0;
        for (i=0;i<size;i ++ ) {
                printf( "%02X ", (unsigned char)buff[i] );
                if ((i+1) % 8 == 0) {
                        printf("\n");
                }
        }

        printf("\n\n\n\n");
}

void encrpyt_buf(char *raw_buf, char **encrpy_buf, int len ) {
        AES_KEY aes;
        unsigned char *key = str2hex("8cc72b05705d5c46f412af8cbed55aad");
        unsigned char *iv = str2hex("667b02a85c61c786def4521b060265e8");
        AES_set_encrypt_key(key,128,&aes);
        AES_cbc_encrypt(raw_buf,*encrpy_buf,len,&aes,iv,AES_ENCRYPT);

        free(key);
        free(iv);
}

void decrpyt_buf(char *raw_buf, char **encrpy_buf, int len ) {
        AES_KEY aes;
        unsigned char *key = str2hex("8cc72b05705d5c46f412af8cbed55aad");
        unsigned char *iv = str2hex("667b02a85c61c786def4521b060265e8");
        AES_set_decrypt_key(key,128,&aes);
        AES_cbc_encrypt(raw_buf,*encrpy_buf,len,&aes,iv,AES_DECRYPT);

        free(key);
        free(iv);
}

int main(int argn, char *argv[] ) {
        char *raw_buf = NULL;
        char *after_padding_buf = NULL;
        int padding_size = 0;
        char *encrypt_buf = NULL;
        char *decrypt_buf = NULL;


        // 1
        raw_buf = (char *)malloc(17);
        memcpy(raw_buf,"life's a struggle",17);
        printf("------------------raw_buf\n");
        printf_buff(raw_buf,17);

        // 2
        after_padding_buf = padding_buf(raw_buf,17,&padding_size);
        printf("------------------after_padding_buf\n");
        printf_buff(after_padding_buf,padding_size);

        // 3
        encrypt_buf = (char *)malloc(padding_size);
        encrpyt_buf(after_padding_buf,&encrypt_buf, padding_size);
        printf("------------------encrypt_buf\n");
        printf_buff(encrypt_buf,padding_size);

        // 4
        decrypt_buf = (char *)malloc(padding_size);
        decrpyt_buf(encrypt_buf,&decrypt_buf,padding_size);
        printf("------------------decrypt_buf\n");
        printf_buff(decrypt_buf,padding_size);


        free(raw_buf);
        free(after_padding_buf);
        free(encrypt_buf);
        free(decrypt_buf);

        return 0;
}

编译scons脚本:

# SConstruct
import glob
env = Environment()      

env["CPPPATH"] = [ '/usr/include/openssl' ]
env['LIBPATH'] = [ '/home/abel/lib/openssl-1.0.2f' ]

env['CPPDEFINES'] = ['LINUX', '_DEBUG' ]
env['CCFLAGS'] = '-g -std=gnu99'
env['LIBS'] = [ 'm', 'crypto', 'dl' ]

env.Program( target = "./test_aes", source = ( glob.glob( './*.c' ) ) )

输出结果:

:!./test_aes                                                                                                                                                                                                                                 
------------------raw_buf
6C 69 66 65 27 73 20 61 
20 73 74 72 75 67 67 6C 
65 



------------------after_padding_buf
6C 69 66 65 27 73 20 61 
20 73 74 72 75 67 67 6C 
65 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 




------------------encrypt_buf
DB 63 28 C5 2C 6A 3F 1B 
FD 4B C5 47 94 4E 24 9D 
D2 15 4C F2 6B 3B 1D C0 
E7 D2 7B D6 1E 78 60 EA 




------------------decrypt_buf
6C 69 66 65 27 73 20 61 
20 73 74 72 75 67 67 6C 
65 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 

总结

代码中还是有很多地方都是直接malloc内存出来,这些点都能扣得更加细。在每次加密调用的时候IV内存将会改变。

基于openssl库实现AES加密(C语言) 一、AES加密算法 阅读详情

相关推荐

利用OpenSSL库对Socket传输进行安全加密(RSA+AES)_socket通过库加解密

到此, Client和Server已经完成完成传输Seed的处理。— 后面的流程是它们怎样使用这个Seed来进行业务数据的安全传输。— Client传输数据给Server。— Server传输数据给Client。

2401_85013615的博客 1441

OpenSSL 使用AES对文件加解密

AES(Advanced Encryption Standard)是一种对称加密算法,它是目前广泛使用的加密算法之一。AES算法是由美国国家标准与技术研究院(NIST)于2001年发布的,它取代了原先的DES(Data Encryption Standard)算法,成为新的标准。AES是一种对称加密算法,意味着加密和解密使用相同的密钥。这就要求密钥的安全性非常重要,因为任何拥有密钥的人都能进行加密和解密操作。其密钥长度,包括128位、192位和256位。不同长度的密钥提供了不同级别的安全性,通常更长的密钥长

微软技术分享 8266

文件AES对称加密-openssl命令和C代码实现

文件AES对称加密-openssl命令和C代码实现

hinewcc的博客 1874

OpenSSL AES对称加密

EVP_CipherInit_ex()、EVP_CipherUpdate() 和 EVP_CipherFinal_ex() 是可用于解密或加密的函数。EVP_DecryptInit_ex()、EVP_DecryptUpdate()和EVP_DecryptFinal_ex()是对应的解密操作。对称加密也被称为共享密钥加密,是一种将相同密钥用于加密和解密的加密方式。在对称加密中,加密和解密使用的是相同的密钥,因此需要确保密钥的安全性。接收方使用相同的密钥对加密后的数据进行解密。适合用于大量数据的加密。

weixin_42936764的博客 2215

c++使用openssl库实现RSA、AES数据加密

使用openssl库实现RSA、AES数据加密      openssl是可以很方便加密解密的库,可以使用它来对需要在网络中传输的数据加密。可以使用非对称加密:公钥加密,私钥解密。openssl提供了对RSA的支持,但RSA存在计算效率低的问题,所以一般的做法是使用对称密钥加密数据,然后再把这个只在当前有效的临时生成的对称密钥用非对称密钥的公钥加密之后传递给目标方,目标方使用约定好的非对

qq839306215的专栏 1万+

使用openssl库实现RSA、AES数据加密

openssl是可以很方便加密解密的库,可以使用它来对需要在网络中传输的数据加密。可以使用非对称加密:公钥加密,私钥解密。openssl提供了对RSA的支持,但RSA存在计算效率低的问题,所以一般的做法是使用对称密钥加密数据,然后再把这个只在当前有效的临时生成的对称密钥用非对称密钥的公钥加密之后传递给目标方,目标方使用约定好的非对称密钥中的私钥解开,得到数据加密的密钥,再进行数据解密,得到数据。对

未语愁眸 2474

利用openssl库,C语言实现AES加密

利用openssl库,C语言实现AES加密

buhuidage的博客 6006

openssl+AES开发实例(linux)

AES(Advanced Encryption Standard)是一种对称密钥加密标准,它是一种对称加密算法,意味着相同的密钥用于加密和解密数据。AES 是 NIST(美国国家标准与技术研究院)于2001年发布的标准,用于替代原先的 DES(Data Encryption Standard)。AES 支持多种密钥长度,包括128位、192位和256位。密钥长度的不同影响了加密算法的安全性,通常更长的密钥长度意味着更高的安全性。AES 将数据分成固定大小的块(分组),每个块的大小是128位。

N阶二进制的博客 1327

linux以下C 利用openssl的AES库加密,解密

OpenSSL提供了AES加解密算法的API   const char *AES_options(void); AES算法状态,是所有支持或者是部分支持。 返回值:“aes(full)” 或者"aes(partial)"   int AES_set_encrypt_key(const unsigned char *userKey, const int bits,AES_KEY *key...

华的专栏 1804

AES:AES算法库在C中以128位192位256位实现

AES 具有128bit / 192bit / 256bit的AES库 主要文件是aes.h aes.c conf.c,test_case.c是使用CUnit进行的测试。 到目前为止,它支持128位,192位或256位加密和解密。 编译此程序包的最简单方法是: cd到包含软件包源代码和类型的目录 输入“ make”来编译包装,测试和样品。 键入“ make install”以安装库。 输入make make来卸载库。 您可以通过键入“ make clean”从源代码目录中删除程序二进制文件和目标文件。

【Python・统计学】(两)多因素方差分析(原理及代码)

自学笔记,分享给对统计学原理不太清楚但需要在论文中用到的小伙伴,欢迎大佬们补充或绕道。ps:本文不涉及公式讲解(文科生小白友好体质)~(部分定义等来源于知乎) 本文重点:多因素方差分析 【1.多因素方差分析简单原理】 【2.多因素方差分析步骤】 【3.多因素方差分析代码】

TUTO_TUTO的博客 4864

C语言 openssl库 AES对称加解密 CBC模式 PKCS7Padding填充 256秘钥 带16偏移 base64编解码

最近学习对接平台 需要用到 AES BASE64 加密对接接口 非常少的资料 而且满足不了需要或者有bug,譬如无偏移,base解码超位数输出不正常等 最后整理出如标题所示的结果 希望能帮助到有需要的朋友 也给自己往后回顾用 使用前需要安装openssl库 使用方法: <./aes 数据> <例子:./aes test> <注意:有空格会被当成多个参数> 功能介...

qq_38916259的博客 7946

Markdown编辑器介绍

这篇文章介绍了Markdown编辑器的功能和使用方法。主要内容包括:Markdown的基本语法如标题、列表、链接插入等;新增功能如图片拖拽、数学公式支持、甘特图和UML图表绘制;常用快捷键说明;以及文本导出导入操作。文章详细说明了如何通过Markdown语法实现文本格式化、代码高亮、表格创建等功能,并提供了多种图表绘制的语法示例,帮助用户更好地利用Markdown编辑器进行写作和内容创作。

soso1968的博客 1178

linux c openssl aes 加解密

1.OpenSSL提供了AES加解密算法的API const char *AES_options(void); AES算法状态,是所有支持或者是部分支持。 返回值:“aes(full)” 或者"aes(partial)" int AES_set_encrypt_key(const unsigned char *userKey, const int bits,AES_KEY *key)...

whatday的专栏 9662

医疗影像配准与融合: 使用MATLAB对医学影像进行配准和融合,实现不同影像模态之间的对准和结构信息融合等

医疗影像配准与融合是医学影像处理的重要技术,它用于将不同来源、不同时间或不同模态的医学影像进行配准和融合,以获得更加完整、准确的患者解剖信息。基于MATLAB的医疗影像配准与融合可以帮助医生更准确地诊断疾病,制定更有效的治疗方案。医疗影像配准与融合是医学影像处理的关键技术,它对于提高医学影像诊断和治疗的准确性至关重要。MATLAB是一种功能强大的数学和科学计算软件,它可以为医疗影像配准与融合提供强大的工具和支持。

走向CTO的路上... 711

一条时间轴上的商品供给:商品供给域事件全景、八大子域事件清单与事件契约规范的工程推演

本文以虚构连锁零售企业“青禾鲜市”为例,用事件风暴重新梳理商品供给域:先剖析同词异义、状态模糊、隐式依赖与被动兜底四类冲突,再以时间轴、八条子域泳道与关键事件铺出全景地图,确立一个事件只有一个户口;随后为总店商品、门店商品、价格、库存、质量、标签、变更通知与操作日志列出聚合、事件、命令与策略,并统一命名、信封结构、版本与幂等规范。程序体检把初稿14个问题清零,仿真显示按聚合版本号更新可售视图可将误判从两位数百分比降到0.019%。文末给出四轮工作坊节奏与新品引入、全国调价、批次召回走查剧本。

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 5万+

C语言aes256加密解密 基于openssl的evp库进行的aes_256_ecb的加密解密。(同时包含base64转码解码)

基于openssl的evp库进行的aes_256_ecb的加密解密。(同时包含base64转码) 遇到了需要进行数据加密解密的工作,进行多方查找比较觉得还是evp的库使用比较方便,写了个小demo在此记录一下,话不多说见代码。 #include <openssl/evp.h> #include <string.h> //base64转码 int DesEncode(char *inbuf, char *outbuf, int len) { int ret = 0; //ev

qq_40519022的博客 2326

无刷电机里的霍尔传感器,和 AS5600 编码器到底有什么区别?

摘要: 无刷电机中的霍尔传感器主要用于换相控制,提供6种状态反馈,无法实现精确角度测量。与AS5600磁编码器(分辨率4096)相比,霍尔仅能确保电机“转得对”,而编码器则用于高精度角度反馈。在机器人等需要位置闭环的场景中,两者需协同使用:霍尔负责基础换相,编码器提供精确角度控制。简单应用中可仅用霍尔,但高精度定位必须搭配编码器。

qq_45430571的博客 241

Linux C语言调用OpenSSL: 对称算法(AES高级加密标准)

Linux C语言调用OpenSSL: 对称加解密(AES高级加密标准),c语言实现

Penseur2018的博客 1360

C#上位机多PLC多协议开发思路:10年老工控师拆解实战方案,避坑90%的问题(附代码框架)

是否连接成功数据地址(如“DB1.DBW0”“D100”“4x0001”)

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 947

二十一、CANdelaStudio深入-SPRMIB的配置

本专栏将由浅入深的展开诊断实际开发与测试的数据库编辑,包含大量实际开发过程中的步骤、使用技巧与少量对Autosar标准的解读。希望能对大家有所帮助,与大家共同成长,早日成为一名车载诊断、通信全栈工程师。 本文介绍CANdelaStudio的肯定响应抑制位配置,欢迎各位朋友订阅、评论,可以提出宝贵意见,以持续输出更好的作品,同时会根据评论、私信不定期更新文章内容,以及专栏目录。订阅该专栏的朋友可私信小编免费答疑解惑(^U^)ノ~YO CANdelaStudio-从入门到深入目录 文章目录CANdelaStu

诊断协议那些事儿's blog 1868

对称加密算法AES【C/C++运用openssl库】

白嫖是一种罪,有用就点个赞把 一.在介绍AES之前我们还是简单的介绍一下DES和3DES 1.DES【可破解的】:全称为Data Encryption Standard ,即数据加密标准,是一种使用密钥加密的块算法,DES算法的入口参数有三个: Key,Data,Mode,其中Key 为7个字节 共56位,是DES算法的工作密钥: Data为8字节 64位,是要被加密或者破解的数据,Mode是DES的工作方式,有加密或者解密两种 2.3DES【很难破解的】:【即Triple DES】,是DES.

qq_44065088的博客 1104

怎么调用onenet平台的API从而读取我们的设备数据和下发命令,做到控制开关

怎么调用onenet平台的API从而读取我们的设备数据和下发命令,做到控制开关 1、首先是怎么读取数据 读取的API是:http://api.heclouds.com/devices/datapoints?devIds=629063002 其中devids这个指的是你的设备ID 然后在我们的headers里面添加一些必要参数,就可以调用了 其中api-key的是你产品里面的master-apikey 把我们的参数写好就可以调用了,选择get方式,点击发送 这个value就是我们需要获取到的参数值了,

zyh960的博客 2万+

基于openssl的AES-CBC加密算法C语言实现

AES(Advanced Encryption Standard,高级加密标准)是一种对称加密算法,而CBC(Cipher Block Chaining,密码分组链接)是AES的一种工作模式,即密码分组链接模式。

qq_40780462的博客 1476

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

基于OpenSSL的AES加密(C/C++)

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

qq_36973838的博客 7723

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

上一篇: cJSON库解析
下一篇: Boost.log库使用方法
erlang_hell
博客等级 码龄14年 57粉丝 89原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值