#include <openssl/des.h>
#include<openssl/aes.h>
#include <cstdio>
#include <string.h>
#include <openssl/evp.h>
#include<iostream>
using namespace std;
//DES_CBC加解密
void cryper(unsigned char input[], const char* key)
{
const_DES_cblock* keystring = (const_DES_cblock*)key;
DES_key_schedule key_schedule;
DES_cblock ivec;//初始化向量
memset(ivec, 0, sizeof(ivec));//这条语句是把ivec中所有字节换做字符“0”
size_t len = (sizeof(input) + 7) / 8 * 8;
unsigned char* output = (unsigned char*)malloc(len + 1);// 最少给len开辟这么多空间 加入input为1 则给len 8个字节空间,凑够一个分组
DES_set_key_unchecked(keystring, &key_schedule); //设置密钥
DES_cbc_encrypt(input, output, sizeof(input), &key_schedule, &ivec, DES_ENCRYPT); // 加密密钥:schedule;ivec: 初始化向量;(一般为8个字节0)加密:DES_ENCRYPT
cout << "加密后的密文:" << endl;// 输出加密后的结果
for (int i = 0; i < len; ++i) {
printf("%02x", output[i]);
}
cout << "解密后的明文:" << endl;
memset(ivec, 0, sizeof(ivec));
DES_cbc_encrypt(output, input, sizeof(output), &key_schedule, &ivec, DES_DECRYPT);// output输入数据 input输出数据;解密:DES_DECRYPT
cout << input<< endl;
}
//AES_CBC加密
int Encrypt_File(unsigned char key[], unsigned char iv[])
{
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); //EVP加密上下文环境
unsigned char out[1024]; //保存密文的缓冲区
int outl, count, v;
unsigned char in[1024]; //保存原文的缓冲区
FILE* data, * secret;
//打开待加密文件
fopen_s(&data,"C:/Users/lele/Desktop/周一下午/实验三/data.docx", "rb");
if (data == NULL)
{
cout << "打开源文件错误" << endl;
return -1;
}
//新建保存密文的文件
fopen_s(&secret,"C:/Users/lele/Desktop/周一下午/实验三/secret.docx", "wb");
if (secret == NULL)
{
cout << "无法创建加密文件" << endl;
fclose(data);
return -1;
}
//初始化ctx
EVP_CIPHER_CTX_init(ctx);
v = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);//指定加密算法为AES、key和iv
if (v != 1)
{
cout << "初始化错误" << endl;
return -1;
}
//读取原文,加密后后保存到密文文件。
for (;;)
{
count = fread(in, 1, 1024, data);//in为原文的缓冲区;返回值:读或写的记录数,成功时返回的记录数等于参数三
if (count <= 0)//判断原文读取结束
break;
v = EVP_EncryptUpdate(ctx, out, &outl, in, count);//加密,out为密文的缓冲区
if (v != 1)
{
cout << "加密错误" << endl;
fclose(data);
fclose(secret);
EVP_CIPHER_CTX_cleanup(ctx);
return -1;
}
fwrite(out, 1, outl, secret);//保存密文到文件
}
//加密结束
cout << "加密操作完成" << endl;
fclose(data);
fclose(secret);
EVP_CIPHER_CTX_cleanup(ctx); //清除EVP加密上下文环境
return 0;
}
//AES_CBC解密
int Decrypt_File(unsigned char key[], unsigned char iv[])
{
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); //EVP加密上下文环境
unsigned char inp[1024 + EVP_MAX_KEY_LENGTH]; //保存解密后明文的缓冲区数组
int outl, count, v;
unsigned char out[1024]; //保存密文数据的数组
FILE* secret, * data2;
//打开待解密的密文文件
fopen_s(&secret, "C:/Users/lele/Desktop/周一下午/实验三/secret.docx", "rb");
if (secret == NULL)
{
cout << "打开密文文件错误" << endl;
return -1;
}
//新建解密后的文件
fopen_s(&data2,"C:/Users/lele/Desktop/周一下午/实验三/data2.docx", "wb");
if (data2 == NULL)
{
cout << "error123!!!" << endl;
fclose(secret);
return -1;
}
//初始化ctx
EVP_CIPHER_CTX_init(ctx);
//设置解密的算法、key和iv
v = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);
if (v != 1)
{
cout << "初始化错误" << endl;
EVP_CIPHER_CTX_cleanup(ctx);
return -1;
}
//循环读取原文,解密后后保存到明文文件。
for (;;)
{
count = fread(out, 1, 1024, secret);
if (count <= 0)
break;
v = EVP_DecryptUpdate(ctx, inp, &outl, out, count);//解密
if (v != 1)
{
cout << "解密错误" << endl;
fclose(secret);
fclose(data2);
EVP_CIPHER_CTX_cleanup(ctx);
return -1;
}
fwrite(inp, 1, outl, data2);//保存明文到文件
}
//解密结束
fclose(secret);
fclose(data2);
EVP_CIPHER_CTX_cleanup(ctx);//清除EVP加密上下文环境
cout << "解密操作完成" << endl;
return 0;
}
int main(void)
{
//DES
unsigned char input[] = "I am liuyaowei";
char* key;
key = new char;
cout << "请输入密钥:" << endl;
cin >> key;
cryper(input, key);
//AES
OpenSSL_add_all_algorithms();
unsigned char key1[EVP_MAX_KEY_LENGTH]; //保存密钥的数组
unsigned char iv[EVP_MAX_KEY_LENGTH]; //保存初始化向量的数组
cout << "请输入密钥 key="; //键盘输入key
for (int i = 0; i < 24; i++)
cin >> key1[i];
for (int i = 0; i < 8; i++) //键盘输入key
iv[i] = i;
Encrypt_File(key1, iv);
Decrypt_File(key1, iv);
}
现代密码学使用三——AES-CBC模式加密word文档
最新推荐文章于 2023-02-21 14:47:33 发布