概述

在密码学里面一共有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 cconst 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;// 1raw_buf = (char *)malloc(17);memcpy(raw_buf,"life's a struggle",17);printf("------------------raw_buf\n");printf_buff(raw_buf,17);// 2after_padding_buf = padding_buf(raw_buf,17,&padding_size);printf("------------------after_padding_buf\n");printf_buff(after_padding_buf,padding_size);// 3encrypt_buf = (char *)malloc(padding_size);encrpyt_buf(after_padding_buf,&encrypt_buf, padding_size);printf("------------------encrypt_buf\n");printf_buff(encrypt_buf,padding_size);// 4decrypt_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内存将会改变。

C语言利用openSSL库AES模块加密相关推荐

  1. MacOS下使用C语言基于openssl库进行RSA加密解密

    MacOS下使用C语言基于openssl库进行RSA加密解密 1 安装openssl并生成密钥 首先当然要安装openssl(这里记得看一下安装路径,应该是/usr/local/Cellar/open ...

  2. linux下面C 利用openssl的AES库加密,解密

    OpenSSL提供了AES加解密算法的API const char *AES_options(void); AES算法状态,是全部支持或者是部分支持. 返回值:"aes(full)" ...

  3. php利用openssl实现RSA非对称加密签名

    来源:http://www.webiji.com/archives/412 php利用openssl实现RSA非对称加密签名 1. 先用php生成一对公钥和私钥 $res = openssl_pkey ...

  4. python分数类_利用标准库fractions模块让Python支持分数类型的方法详解

    前言 你可能不需要经常处理分数,但当你需要时,Python的Fraction类会给你很大的帮助.本文将给大家详细介绍关于利用标准库fractions模块让Python支持分数类型的相关内容,分享出来供 ...

  5. C语言使用openssl库进行加密

    概述 在密码学里面一共有3中分类: 1.对称加密/解密 对称加密比较常见的有DES/AES.加密方和解密方都持有相同的密钥.对称的意思就是加密和解密都是用相同的密钥. 2.非对称加密/解密 常见的加密 ...

  6. 单片机c语言 openssl,Linux下C语言使用openssl库进行加密

    在这里插一小节加密的吧,使用openssl库进行加密. 使用MD5加密 我们以一个字符串为例,新建一个文件filename.txt,在文件内写入hello ,然后在Linux下可以使用命令md5sum ...

  7. linux配置文件密码加密工具,Linux下利用openssl对文件进行加密和解密

    转载地址:http://hi.baidu.com/edeed/item/99206a096b62d0e1ff240db8 --建立文件test.txt, 特意写入中英文# cd /tmp # echo ...

  8. 利用openssl进行aes加解密

    之前写过aes加密算法简单说明,本篇用openssl对aes的ecb和cbc模式进行代码编写. 现在拿128位的aes加解密进行说明. 首先强调的是,在openssl提供的函数中,加密和解密每次只能针 ...

  9. c语言 通过openssl进行rsa的加密和解密

    参考资料 https://blog.csdn.net/enjoyinwind/article/details/23530303 https://blog.csdn.net/stormbjm/artic ...

最新文章

  1. 本、硕、博的区别,只用两组图就解释清楚了
  2. 调和油、色拉油、花生油哪种吃着好
  3. UNIX网络编程——套接字选项(SO_RCVBUF和SO_SNDBUF)
  4. 地温梯度 河南_河南省地热(温泉)分布规律
  5. 电磁场与电磁波实验:仿真计算介质板的电磁参数
  6. 计算机网络——数据链路层
  7. 国产分布式ETL调度管理工具 TASKCTL 8.0 核心/代理节点部署
  8. JS实现页面复制文字时自动加版权
  9. 一文读懂DEFI借贷以及清算的含义
  10. OCSNG inventory | 介绍
  11. 基于4G工业路由器的智慧厕所管理方案
  12. 程序员讲装修——平台选择
  13. 一套完整的Android通用框架
  14. LMS算法的基本理论和MATLAB仿真
  15. centos 删除文件夹_手机文件夹是英文,占空间还不敢乱删?花一分钟读懂手机语言...
  16. spring实习总结
  17. Ubuntu 22.04换清华源
  18. 【android极光推送】—从客户端到后台,一文通吃
  19. Java使用Jsoup获得新闻联播所有文字稿
  20. 全世界禁用谷歌的五大国家_5个国家站在Google与世界统治之间

热门文章

  1. 新的ES6语法01—let:使用let关键字声明块范围的变量
  2. 基于 python的MES管理系统
  3. 【最好的U盘分区工具】优易U盘加密软件(U盘加密精灵)V 2.0
  4. html 仿excel,智表-浏览器端仿EXCEL表格jQuery插件
  5. 【SAP-PS笔记】项目交货之基于销售订单VL01N交货
  6. 同一进程中的线程究竟共享那些资源
  7. sqlite插入记录值为纯数字的字符串的问题以及sqlite语句中字符串的拼接
  8. 第2章 词向量表示 GloVe word2vec skip-gram CBOW
  9. 让您的video铺满整个div!
  10. ElasticSearch系列 - SpringBoot整合ES:实现分页搜索 from+size、search after、scroll