现代密码学使用三——AES-CBC模式加密word文档

1 篇文章 0 订阅
#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);
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值