本文共 5342 字,大约阅读时间需要 17 分钟。
AES介绍
不多说了,可以度娘。。。 贴点传送门,都是优秀的参考文献 链接: 实用贴——分组加密的常用工作模式 链接: OPENSSL库的使用-AES篇贴一下头文件,有兴趣的都应该去翻openssl/include
#include <openssl/aes.h> //aes加密# define AES_ENCRYPT 1# define AES_DECRYPT 0/** Because array size can't be a const in C, the following two are macros.* Both sizes are in bytes.*/# define AES_MAXNR 14# define AES_BLOCK_SIZE 16// AES默认块长 128bits,大部分代码会调用 AES_BLOCK_SIZE 去初始化typedef struct aes_key_st AES_KEY;const char *AES_options(void);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);/*这两个函数分别用于加解密的密钥生成@const unsigned char *userKey 约定密码@const int bits 密码长度 分别对应128 、 192 、 256 注意这里是bits,所以是输入密码长度*8,也就是16位长度密码对应128bits@AES_KEY *key 生成密体*/void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key, const int enc);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 数据长度@key 密钥体AES_KEY @ivec 初始向量(一般为16字节全0)@enc AES_ENCRYPT 代表加密, AES_DECRYPT代表解密;*/
可以使用#include <openssl/aes.h> 去进行加密处理
// AES加密std::string aes_encode(std::string& data, std::string& passwd){ int dataLen = data.length(); int nPadd = AES_BLOCK_SIZE - dataLen % AES_BLOCK_SIZE; //pkcs7padding,缺N位就补N个N data.append(size_t(nPadd), char(nPadd)); dataLen = data.length(); //补齐之后的数据长度 unsigned char ivb[AES_BLOCK_SIZE]; //一般16位,关于IV这里用的是全‘0’填充 memset(&ivb, '0', AES_BLOCK_SIZE); //有兴趣增加密码安全的可以置换或者随机IV随加密结果输出 unsigned char buf[dataLen]; memset(&buf, 0, dataLen); AES_KEY key; AES_set_encrypt_key((unsigned const char *)(passwd.c_str()), 128, &key); //*8 int bit 设置密钥 AES_cbc_encrypt((unsigned const char *)(data.c_str()), buf, dataLen, &key, &(ivb[0]), AES_ENCRYPT); //enc: 加密/解密模式,AES_ENCRYPT,加密;AES_DECRYPT,解密; auto base64Out = base64_encode(buf, dataLen); //这个不是加密过程,普通base64 return base64Out;}std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) { std::string ret; int i = 0; int j = 0; unsigned char char_array_3[3]; unsigned char char_array_4[4]; while (in_len--) { char_array_3[i++] = *(bytes_to_encode++); if (i == 3) { char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; for(i = 0; (i <4) ; i++) ret += base64_chars[char_array_4[i]]; i = 0; } } if (i) { for(j = i; j < 3; j++) char_array_3[j] = '\0'; char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; for (j = 0; (j < i + 1); j++) ret += base64_chars[char_array_4[j]]; while((i++ < 3)) ret += '='; } return ret; }
好吧,等我试了几次死磕出了加密方法之后,小伙伴突然说openssl有个EVP框架,实现了加解密过程。。。早说嘛,不过说实话实际用上之后觉得好像比自己写还复杂,可能对于ECB和CBC模式来说大材小用了,期望RSA会简单还有流式加解密模式。
#include <openssl/evp.h>
std::string aes_encodeV1(std::string& data, std::string& passwd){ EVP_CIPHER_CTX *ctx; int outlen = 0; int encLen = 0; ctx = EVP_CIPHER_CTX_new(); int dataLen = data.length(); int nPadd = AES_BLOCK_SIZE - dataLen % AES_BLOCK_SIZE; //pkcs7padding data.append(size_t(nPadd), char(nPadd)); dataLen = data.length(); unsigned char ivb[AES_BLOCK_SIZE]; memset(&ivb, '0', AES_BLOCK_SIZE); unsigned char buf[dataLen]; memset(&buf, 0, dataLen); EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, (unsigned const char *)(passwd.c_str()), ivb, 1); EVP_CipherUpdate(ctx, buf, &outlen, (unsigned const char *)(data.c_str()), dataLen); encLen = outlen; EVP_CipherFinal(ctx, buf+outlen, &outlen); encLen += outlen; EVP_CIPHER_CTX_free(ctx); auto base64Out = base64_encode(buf, encLen); return base64Out;}
#!/usr/bin/env python3## This is a simple script to encrypt a message using AES# with CBC mode in Python 3.# Before running it, you must install pycryptodome:## $ python -m pip install PyCryptodome## Author.: silverzzq# Date...: 2021-03-25##from base64 import b64decodefrom Crypto.Cipher import AESfrom Crypto.Util.Padding import pad, unpadclass AESCipher: def __init__(self, key): self.key = key.encode('utf8') def encrypt(self, data): iv = "" iv = iv.ljust(16,'0').encode('utf-8') self.cipher = AES.new(self.key, AES.MODE_CBC, iv) return b64encode(self.cipher.encrypt(pad(data.encode('utf-8'), AES.block_size))) #pad中默认的padding模式就是pkcs7paddingif __name__ == '__main__': msg = "12345678123456781234567812345678" pwd = "1234567812345678" print('Ciphertext:', AESCipher(pwd).encrypt(msg).decode('utf-8'))
转载地址:http://aktni.baihongyu.com/