使用openssl开源AES算法,实现aes、aes-cbc和aes-ecb对字符串的加解密

注意事项

  • 对于用户输入的密码进行了md5运算,从而保证数据格式的统一性

  • 内部调用的随机函数,参考我的其他博文 参考链接

头文件crypto_util.h

#pragma once#include <string>namespace hsm{namespace mgmt{void get_md5_digest(const std::string &data,uint8_t result[16]);std::string aes_encrypt_to_string(const std::string &string,const std::string &password);std::string aes_decrypt_from_string(const std::string &string,const std::string &password);std::string aes_ecb_encrypt_to_string(const std::string &string,const std::string &password);std::string aes_ecb_decrypt_from_string(const std::string &string,const std::string &password);std::string aes_cbc_encrypt_to_string(const std::string &string,const std::string &password);std::string aes_cbc_decrypt_from_string(const std::string &string,const std::string &password);}//namespace mgmt
}//namespace hsm

源文件crypto_util.cpp

#include "../util/crypto_util.h"#include <cstring>
#include <memory>#include <openssl/aes.h>
#include <openssl/md5.h>namespace hsm{namespace mgmt{void get_md5_digest(const std::string &data,uint8_t result[16]){MD5_CTX md5_ctx{};MD5_Init(&md5_ctx);MD5_Update(&md5_ctx,data.c_str(),data.length());MD5_Final(result,&md5_ctx);}
/*** @brief generate a valid aes key from input password** @note AES only support keys with length 128/192/256bits* @note this implementation use md5 as a method to fix the password*/std::unique_ptr<AES_KEY> get_aes_key(const std::string &password,int flag){auto aes_key = std::make_unique<AES_KEY>();uint8_t data[16]{};get_md5_digest(password,data);if (flag == AES_ENCRYPT){AES_set_encrypt_key(data,sizeof(data)*8,aes_key.get());} else if (flag == AES_DECRYPT){AES_set_decrypt_key(data,sizeof(data)*8,aes_key.get());}return aes_key;}std::string aes_encrypt_to_string(const std::string &data,const std::string &password){auto aes_key = get_aes_key(password,AES_ENCRYPT);std::string result(data.length(),'0');auto input_offset = reinterpret_cast<const uint8_t *>(data.c_str());auto output_offset = reinterpret_cast<uint8_t *>(&result[0]);//encrypt blocksfor (size_t i = 0; i < data.length() / AES_BLOCK_SIZE ; ++i) {AES_encrypt(input_offset,output_offset,aes_key.get());input_offset += AES_BLOCK_SIZE;output_offset += AES_BLOCK_SIZE;}//write rest od data to fileauto rest_input_length = data.length() % AES_BLOCK_SIZE;if (rest_input_length > 0 ){std::memcpy(output_offset,input_offset,rest_input_length + 1);}return result;}std::string aes_decrypt_from_string(const std::string &enc_data,const std::string &password){auto aes_key = get_aes_key(password,AES_DECRYPT);std::string result(enc_data.length(),'0');auto input_offset = reinterpret_cast<const uint8_t *>(enc_data.c_str());auto output_offset = reinterpret_cast<uint8_t *>(&result[0]);//decrypt blocksfor (size_t i = 0;i < enc_data.length() / AES_BLOCK_SIZE;i++){AES_decrypt(input_offset,output_offset,aes_key.get());input_offset += AES_BLOCK_SIZE;output_offset += AES_BLOCK_SIZE;}//decrypt rest of dataauto rest_input_length = enc_data.length() % AES_BLOCK_SIZE;if (rest_input_length > 0 ){std::memcpy(output_offset,input_offset,rest_input_length + 1);}return result;}//aes-ecbstd::string aes_ecb_encrypt_to_string(const std::string &data,const std::string &password){auto aes_key = get_aes_key(password,AES_ENCRYPT);std::string result(data.length(),'0');auto input_offset = reinterpret_cast<const uint8_t *>(data.c_str());auto output_offset = reinterpret_cast<uint8_t *>(&result[0]);//encrypt blocksfor (size_t i = 0; i < data.length() / AES_BLOCK_SIZE ; ++i) {AES_ecb_encrypt(input_offset,output_offset,aes_key.get(),AES_ENCRYPT);input_offset += AES_BLOCK_SIZE;output_offset += AES_BLOCK_SIZE;}//write rest od data to fileauto rest_input_length = data.length() % AES_BLOCK_SIZE;if (rest_input_length > 0 ){std::memcpy(output_offset,input_offset,rest_input_length + 1);}return result;}std::string aes_ecb_decrypt_from_string(const std::string &enc_data,const std::string &password){auto aes_key = get_aes_key(password,AES_DECRYPT);std::string result(enc_data.length(),'0');auto input_offset = reinterpret_cast<const uint8_t *>(enc_data.c_str());auto output_offset = reinterpret_cast<uint8_t *>(&result[0]);//decrypt blocksfor (size_t i = 0;i < enc_data.length() / AES_BLOCK_SIZE;i++){AES_ecb_encrypt(input_offset,output_offset,aes_key.get(),AES_DECRYPT);input_offset += AES_BLOCK_SIZE;output_offset += AES_BLOCK_SIZE;}//decrypt rest of dataauto rest_input_length = enc_data.length() % AES_BLOCK_SIZE;if (rest_input_length > 0 ){std::memcpy(output_offset,input_offset,rest_input_length + 1);}return result;}//aes-cbcstd::string aes_cbc_encrypt_to_string(const std::string &data,const std::string &password){unsigned char buffer[AES_BLOCK_SIZE] = {0};auto aes_key = get_aes_key(password,AES_ENCRYPT);std::string result(data.length(),'0');auto input_offset = reinterpret_cast<const uint8_t *>(data.c_str());auto output_offset = reinterpret_cast<uint8_t *>(&result[0]);//encrypt blocksfor (size_t i = 0;i < 16;i++){buffer[i] += 1;}AES_cbc_encrypt(input_offset,output_offset,data.length(),aes_key.get(),buffer,AES_ENCRYPT);return result;}std::string aes_cbc_decrypt_from_string(const std::string &enc_data,const std::string &password){unsigned char buffer[AES_BLOCK_SIZE] = {0};auto aes_key = get_aes_key(password,AES_DECRYPT);std::string result(enc_data.length(),'0');auto input_offset = reinterpret_cast<const uint8_t *>(enc_data.c_str());auto output_offset = reinterpret_cast<uint8_t *>(&result[0]);for (size_t i = 0;i < 16;i++){buffer[i] += 1;}AES_cbc_encrypt(input_offset,output_offset,enc_data.length(),aes_key.get(),buffer,AES_DECRYPT);return result;}}//namespace mgmt
}//namespace hsm

