⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 coderdefine.cpp

📁 这是一个基于openssl库的对文件进行加密和数字签名的软件
💻 CPP
字号:
#include "EDcode2.h"

//-------------------------------------------------------
EDcoder::EDcoder()
{
	en_sfp=NULL;
	en_ofp=NULL;
	de_sfp=NULL;
	de_ofp=NULL;
}

EDcoder::~EDcoder()
{
	if(en_sfp!=NULL)
	{
		fclose(en_sfp);
		en_sfp=NULL;
	}
	
	if(en_ofp!=NULL)
	{
		fclose(en_ofp);
		en_ofp=NULL;
	}

	if(de_sfp!=NULL)
	{
		fclose(de_sfp);
		de_sfp=NULL;
	}
	
	if(de_ofp!=NULL)
	{
		fclose(de_ofp);
		de_ofp=NULL;
	}
}

bool EDcoder::Open_en_sfp(char *filename)
{
	en_sfp=fopen(filename,"rb");
	if(en_sfp==NULL)
	    return false;
	return true;
}

bool EDcoder::Open_en_ofp(char *filename)
{
	en_ofp=fopen(filename,"wb");
	if(en_ofp==NULL)
		return false;
	return true;
}

bool EDcoder::Open_de_sfp(char *filename)
{
	de_sfp=fopen(filename,"rb");
	if(de_sfp==NULL)
	    return false;
	return true;
}

bool EDcoder::Open_de_ofp(char *filename)
{
	de_ofp=fopen(filename,"wb+rb");
	if(de_ofp==NULL)
		return false;
	return true;
}

bool EDcoder::Open_user_prikey(char *filename) // 打开用户私钥文件
{
	user_prikey=fopen(filename,"rb");
	if(user_prikey==NULL)
		return false;
	return true;
}

bool EDcoder::Open_user_pubkey(char *filename) // 打开用户公钥文件
{
	user_pubkey=fopen(filename,"rb");
	if(user_pubkey==NULL)
		return false;
	return true;
}

bool EDcoder::Open_server_prikey(char *filename) // 打开服务器私钥文件
{
	server_prikey=fopen(filename,"rb");
	if(server_prikey==NULL)
		return false;
	return true;
}

bool EDcoder::Open_server_pubkey(char *filename) // 打开服务器公钥文件
{
	server_pubkey=fopen(filename,"rb");
	if(server_pubkey==NULL)
		return false;
	return true;
}

void EDcoder::Gen_md5_sum(FILE *fp)
{
	char buf[BUFLEN];
	int read_len,total_read_len=0;
	int filelen;
	
	MD5_CTX md5_ctx;
    MD5_Init(&md5_ctx);

	fseek(fp,0,2);
	filelen=ftell(fp);

	fseek(fp,0,0);
	while(1)
	{    
	 read_len=fread(buf,1,BUFLEN,fp);
	 total_read_len+=read_len;
	 if(read_len==BUFLEN)
         MD5_Update(&md5_ctx,buf,BUFLEN);
	 else
	 {    
		 MD5_Update(&md5_ctx,buf,read_len); 
	     break;
	 }
     
    }
	MD5_Final(MD5_sum,&md5_ctx); //最终生成MD5校验码到MD5_sum

    //cout<<filelen<<endl;
	// 假如读文件长度跟文件本身长度不同就退出
	if(total_read_len!=filelen)
	{
		cout<<"MD5 校验码阶段读文件错误!"<<endl;
		cout<<filelen<<" "<<total_read_len<<endl;
		return;
	}
    
	cout<<"MD5校验码生成"<<endl;

}

void EDcoder::Print_MD5()
{
	// 打印MD5校验码
	cout<<"MD5 sum code is: "; 
	for(int i=0;i<16;i++)
	{
		cout<<hex<<(int)(MD5_sum[i]>>4);
		cout<<hex<<(int)(MD5_sum[i]%16);
	}
	cout<<endl;
}

void EDcoder::Gen_3des()
{
	/* --- 生成Des随即密钥 --- */
    if(RAND_status()!=1)
	{
		cout<<"PRNG引擎不工作了!"<<endl;
		return;
	}

	time_t t;
	srand((unsigned)time(&t));

    //_ossl_old_des_cblock key;
    //des_random_key(&key); 这个旧的东西没问题,不过这里不合适

    DES_cblock key1,key2,key3; //三重钥匙

    int result1,result2,result3;
	// 问题:三个生成的密钥一样,考虑修改随机生成器
	result1 = DES_random_key(&key1); 
    result2 = DES_random_key(&key2);
	result3 = DES_random_key(&key3);

	/*----------------------------------
	有毛病的写法:
	DES_cblock *key = NULL;
    int result = DES_random_key(key);
	不能用指针的
      ----------------------------------*/

	if(result1==0||result2==0||result3==0)
		cout<<"3DES密钥生成错误!"<<endl;
	else
        cout<<"3DES密钥生成!"<<endl;

	char *tmp_key=(char*)&key1;
	for(int i=0;i<8;i++)
		this->DES_key[i]=tmp_key[i];

	tmp_key=(char*)&key2;
	for(i=8;i<16;i++)
		this->DES_key[i]=tmp_key[i]+(rand()%20);

	tmp_key=(char*)&key3;
	for(i=16;i<24;i++)
		this->DES_key[i]=tmp_key[i]+(rand()%30);

	//DES_key[24]='\0';

    /* --- 生成Des随即密钥 --- */
}

