六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 53|回复: 0

VC++2010基于windows Sdk for windows7 开发CrytoAPI应用--加密解密文件

[复制链接]

升级  11.82%

1179

主题

1179

主题

1179

主题

榜眼

Rank: 8Rank: 8

积分
3591
 楼主| 发表于 2013-2-7 03:40:16 | 显示全部楼层 |阅读模式
windows Sdk for windows7 开发CrytoAPI是微软推出的安全应用调用函数,用很小的代码就可以实现复杂的安全信息加密。下面演示文件加密解密,详情请见代码。
#include <stdio.h>#include <stdlib.h>#include <windows.h>#include "eboy_wincrypt.h"//#include <wincrypt.h>#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)#define KEYLENGTH  0x00800000#define ENCRYPT_ALGORITHM CALG_RC2 #define ENCRYPT_BLOCK_SIZE 8 void HandleError(char *s);BOOL CryEncryptFile( PCHAR szSource,  PCHAR szDestination,  PCHAR szPassword); BOOL CryDecryptFile( PCHAR szSource,  PCHAR szDestination,  PCHAR szPassword); //加密文件例子void jiami(){PCHAR szSource;     PCHAR szDestination;     PCHAR szPassword;     char  response;if(!(szSource=(char *)malloc(100)))HandleError("malloc 失败.");if(!(szDestination=(char *)malloc(100)))HandleError("malloc 失败.");if(!(szPassword=(char *)malloc(100)))HandleError("malloc 失败.");printf("文件加密. \n\n");printf("请输入待加密的文件: ");scanf("%s",szSource);printf("请输入保存密文的文件: ");scanf("%s",szDestination);printf("使用口令加密文件吗? ( y/n ) ");getchar();scanf("%c",&response);if(response == 'y'){printf("请输入口令:");scanf("%s",szPassword);}else{printf("不使用口令,则使用随机数作为密钥。 \n");free(szPassword);szPassword = NULL;}//--------------------------------------------------------------------// 调用EncryptFile函数完成加密。if(CryEncryptFile(szSource, szDestination, szPassword)){printf("加密文件%s 成功. \n", szSource);printf("密文文件为 %s.\n",szDestination);}else{HandleError("加密文件失败!"); } }//解密文件例子void jiemi(){PCHAR szSource; PCHAR szDestination; PCHAR szPassword; char  response;if(!(szSource=(char *)malloc(100)))HandleError("malloc 失败.");if(!(szDestination=(char *)malloc(100)))HandleError("malloc 失败.");if(!(szPassword=(char *)malloc(100)))HandleError("malloc 失败.");printf("文件解密. \n\n");printf("输入待解密的文件名: ");scanf("%s",szSource);printf("输入明文保存文件名: ");scanf("%s",szDestination);printf("是否使用口令加密的文件? ( y/n ) ");getchar();scanf("%c",&response);if(response == 'y'){printf("输入口令:");scanf("%s",szPassword);}else{printf("没有使用口令加密,加密密钥以密文的形式保存在文件中。\n");free(szPassword);szPassword = NULL;}if(!CryDecryptFile(szSource, szDestination, szPassword)){printf("\n解密文件失败. \n"); }else{ printf("\n解密文件%s 成功 \n", szSource);printf("解密后的文件保存为 %s .\n",szDestination);}}/************************************************************************函数功能:加密文件                                                             参数:szSource:[IN],待加密的明文文件路径szDestination:[IN] 加密后的密文文件路径szPassword:[IN] 口令************************************************************************/static BOOL CryEncryptFile(        PCHAR szSource,         PCHAR szDestination,         PCHAR szPassword){//变量声明FILE *hSource;//待加密的明文文件句柄FILE *hDestination; //密文文件句柄HCRYPTPROV hCryptProv; //CSP句柄HCRYPTKEY hKey;//密钥句柄HCRYPTKEY hXchgKey;//交换密钥句柄HCRYPTHASH hHash;//摘要句柄PBYTE pbKeyBlob;DWORD dwKeyBlobLen; PBYTE pbBuffer; DWORD dwBlockLen; DWORD dwBufferLen; DWORD dwCount;  //--------------------------------------------------------------------// 打开原文件 if(hSource = fopen(szSource,"rb")){   printf("打开明文文件 %s,成功. \n", szSource);}else{    HandleError("打开明文文件出错");} //--------------------------------------------------------------------// 打开密文文件. if(hDestination = fopen(szDestination,"wb")){ printf("打开密文文件 %s,成功. \n", szDestination);}else{HandleError("打开密文文件出错");}//打开 MS_ENHANCED_PROV CSPif(CryptAcquireContext(  &hCryptProv,   NULL,   MS_ENHANCED_PROV,   PROV_RSA_FULL,   0)){   printf("打开CSP成功 \n");}else{   HandleError("调用 CryptAcquireContext 出错!"); }//--------------------------------------------------------------------//   创建会话密钥if(!szPassword ) //密码为空,那么使用随机数作为会话密钥来加密文件{  //--------------------------------------------------------------- // 产生一个随机的密钥.  if(CryptGenKey(  hCryptProv,   ENCRYPT_ALGORITHM,   KEYLENGTH | CRYPT_EXPORTABLE,   &hKey))  {  printf("创建会话密钥成功. \n");  }   else  {  HandleError("调用 CryptGenKey 出错!");   } //---------------------------------------------------------------  // 获得加密者的交换密钥(加密密钥)即容器对应的公钥 if(CryptGetUserKey(   hCryptProv,    AT_KEYEXCHANGE,    &hXchgKey))  {printf("获得用户公钥成功.\n");   }   else   {  HandleError("调用 CryptGetUserKey 出错,可能用户公钥不存在!");    } //--------------------------------------------------------------- // 导出会话密钥hKey,使用交换密钥hXchgKey加密。第一次调用只得到BLOB长度。 if(CryptExportKey(   hKey,    hXchgKey,    SIMPLEBLOB,    0,    NULL,    &dwKeyBlobLen))  {   printf("导出的密钥长度为%d字节. \n",dwKeyBlobLen);   }   else   {  HandleError("调用 CryptExportKey 出错!");    }   //分配内存   if(pbKeyBlob =(BYTE *)malloc(dwKeyBlobLen))   {   ;   }   else   {   HandleError("内存不够了. \n");    } //---------------------------------------------------------------// 导出会话密钥hKey,使用交换密钥hXchgKey加密 if(CryptExportKey(  hKey,   hXchgKey,   SIMPLEBLOB,   0,   pbKeyBlob,   &dwKeyBlobLen))   {   printf("导出密钥成功 \n");   }    else   {   HandleError("调用 CryptExportKey 出错!");    }  //--------------------------------------------------------------- // 释放交换密钥句柄 CryptDestroyKey(hXchgKey);  hXchgKey = 0;   //--------------------------------------------------------------- // 把密文会话密钥的长度写入目标文件  fwrite(&dwKeyBlobLen, sizeof(DWORD), 1, hDestination);  if(ferror(hDestination)) {  HandleError("写文件头失败"); } else { ; } //--------------------------------------------------------------  // 把密文会话密钥写入目标文件      fwrite(pbKeyBlob, 1, dwKeyBlobLen, hDestination);  if(ferror(hDestination)) {  HandleError("写文件头失败"); } else {printf("密文的会话密钥已经写入到文件。\n"); }} else //输入了口令,那么使用此口令派生出会话密钥来加密文件{ //创建摘要句柄if(CryptCreateHash(   hCryptProv,    CALG_MD5,    0,    0,    &hHash)){printf("创建哈希句柄成功. \n");}else{  HandleError("调用 CryptCreateHash 出错!"); }  //--------------------------------------------------------------------// 对口令进行摘要运算if(CryptHashData(   hHash,    (BYTE *)szPassword,    strlen(szPassword),    0)) {printf("口令已经被哈希. \n"); } else {HandleError("调用 CryptHashData 出错!");  }//--------------------------------------------------------------------// 从哈希对象中派生出会话密钥if(CryptDeriveKey(   hCryptProv,    ENCRYPT_ALGORITHM,    hHash,    KEYLENGTH,    &hKey)) {   printf("从哈希对象中派生出会话密钥成功。 \n");  } else {HandleError("调用 CryptDeriveKey 出错!");  }//--------------------------------------------------------------------//销毁哈希对象CryptDestroyHash(hHash); hHash = 0; } //--------------------------------------------------------------------//现在加密文件的会话密钥已经准备好了。dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE; if(ENCRYPT_BLOCK_SIZE > 1) dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE; else dwBufferLen = dwBlockLen;   if(pbBuffer = (BYTE *)malloc(dwBufferLen)){;}else{ HandleError("内存不够了. \n"); }//--------------------------------------------------------------------// 不断循环加密原文件,把密文写入的密文文件do { //--------------------------------------------------------------------// 读取原文dwBlockLen字节dwCount = fread(pbBuffer, 1, dwBlockLen, hSource); if(ferror(hSource)){ HandleError("读取原文错误。\n");} //--------------------------------------------------------------------// 加密数据if(!CryptEncrypt( hKey,  0,  feof(hSource),  0,  pbBuffer,  &dwCount,  dwBufferLen)){    HandleError("调用 CryptEncrypt 出错. \n"); } //--------------------------------------------------------------------// 把密文写入的密文文件fwrite(pbBuffer, 1, dwCount, hDestination); if(ferror(hDestination)){ HandleError("写文件失败");}} while(!feof(hSource)); //--------------------------------------------------------------------//关闭文件句柄if(hSource) fclose(hSource); if(hDestination) fclose(hDestination); //--------------------------------------------------------------------// 释放内存if(pbBuffer)  free(pbBuffer);  //--------------------------------------------------------------------// 销毁会话密钥if(hKey) CryptDestroyKey(hKey); //--------------------------------------------------------------------// 释放交换密钥if(hXchgKey) CryptDestroyKey(hXchgKey);  //--------------------------------------------------------------------// 销毁哈希对象if(hHash) CryptDestroyHash(hHash);  //--------------------------------------------------------------------// 释放CSP句柄if(hCryptProv) CryptReleaseContext(hCryptProv, 0);return(TRUE); } // End of Encryptfile/************************************************************************函数功能:解密文件                                                             参数:szSource:[IN],待解密的密文文件路径szDestination:[IN] 加密后的明文文件路径szPassword:[IN] 口令************************************************************************/static BOOL CryDecryptFile(     PCHAR szSource,      PCHAR szDestination,      PCHAR szPassword) { //--------------------------------------------------------------------//   声明变量FILE *hSource;//解密的密文文件句柄FILE *hDestination;//明文文件句柄HCRYPTPROV hCryptProv; //CSP句柄HCRYPTKEY hKey;//密钥句柄HCRYPTHASH hHash;//摘要句柄PBYTE pbKeyBlob = NULL; DWORD dwKeyBlobLen; PBYTE pbBuffer; DWORD dwBlockLen; DWORD dwBufferLen; DWORD dwCount; BOOL status = FALSE;  //--------------------------------------------------------------------// 打开密文文件if(!(hSource = fopen(szSource,"rb"))) {   HandleError("打开密文文件失败 !");}//--------------------------------------------------------------------// 打开目标文件即解密后的明文文件if(!(hDestination = fopen(szDestination,"wb"))){HandleError("打开明文文件失败 !");} //--------------------------------------------------------------------// 获得CSP句柄if(!CryptAcquireContext(  &hCryptProv,   NULL,   MS_ENHANCED_PROV,   PROV_RSA_FULL,   0)){   HandleError("调用 CryptAcquireContext 函数出错 !"); }//--------------------------------------------------------------------//  检查szPassword是否为空if(!szPassword) //szPassword为空{ //--------------------------------------------------------------------// 使用保存在文件中的加密密钥解密 //从密文文件中读取密钥  fread(&dwKeyBlobLen, sizeof(DWORD), 1, hSource); if(ferror(hSource) || feof(hSource)){HandleError("读文件头失败!"); }if(!(pbKeyBlob = (BYTE *)malloc(dwKeyBlobLen))){HandleError("申请内存失败!."); }fread(pbKeyBlob, 1, dwKeyBlobLen, hSource); if(ferror(hSource) || feof(hSource)){HandleError("读文件头失败!"); }//--------------------------------------------------------------------// 导入密钥到CSP,使用私钥解密会话密钥,产生hKey。if(!CryptImportKey(  hCryptProv,   pbKeyBlob,   dwKeyBlobLen,   0,   0,   &hKey)){   HandleError("调用 CryptImportKey 函数出错 !"); }} else //口令非空,口令派生出的会话密钥解密文件{ //--------------------------------------------------------------------// 创建哈希对象if(!CryptCreateHash(   hCryptProv,    CALG_MD5,    0,    0,    &hHash)){HandleError("调用 CryptCreateHash 函数出错 !"); }//--------------------------------------------------------------------// 哈希口令if(!CryptHashData(   hHash,    (BYTE *)szPassword,    strlen(szPassword),    0)) {HandleError("调用 CryptHashData 函数出错 !"); }//--------------------------------------------------------------------// 从哈希对象中派生出会话密钥if(!CryptDeriveKey(  hCryptProv,   ENCRYPT_ALGORITHM,   hHash,   KEYLENGTH,   &hKey)){    HandleError("调用 CryptDeriveKey 函数出错 !"); }//--------------------------------------------------------------------// 销毁哈希对象CryptDestroyHash(hHash); hHash = 0; } //--------------------------------------------------------------------//现在已经获得了解密数据的会话密钥。dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE; dwBufferLen = dwBlockLen; if(!(pbBuffer = (BYTE *)malloc(dwBufferLen))){   HandleError("Out of memory!\n"); }//--------------------------------------------------------------------// 解密密文,并把明文写到明文文件中。do { //--------------------------------------------------------------------// 循环读取密文dwCount = fread( pbBuffer,  1,  dwBlockLen,  hSource); if(ferror(hSource)){HandleError("读取密文失败!");}//--------------------------------------------------------------------// 数据解密if(!CryptDecrypt(  hKey,   0,   feof(hSource),   0,   pbBuffer,   &dwCount)){   HandleError("CryptDecrypt解密失败!"); }//--------------------------------------------------------------------// 写明文数据到文件fwrite(pbBuffer, 1, dwCount, hDestination); if(ferror(hDestination)){   HandleError("写文件失败!"); }} while(!feof(hSource)); status = TRUE; //--------------------------------------------------------------------// 关闭文件if(hSource)    fclose(hSource); if(hDestination) fclose(hDestination);  //--------------------------------------------------------------------// 释放内存if(pbKeyBlob)  free(pbKeyBlob);if(pbBuffer)  free(pbBuffer);  //--------------------------------------------------------------------// 销毁会话密钥if(hKey) CryptDestroyKey(hKey); //--------------------------------------------------------------------// 销毁哈希对象if(hHash) CryptDestroyHash(hHash); //--------------------------------------------------------------------// 释放CSP句柄if(hCryptProv) CryptReleaseContext(hCryptProv, 0); return status;} // End of Decryptfile//出错处理函数void HandleError(char *s){    printf("本程序在运行时有错误发生.\n");    printf("%s\n",s);    printf("错误码: %x\n.",GetLastError());    printf("程序退出.\n");    exit(1);}int main(int argc, char* argv[]){jiami();jiemi();return 0;}
本文作者专著《Visual C++2010开发权威指南》即将推出,敬请关注,Visual C++2010最近技术,Windows7开发最新技术!
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表