9.2.2 文件解密函数Decrypt_File

   函数功能:根据输入的口令对文件解密,并输出明文到指定的文件。

函数定义:

BOOL Decrypt_File(CString strCipherFilePath, CString strPlainFilePath, CString strPass)

参数说明:

q        strCipherFilePath[IN] 待解加密的文件路径

q        strPlainFilePath[IN] 解密后的明文文件保存路径

q        strPass:[IN] 解密口令

返回值:操作成功返回TRUE,否则返回FALSE

处理过程如下:

1)定义一些必要的变量,包括保存密钥的数组、保存初始化向量的数组、EVP加密上下文环境、保存密文的缓冲区、保存原文的缓冲区、加密算法、输入文件句柄、输出文件句柄等。

         unsigned char key[EVP_MAX_KEY_LENGTH];                    //保存密钥的数组

         unsigned char iv[EVP_MAX_KEY_LENGTH];                       //保存初始化向量的数组    

         EVP_CIPHER_CTX ctx;                                                             //EVP加密上下文环境

         unsigned char out[1024+EVP_MAX_KEY_LENGTH];         //保存解密后明文的缓冲区数组

         int outl;

         unsigned char in[1024];                                                            //保存密文数据的数组

         int inl;

         const EVP_CIPHER * cipher;                                                  //加密算法

         int rv;

         FILE *fpIn;                                                                                    //输入文件句柄

         FILE *fpOut;                                                                                 //输出文件句柄 

         char enchead[128]={0};                                                            //保存密文文件头的数组

         int nAlg_ID=0;                                                                             //加密算法

2)打开待解密的密文文件和保存明文的文件。

         //打开待解密的密文文件

         fpIn = fopen(strCipherFilePath.GetBuffer(0),"rb");

         if(fpIn==NULL)

         {

                   return FALSE;

         }

         //打开保存明文的文件

         fpOut = fopen(strPlainFilePath.GetBuffer(0),"wb");

         if(fpOut==NULL)

         {

                   fclose(fpIn);

                   return FALSE;

         }

3)读取密文文件头,获取加密算法。

         //读取密文文件头,获取加密算法

         fread(enchead,1,128,fpIn);

         sscanf(enchead,"ALGID:%d/n",&nAlg_ID);

4)根据算法ID获得EVP_CIPHER算法。

         //根据算法ID获得EVP_CIPHER算法

         cipher = EVP_get_cipherbynid(nAlg_ID);

5)根据口令、密码算法生成keyiv

         EVP_BytesToKey(cipher,EVP_md5(),NULL,(const unsigned char *)strPass.GetBuffer(0),strPass.GetLength(),1,key,iv);

6)初始化ctx ,设置密码算法、keyiv

         //初始化ctx

         EVP_CIPHER_CTX_init(&ctx);

         //设置解密的算法、keyiv

         rv = EVP_DecryptInit_ex(&ctx,cipher,NULL,key,iv);

7)循环读取原文,解密后后保存到明文文件。

         for(;;)

         {

                   inl = fread(in,1,1024,fpIn);

                   if(inl <= 0)

                            break;

                   rv = EVP_DecryptUpdate(&ctx,out,&outl,in,inl);//解密

                   if(rv != 1)

                   {

                            fclose(fpIn);

                            fclose(fpOut);

                            EVP_CIPHER_CTX_cleanup(&ctx);

                            return FALSE;

                   }

                   fwrite(out,1,outl,fpOut);//保存明文到文件

         }

         //解密结束

         rv = EVP_DecryptFinal_ex(&ctx,out,&outl);

         if(rv != 1)

         {

                   fclose(fpIn);

                   fclose(fpOut);

                   EVP_CIPHER_CTX_cleanup(&ctx);

                   return FALSE;

         }

         fwrite(out,1,outl,fpOut);//保存明文到文件

         fclose(fpIn);

         fclose(fpOut);

6)清除EVP加密上下文环境。

         EVP_CIPHER_CTX_cleanup(&ctx);//清除EVP加密上下文环境

处理过程如图所示:

密文文件的格式为密文文件头+密文。文件头为128字节,其格式为“ALGID:”字符串+ nAlg_ID

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值