openssl evp 对称加密(AES_ecb,ccb)
evp.h 封装了openssl常用密码学工具,以下主要说对称加密的接口
enc_dec.cpp
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <openssl/evp.h>
using namespace std;
/**
* @brief
*
* @param isStr [in] 明文数据 [in]
* @param inlen [in] 文件长度
* @param key [in]
* @param encData [out] 密文数据
* @param file_name [in] 文件名,将密文保存到文件
*
* @return
*/
int encrypt_data(const char* isStr , uint32_t inlen, const string& key, string &encData, const string file_name)
{
EVP_CIPHER_CTX ctx;
do {
encData.resize(inlen + EVP_MAX_BLOCK_LENGTH);
unsigned char iv[] = "encdec";
int enclen = 0;
int outlen = 0;
unsigned char* outbuf = (unsigned char*)encData.data();
EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit_ex(&ctx, EVP_rc4(), NULL, NULL, NULL, 1);
EVP_CIPHER_CTX_set_key_length(&ctx, key.size());
EVP_CipherInit_ex(&ctx, NULL, NULL, (unsigned char*)key.data(), iv, 1);
if (!EVP_CipherUpdate(&ctx, outbuf, &outlen, (const unsigned char*)isStr, inlen)) {
return -1;
}
enclen = outlen;
if (!EVP_CipherFinal_ex(&ctx, outbuf+outlen, &outlen)) {
return -1;
}
enclen += outlen;
encData.resize(enclen);
FILE *file = fopen(file_name.c_str(), "wb+");
if (file) {
fwrite(encData.data(), 1, enclen, file);
fclose(file);
}
} while (0);
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
/**
* @brief
*
* @param encData [in] 密文
* @param enclen [in] 密文长度
* @param key [in]
* @param decData [out] 明文
*
* @return
*/
int decrypt_data(const char* encData , uint32_t enclen, const string& key, string &decData )
{
EVP_CIPHER_CTX ctx;
do {
decData.resize(enclen + EVP_MAX_BLOCK_LENGTH);
unsigned char iv[] = "encdec";
int outlen = 0;
int declen = 0;
unsigned char* outbuf = (unsigned char*)decData.data();
EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit_ex(&ctx, EVP_rc4(), NULL, NULL, NULL, 0);
EVP_CIPHER_CTX_set_key_length(&ctx, key.size());
EVP_CipherInit_ex(&ctx, NULL, NULL, (unsigned char*)key.data(), iv, 0);
if (!EVP_CipherUpdate(&ctx, outbuf, &outlen, (const unsigned char*)encData, enclen)) {
return -1;
}
declen = outlen;
outlen = 0;
if (!EVP_CipherFinal_ex(&ctx, outbuf + declen, &outlen)) {
return -1;
}
declen += outlen;
decData.resize(declen);
} while (0);
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
int main(int argc, char** argv)
{
if(argc<3){
std::cout<<"enc_tool <1/0> <intput_file> <output_enc_file_name>"<<std::endl;
exit(-1);
}
int enc_flag = atoi(argv[1]);
string key = "123";
if(enc_flag){
//enc
string file_name = argv[2];
FILE *fin = fopen(file_name.c_str(), "rb");
fseek(fin, 0, SEEK_END);//tail
uint32_t DataLen = ftell(fin);
fseek(fin, 0, SEEK_SET);//head
char* file_buff = (char*)malloc(sizeof(char)*DataLen);
fread(file_buff, sizeof(char), DataLen, fin);
string encData;
string out_file_name;
if(argc<4){
out_file_name = "enc_result.txt";
}else{
out_file_name = argv[3];
}
encrypt_data(file_buff, DataLen, key, encData, out_file_name);
free(file_buff);
fclose(fin);
}else{
//dec
string file_name = argv[2];
FILE *fp = fopen(file_name.c_str(), "rb");
fseek(fp, 0, SEEK_END);//tail
int encDataLen = ftell(fp);
fseek(fp, 0, SEEK_SET);//head
char* buff = (char*)malloc(sizeof(char) * encDataLen);
fread(buff, sizeof(char), encDataLen, fp);
string dec_data;
decrypt_data(buff, encDataLen, key, dec_data);
std::cerr<<"dec_data is "<<dec_data;
fclose(fp);
free(buff);
}
}
大致流程
-
EVP_CipherInit_ex 初始化加密使用的key,iv,算法模式,最后 一个参数,1表示加密,0表示解密
-
EVP_CipherUpdate 加密解密处理
-
EVP_CipherFinal_ex 获取结果
Makefile
OBJ = run
CC = g++
FLAGS = --std=c++11
INC = -I ./
LIBS = -L -lssl -lcrypto
all:
$(CC) $(FLAGS) enc_dec.cpp -o $(OBJ) $(INC) $(LIBS)
clean:
rm -rf $(OBJ)
加密:
./run 1 test.txt
解密:
./run 0 enc_result.txt