📄 coderdefine.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 + -