?? 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 + -