博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c++ python 实现AES加密 基于openssl
阅读量:4080 次
发布时间:2019-05-25

本文共 5342 字,大约阅读时间需要 17 分钟。

c++ python 实现AES加密 基于openssl

前序

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代表解密;*/

C++代码

可以使用#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加密框架

好吧,等我试了几次死磕出了加密方法之后,小伙伴突然说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;}

python验证代码

#!/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/

你可能感兴趣的文章
FTP 常见问题
查看>>
zookeeper单机集群安装
查看>>
do_generic_file_read()函数
查看>>
Python学习笔记之数据类型
查看>>
Python学习笔记之特点
查看>>
shell 快捷键
查看>>
VIM滚屏操作
查看>>
EMC 2014存储布局及十大新技术要点
查看>>
linux内核内存管理(zone_dma zone_normal zone_highmem)
查看>>
将file文件内容转成字符串
查看>>
循环队列---数据结构和算法
查看>>
优先级队列-数据结构和算法
查看>>
链接点--数据结构和算法
查看>>
servlet中请求转发(forword)与重定向(sendredirect)的区别
查看>>
Spring4的IoC和DI的区别
查看>>
springcloud 的eureka服务注册demo
查看>>
eureka-client.properties文件配置
查看>>
MODULE_DEVICE_TABLE的理解
查看>>
platform_device与platform_driver
查看>>
platform_driver平台驱动注册和注销过程(下)
查看>>