赞
踩
操作系统:WSL2-Ubuntu22.04
在线AES计算网站:SSLeye
代码中需要用到OpenSSL和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
生成加/解密的密钥
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);
userKey:密钥,必须16、24或32Bytes
bits:密钥长度,128、192或256bit
key:密钥指针
ECB加/解密,每次执行一个块,一个块为16Bytes,明文不足一个块的需要进行补位
void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key, const int enc);
in:明文指针,长度不足一个块16Bytes的需要进行补位
out:密文,长度为一个块16Bytes
key:密钥指针
enc:AES_ENCRYPT或AES_DECRYPT
CBC加/解密,可以加密任意长度的明文,但是密文长度必须为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);
in:明文指针
out:密文指针
length:明文实际长度(不足一个块16Bytes会自动补0),但是密文的长度应该是补0后长度,例如length=8,那么为密文分配的空间应该为16
key:密钥指针
ivec:初始化向量,必须为16字节且可读写。每个块运算完之后会生成新的向量传给下一个块运算,所以加密完成后此值会改变,解密时应该重新赋值。
enc:AES_ENCRYPT或AES_DECRYPT
#include <stdio.h> #include <string.h> #include <openssl/aes.h> #include "base64.h" int main(void) { unsigned char aes_in[16] = "123456789abcdef"; unsigned char aes_out[16]; unsigned char b64_out[1024] = {0}; AES_KEY encrypt_key, decrypt_key; /****************************加密****************************/ // 生成加密密钥 必须128bit/16BYTE AES_set_encrypt_key("1234567890123456", 128, &encrypt_key); // 加密 一次执行一个块即16BYTE AES_ecb_encrypt(aes_in, aes_out, &encrypt_key, AES_ENCRYPT); // 以base64编码形式打印 base64_encode(aes_out, 16, b64_out); printf("%s\r\n", b64_out); // ahBLMYUa/tgH+sxQNzZxyw== /****************************解密****************************/ memset(aes_in, 0, 16); // 生成解密密钥 必须128bit/16BYTE AES_set_decrypt_key("1234567890123456", 128, &decrypt_key); // 解密 一次执行一个块即16BYTE AES_ecb_encrypt(aes_out, aes_in, &decrypt_key, AES_DECRYPT); printf("%s\r\n", aes_in); // 123456789abcdef }
#include <stdio.h> #include <string.h> #include <openssl/aes.h> #include "base64.h" int main(void) { unsigned char ivec[16] = "1234567890123456"; unsigned char aes_in[20] = "1234567890123456789"; unsigned char aes_out[32]; unsigned char b64_out[1024] = {0}; AES_KEY encrypt_key, decrypt_key; /****************************加密****************************/ // 生成加密密钥 必须128bit/16BYTE AES_set_encrypt_key("1234567890123456", 128, &encrypt_key); // 加密 AES_cbc_encrypt(aes_in, aes_out, 20, &encrypt_key, ivec, AES_ENCRYPT); // 以base64编码形式打印 base64_encode(aes_out, 32, b64_out); printf("%s\r\n", b64_out); // 2LWYSMdnDJSym1TSN54uer0JwNlyHlQcjnl1uQ7ofOw= /****************************解密****************************/ memset(aes_in, 0, 20); // 生成解密密钥 必须128bit/16BYTE AES_set_decrypt_key("1234567890123456", 128, &decrypt_key); memcpy(ivec, "1234567890123456", 16); // 解密 AES_cbc_encrypt(aes_out, aes_in, 20, &decrypt_key, ivec, AES_DECRYPT); printf("%s\r\n", aes_in); // 1234567890123456789 }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。