调用代码

#include <iostream>
#include <bitset>#include "util/crypto_util.h"
#include "include/random.h"int main() {std::string str;GenerateRandom(&str,32);std::cout << "GenerateRandom:" << str << "\n";//Test crypto_util md5
//    std::string str = "1qaz2wsx3edc4rfv5tgb6yhn7ujm8ik9";std::string password = "123456qweasdzxcv";//Test aes_cbcstd::string enc_string_cbc{};std::string dec_string_cbc{};enc_string_cbc = hsm::mgmt::aes_cbc_encrypt_to_string(str,password);std::cout << "enc_string_cbc enc:" <<enc_string_cbc << std::endl;dec_string_cbc = hsm::mgmt::aes_cbc_decrypt_from_string(enc_string_cbc,password);std::cout <<  "enc_string_cbc dec:" << dec_string_cbc << std::endl;std::cout << std::endl;//Test aes_ecbstd::string enc_string_ecb{};std::string dec_string_ecb{};enc_string_ecb = hsm::mgmt::aes_ecb_encrypt_to_string(str,password);std::cout << "enc_string_ecb enc:" <<enc_string_ecb << std::endl;dec_string_ecb = hsm::mgmt::aes_ecb_decrypt_from_string(enc_string_ecb,password);std::cout <<  "enc_string_ecb dec:" << dec_string_ecb << std::endl;std::cout << std::endl;//Test aes_stringstd::string enc_string{};std::string dec_string{};enc_string = hsm::mgmt::aes_encrypt_to_string(str,password);std::cout << "enc_string_aes enc:" <<enc_string << std::endl;dec_string = hsm::mgmt::aes_decrypt_from_string(enc_string_ecb,password);std::cout <<  "enc_string_aes dec:" << dec_string << std::endl;std::cout << std::endl;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/446915.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android学习指南

目录核心分析内容1、学什么1.1、Android基础 & 常用1.2、Android进阶1.3、与时俱进、热门技术1.4、编程语言&#xff1a;Java与Java虚拟机1.5、计算机基础1.6、总结2、怎么学2.1、学习路径&#xff1a;如何循序渐进、阶段性的学习Android的理论知识&#xff1f;2.2、获取途…

使用memcmp函数判断两个函数的前n位字节数是否相等

memcmp函数的介绍 头文件&#xff1a;#include <string.h>定义函数&#xff1a;int memcmp (const void *s1, const void *s2, size_t n);函数说明&#xff1a;memcmp()用来比较s1 和s2 所指的内存区间前n 个字符。字符串大小的比较是以ASCII 码表上的顺序来决定&#x…

java 选择排序

选择排序–时间复杂度n^2 第一次从arr[0]–arr[n-1]中选出最小值,与arr[0]交换 第二次从arr[1]–arr[n-1]中选出最小值,与arr[1]交换… 最小数:假定当前这个数是最小数,然后和后面的每个数进行比较,当发现有更小的数时,重定最小数与最小数的下标 总结: 选择排序一共有数组大…

Linux环境下实现unsigned char*向string的转换

代码 unsigned char input_data[input_data_length] {"This is my first encrypted plaintext hello world"}; openssl_enc_string hsm::mgmt::aes_ecb_encrypt_to_string(static_cast<string>((const char * )input_data),password);使用static_cast<st…

概率论 事件关系 古典概型与几何概型