void EDcoder::Print_3DES()
{
	cout<<"The size of 3DES key is: "<<sizeof(DES_key)<<endl;
    cout<<"The 3DES key is: "<<endl;
	for(int i=0;i<8;i++)
		cout<<dec<<(int)this->DES_key[i]<<" ";
	cout<<endl;

	for(i=8;i<16;i++)
	    cout<<dec<<(int)this->DES_key[i]<<" ";
	cout<<endl;

	for(i=16;i<24;i++)
	    cout<<dec<<(int)this->DES_key[i]<<" ";
	cout<<endl;
}

int EDcoder::Des_encrypt()
{
	EVP_CIPHER_CTX des_ctx;
    EVP_CIPHER * type;

    //unsigned char workvec[10000]; 向量好像无用
    unsigned char enc_data[2000]; // 加密后的缓冲
	unsigned char data[BUFLEN];

    long encryptedLength = 0;
    int elen=0;

    type = (EVP_CIPHER*)EVP_des_ede3_cbc();  // 初始化EVP_CIPHER结构
    EVP_CIPHER_CTX_init(&des_ctx);  // 初始化EVP_CIPHER_CTX结构

    if(EVP_CipherInit(&des_ctx, type, (unsigned char*)&DES_key, NULL, 1)==0) // 1是加密
    {
        cout<<"EVP_CipherInit error"<<endl;
        return 0;
    }

    /*add encrypted data */
	//cout<<"Begin 3DES encrypt"<<endl;
	int size_read;
	
	//unsigned char *data=new unsigned char[BUFLEN];
	//unsigned char *enc_data=new unsigned char[BUFLEN];
	fseek(en_sfp,0,0);
	do
	{    
	 size_read=fread(data,1,BUFLEN,en_sfp);
	 
	 if(size_read==0)
		 break;

     if(EVP_CipherUpdate(&des_ctx, enc_data, &elen, data, size_read)==0) // 从data读出,加密到enc_data
     {
         cout<<"EVP_CipherUpdate error"<<endl;
         return 0;
     }

	 encryptedLength += elen;

     fwrite(enc_data, 1, elen, en_ofp);    
    }while(size_read==BUFLEN);
	
    EVP_CipherFinal(&des_ctx, enc_data, &elen);
    encryptedLength += elen;
    fwrite(enc_data, 1, elen,en_ofp);
    EVP_CIPHER_CTX_cleanup(&des_ctx);


	return encryptedLength;

}

int EDcoder::Des_decrypt(int filelen)
{
	EVP_CIPHER_CTX des_ctx;
    EVP_CIPHER * type;

    //unsigned char workvec[10000]; 向量好像无用
    unsigned char dec_data[2000]; // 解密后的缓冲
	unsigned char data[BUFLEN];

    long decryptedLength = 0;
    int elen=0;

    type = (EVP_CIPHER*)EVP_des_ede3_cbc();  // 初始化EVP_CIPHER结构
    EVP_CIPHER_CTX_init(&des_ctx);  // 初始化EVP_CIPHER_CTX结构

    if(EVP_CipherInit(&des_ctx, type, DES_key, NULL, 0)==0) // 0是解密,1是加密
    {
        cout<<"EVP_CipherInit error"<<endl;
        return 0;
    }

    /*add encrypted data */
	//cout<<"Begin 3DES encrypt"<<endl;
	int size_read;
	int count=0;
	
	//unsigned char *data=new unsigned char[BUFLEN];
	//unsigned char *enc_data=new unsigned char[BUFLEN];
	
	do
	{    
	 size_read=fread(data,1,BUFLEN,de_sfp);
	 
	 if(size_read==0)
		 break;

     if(EVP_CipherUpdate(&des_ctx, dec_data, &elen, data, size_read)==0) // 从data读出,解密到enc_data
     {
         cout<<"EVP_CipherUpdate error"<<endl;
         return 0;
     }

	 decryptedLength += elen;

     fwrite(dec_data, 1, elen, de_ofp); 
    }while(size_read==BUFLEN);
	
    EVP_CipherFinal(&des_ctx, dec_data, &elen);
    decryptedLength += elen;
	//cout<<decryptedLength<<endl;
	//cout<<filelen<<endl;
    fwrite(dec_data, 1, elen,de_ofp);

    EVP_CIPHER_CTX_cleanup(&des_ctx);


	return decryptedLength;
}

