赞
踩
一、简述
记--C语言实现的AES加解密。
示例代码打包:外链:https://wwm.lanzouq.com/b0camwuah 密码:7ios
二、AES简述
| 名称 | 内容 | 备注 |
|---|---|---|
| AES描述 | AES属于对称加密,就是用一个密匙K将数据Data1加密得到Data2, 解密时需要密匙K对Data2解密还原为Data1。 | 对称加密算法也就是加密和解密用相同的密钥。 |
| 密匙长度 | AES128是16字节,也就是128bit; AES192是24字节,也就是192bit; AES256是32字节,也就是256bit; |
|
| 加密轮数 | AES128是10轮; AES192是12轮; AES256是14轮; |
根据给出的初始密匙再拓展出多个密匙。轮数多的安全性相对更高些。 |
| 明文分组 | 明文也就是要加密的数据,按16字节为一组进行分别加密,不够16字节的可进行数据填充。如果选择了填充方式,解密后需要将填充的数据剔除。 填充方式: NoPadding:不填充,那就只能加密长度为16倍数的数据,一般不使用 PKCS5(PKCS7):应用比较多,最后一组缺几个字节就填充几 |
PKCS7示例: 要加密的数据是0123456789abc共13个数据,再填充3个才够16个,PKCS7填充时会在后面填充3个3。 |
| 加密方式 | 电码本模式(Electronic Codebook Book (ECB)):将明文按16字节分组,每个明文使用同一个初始块向量,每组分别加密后拼接。 密码分组链接模式(Cipher Block Chaining (CBC)):因为ECB每个明文使用同一个初始化向量,所以明文内相同的明文分组,加密的密文也是相同的;针对这个问题就有了CBC模式,每一小段明文先与初始块向量或者上一段的密文段进行异或运算后,再与密钥进行加密;简单来说就是每一段的明文的初始块向量都是不一样的,这样明文内相同的明文分组,加密的密文也因此不同。 |
实际应用比较多的是ECB和CBC。 |
三、示例代码
main.c
- #include "aes.h"
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h> //isprint
-
- /* 编译指令
- D:\R\Qt5.7\Tools\mingw530_32\bin\gcc.exe -fdiagnostics-color=always -g D:\VSCode\AES\main.c D:\VSCode\AES\aes.c -o D:\VSCode\AES\main.exe
- */
-
- void PrintData(const char *head, unsigned char *data, unsigned int len)
- {
- unsigned int i;
-
- printf("%s, len:%u:\r\n", head, len);
-
- //按16进制打印出来
- printf("HEX:[");
- for (i=0; i<len; i++) {
- printf("%02X ", data[i]);
- }
- printf("]\r\n");
-
- //按ASCII码打印出来
- printf("ASCII:[");
- for (i=0; i<len; i++) {
- if (isprint(data[i])) {//可打印字符
- printf("'%c' ", data[i]);
- } else {
- printf("\\%02X ", data[i]);
- }
-
- }
- printf("]\r\n");
- }
-
- int main(int argc, char *argv[])
- {
- unsigned int len;
- //秘钥,根据实际情况自己定义,AES128 用16字节、AES192 用24字节、AES256 用32字节
- unsigned char key[32] = {
- 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x30,0x41,0x42,0x43,0x44,0x45,0x46,
- 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x30,0x41,0x42,0x43,0x44,0x45,0x46
- };
-
- //初始化向量, 固定长度16个, 当mode=AES_MODE_CBC时用到
- unsigned char IV[4*Nb] = {0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x30,0x41,0x42,0x43,0x44,0x45,0x46};
-
- //要加密的内容
- unsigned char sourceMsg[] = "Hello AES 128/192/256";
- //加密后的内容
- unsigned char encryptMsg[sizeof(sourceMsg)+16] = {0};
- //解密后的内容
- unsigned char decryptMsg[sizeof(sourceMsg)+16] = {0};
-
- //设置加密方式、密匙
- AESInfo_t aesInfo = {
- .type = AES256,
- .mode = AES_MODE_CBC,
- .key = key,
- .pIV = IV
- };
-
- printf("Build %s %s\r\n", __DATE__, __TIME__);
- PrintData("sourceMsg", sourceMsg, strlen((const char *)sourceMsg));
-
- //初始化
- AESInit(&aesInfo);
-
- //加密
- len = AESEncrypt(&aesInfo, sourceMsg, encryptMsg, strlen((const char *)sourceMsg));
- PrintData("encryptMsg", encryptMsg, len);
-
- //解密
- len = AESDecrypt(&aesInfo, decryptMsg, encryptMsg, len);
- PrintData("decryptMsg", decryptMsg, len);
-
- return 0;
- }

aes.c
- #include "aes.h"
- #include <string.h>
-
- // GF(2^8) 多项式
- #define BPOLY 0x1B //x^4 + x^3 + x^1 + x^0= 从右边开始算,bit0、bit
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。