基本知识点 随机试验:1.不确定性2.可预知性3.可重复性基本事件:包含一个样本点 必然事件:全集 不可能事件:空集 子集2^n-1-1(减去空集与真集) 事件间的关系 1.包含关系 2.和运算AUBAB,A与B至少有一个发生 3.积事件A∩BAB,AB同时发生 4.差事件A-BAB ̅A-AB,A发生但B不发生 5.…

Android代码命名规范

目录目录1、为什么 规范 Android 代码命名&#xff1f;2、Android需要命名的代码&#xff08;对象&#xff09;有哪些&#xff1f;3、具体命名规范3.1、包3.2、类3.3、变量3.4、方法3.5、参数名3.6、资源3.6.1、布局文件资源3.6.2、图片资源3.6.3、参数值资源3.6.4、动画资源3.…

安卓牛客专项练习2020.12.10

安卓Activity活动 Android的Activity活动中&#xff0c;我们一般可以归结为四种状态: 1.运行状态Running 2.暂停状态Paused 3.停止状态Stopped 4.销毁状态Destroyed 动画Animation 1.补间动画TWeen Animation 其中包括: 平移Translate Animation 透明Alpha Animation 旋转Ro…

将结构体数据存储到一段字符串string中

核心思想 指定一段内存空间存储结构体数据&#xff0c;然后使用一个指针强制类型转化为结构体类型的&#xff0c;就可以使用这个指针操作结构体相关的成员函数和变量结构体内存只会为定义的变量进行分配内存空间&#xff0c;函数只进行调用&#xff0c;不占据空间 结构体 void…

Idea中搭建Resin运行环境(Mac)

一、背景 idea中搭建Resin运行环境&#xff0c;可以在idea中通过点击Run按钮直接调试应用。 二、Resin下载地址 下载地址&#xff1a;https://caucho.com/products/resin/download/gpl#download 我下载的是tar.gz的&#xff0c;通过tar -zxvf命令解压到自己mac的任意目录下…

Java牛客专项练习2020.12.10

TreeSet subset()方法: subset(from,true,to,true),返回从from元素到to元素的一个集合,true判断是否包含边境元素 Java与C Java与C都有三个特征: 封装,继承,多态 抽象类与接口 1.抽象类可以有构造方法,但不能new;接口没有构造方法 2.抽象类中可以有普通成员变量int x等,接…

Idea中搭建Wildfly(JBoss)运行环境(Mac)

目录一、简介二、下载Wildfly&#xff08;JBoss&#xff09;三、配置Idea四、调试一、简介 首先说一下在linux环境&#xff0c;只需要将war包上传到 wildfly-8.2.0.Final/standalone/deployments 目录&#xff0c;然后到 wildfly-8.2.0.Final/bin 目录下 ./standalone.sh&…

启动linux的rpc服务的命令

命令 sudo service rc-local status

java插入排序

插入排序 思路: 把集合分成有序表与无序表,最开始有序表只有一个元素,无序表有n-1个元素,排序过程中每次取出无序表的第一个元素,然后与有序表中的元素比较,插入到适当位置 小结: 1.一共要进行n-1次排序循环 排序过程 排序前--- [101, 34, 119, 1] 第1轮插入后--- [34, 101,…

一个简单JavaAgent的实现

一、什么是javaagent javaagent是一个JVM“插件”&#xff0c;一种专门精心制作的.jar文件&#xff0c;它能够利用JVM提供的Instrumentation API。 1.1、概要 Java Agent由三部分组成&#xff1a;代理类、代理类元信息和JVM加载.jar和代理的机制&#xff0c;整体内容如下图所…

Openai的openai新版本调用方式

最近大家有没有发现Openai的openai已经更新到1.6.1了,而且API的调用方式发生了巨大的变化,下面来看看openai新的调用方式吧。 欢迎关注公众号 module ‘openai’ has no attribute ChatCompletion. 提示openai的版本过低。(pip install -U openai) 1. Chat API from openai…

计算机系统基础 计算机系统的基本组成与基本功能

基础知识点 1.1946年第一台通用电子计算机ENIAC诞生 2.冯.诺依曼结构: 组成:输入设备,输出设备,存储器,运算器,控制器 3.现代计算机结构模型: 组成 CPU中央处理器 PC程序计数器 IR指令寄存器 ALU算数逻辑部件 GPRs通用寄存器组 MAR存储器地址寄存器 MDR存储器数据寄存器 知…

Android UI卡顿监控

一、背景 应用的使用流畅度&#xff0c;是衡量用户体验的重要标准之一。Android 由于机型配置和系统的不同&#xff0c;项目复杂App场景丰富&#xff0c;代码多人参与迭代历史较久&#xff0c;代码可能会存在很多UI线程耗时的操作&#xff0c;实际测试时候也会偶尔发现某些业务…

linux查看内核版本信息

使用命令 uname -acat /proc/version

C语言学习:snprintf()函数

函数原型&#xff1a; int snprintf(char* dest_str,size_t size,const char* format,...);函数功能&#xff1a; 先将可变参数 “...” 按照format的格式格式化为字符串&#xff0c;然后再将其拷贝至dest_str中。 头文件&#xff1a; #include<stdio.h>注意事项&…