void EDcoder::Gen_rsa(char *filename1,char *filename2)
{
	RSA *key=NULL;

	int e=17;
    //生成RSA密钥对
    key=RSA_generate_key(1024,RSA_F4,NULL,NULL); // RSA_F4=65537

    //保存私钥文件
    FILE *fp1= fopen(filename1,"wb"); //filename和下面的filename2都是经过验证正确的文件路径名。
    if(fp1==NULL)
    {
      cout<<"创建私钥文件错误"<<endl; // 203117.pri.key
      return;
    }

    PEM_write_RSAPrivateKey(fp1, key, NULL, NULL, 0, NULL, NULL);
    fclose(fp1);

    //保存公钥文件
    FILE *fp2= fopen(filename2,"wb");
    if(fp2==NULL)
    {
      cout<<"创建公钥文件错误"<<endl; // 203117.pub.key 
      return;
    }
    PEM_write_RSAPublicKey(fp2, key);
    fclose(fp2);
}

void EDcoder::Init_prikey(FILE *fp)
{
	pri_rsa=PEM_read_RSAPrivateKey(fp,NULL,NULL,NULL);
}

void EDcoder::Init_pubkey(FILE *fp)
{
	pub_rsa=PEM_read_RSAPublicKey(fp,NULL,NULL,NULL);
}

int EDcoder::Encrypt(char *srcfile,char *destfile)  // 总加密
{
	unsigned int filelen=0;

	// 1,读取文件,得到数据和数据长度
	if(!Open_en_sfp(srcfile))
		return 1;
	if(!Open_en_ofp(destfile))
		return 2;

	fseek(en_sfp,0,2);
	filelen=ftell(en_sfp);


	// 2,产生MD5校验码
    this->Gen_md5_sum(this->en_sfp);
    //this->Print_MD5();
	
	// 3,生成3DES密钥,加密原文放到后面
	this->Gen_3des();
	//this->Print_3DES();

	// 4,拼接3DES密钥和MD5校验码,使用用户的RSA私钥加密,得到“签名”
	//    3DES和MD5校验码总长为24+16=40 Bytes
	//    加密后的签名应该为128 Bytes
	for(int i=0;i<24;i++)
		MergeKey[i]=DES_key[i];

	for(i=0;i<16;i++)
		MergeKey[i+24]=MD5_sum[i];

	/* 输出3des和md5合成的字串
	cout<<"MergeKey is:"<<endl;
	for(i=0;i<40;i++)
	    cout<<dec<<(int)MergeKey[i]<<" ";
	cout<<endl;
	*/

	//测试:RSA *mykey=RSA_generate_key(1024,RSA_F4,NULL,NULL); // RSA_F4 is 65537
	this->Init_prikey(user_prikey);	
    int result=RSA_private_encrypt(40,MergeKey,Sign,pri_rsa,RSA_PKCS1_PADDING);
    if(result<0)
		return 3;

	/* 输出用用户私钥加密后的《签名》
	cout<<"Sign is:"<<endl;
	for(i=0;i<128;i++)
	    cout<<dec<<(int)Sign[i]<<" ";
	cout<<endl;
    */

	/* 测试能否用自己的公钥解密 */
	/*
	this->Init_pubkey("203117.pub.key");
    result=RSA_public_decrypt(RSA_size(pub_rsa),Sign,MergeKey,pub_rsa,RSA_PKCS1_PADDING);
	cout<<"pub_rsa size is "<<RSA_size(pub_rsa)<<endl;
    if(result<0)
		return 4;

	cout<<"MergeKey is:"<<endl;
	for(i=0;i<40;i++)
	    cout<<dec<<(int)MergeKey[i]<<" ";
	cout<<endl;
    测试通过 
	*/

    // 5,把签名分开2份,每份64字节,然后用服务器公钥分别加密,合并得到“加密签名”
    unsigned char tmpsign1[64],tmpsign2[64];
	unsigned char tmp_ensign1[128],tmp_ensign2[128];

	for(i=0;i<64;i++)
	{
		tmpsign1[i]=Sign[i];
		tmpsign2[i]=Sign[64+i];
	}

    this->Init_pubkey(server_pubkey);

    result=RSA_public_encrypt(64,tmpsign1,tmp_ensign1,pub_rsa,RSA_PKCS1_PADDING);
	//cout<<"step 5 result is "<<result<<endl;
    if(result<0)
		return 5;

    result=RSA_public_encrypt(64,tmpsign2,tmp_ensign2,pub_rsa,RSA_PKCS1_PADDING);
	//cout<<"step 6 result is "<<result<<endl;
    if(result<0)
		return 6;  
	
	for(i=0;i<128;i++)
		enSign[i]=tmp_ensign1[i];
	for(i=0;i<128;i++)
		enSign[i+128]=tmp_ensign2[i];

	// 6,往目标文件写入数据长度
    if(fwrite(&filelen,1,4,this->en_ofp)!=4)
		return 7;

	// 7,往目标文件写入加密签名
	if(fwrite(enSign,1,256,this->en_ofp)!=256)
		return 8;

    // 8,往目标文件写入密文
	if(this->Des_encrypt()<=0)
		return 9;

	return 0;
}

int EDcoder::Decrypt(char *srcfile,char *destfile)  // 总解密
{
	int filelen;
    int result;

    //cout<<"now is step1"<<endl;
	// 1,读取文件,得到数据长度,加密签名,密文稍后读取
	if(!Open_de_sfp(srcfile))
		return 1;
	if(!Open_de_ofp(destfile))
		return 2;

	if(fread(&filelen,1,4,this->de_sfp)!=4)
		return 3;
	//cout<<"filelen is "<<filelen<<endl;

    if(fread(this->enSign,1,256,this->de_sfp)!=256)
		return 4;
    
	//cout<<"now is step2"<<endl;
	// 2,用服务器私钥对加密签名进行解密,得到签名
    this->Init_prikey(server_prikey);
    
    unsigned char tmpsign1[64],tmpsign2[64];
	unsigned char tmp_ensign1[128],tmp_ensign2[128];

    fseek(this->de_sfp,4,0);
	fread(tmp_ensign1,1,128,this->de_sfp);
	fread(tmp_ensign2,1,128,this->de_sfp);

    result=RSA_private_decrypt(RSA_size(pri_rsa),tmp_ensign1,tmpsign1,pri_rsa,RSA_PKCS1_PADDING);
	//cout<<"pri_rsa size is "<<RSA_size(pri_rsa)<<endl;
    if(result<0)
		return 5;

	result=RSA_private_decrypt(RSA_size(pri_rsa),tmp_ensign2,tmpsign2,pri_rsa,RSA_PKCS1_PADDING);
	if(result<0)
		return 6;

    //cout<<"now is step3"<<endl;
    // 3,用用户公钥对签名进行解密,得到3DES密钥和MD5校验码拼接码
    for(int i=0;i<64;i++)
		Sign[i]=tmpsign1[i];
	for(i=64;i<128;i++)
		Sign[i]=tmpsign2[i-64];

	/*
	cout<<"Sign is:"<<endl;
	for(i=0;i<128;i++)
	    cout<<dec<<(int)Sign[i]<<" ";
	cout<<endl;
    */

    this->Init_pubkey(user_pubkey);
	result=RSA_public_decrypt(RSA_size(pub_rsa),Sign,MergeKey,pub_rsa,RSA_PKCS1_PADDING);
	//cout<<"step7 result is "<<result<<endl;
	if(result<0)
		return 7;

	/*
	cout<<"MergeKey is:"<<endl;
	for(i=0;i<40;i++)
	    cout<<dec<<(int)MergeKey[i]<<" ";
	cout<<endl;
    */

	unsigned char tmp_MD5_sum[16];
	for(i=0;i<24;i++)
		this->DES_key[i]=MergeKey[i];
	for(i=24;i<40;i++)
		tmp_MD5_sum[i-24]=MergeKey[i];
    
    //this->Print_3DES();
    /*
	cout<<"tmp_MD5_sum code is: "; 
	for(i=0;i<16;i++)
	{
		cout<<hex<<(int)(tmp_MD5_sum[i]>>4);
		cout<<hex<<(int)(tmp_MD5_sum[i]%16);
	}
	cout<<endl;
    */
    
	//cout<<"now is step4"<<endl;
	// 4,用3DES密钥解密,得到解密文
	fseek(this->de_sfp,260,0);
	result=this->Des_decrypt(filelen);
	if(result<=0)
		return 8;

    //cout<<"now is step5"<<endl;
    // 5,读取解密文,进行MD5校验
	this->Gen_md5_sum(this->de_ofp);

    //cout<<"now is step6"<<endl;
    // 6,比较tmp_MD5_sum和MD5_sum,若一样,就确定解密文为原文;若不同就删除解密文,并返回错误
	result=1;
	for(i=0;i<16;i++)
	{
		if(tmp_MD5_sum[i]!=this->MD5_sum[i])
		{
			result=0;
			break;
		}
	}

	if(result!=1)
	{
		//this->Print_MD5();
		remove(destfile);
		return 9;
	}


	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -