标题:有关cryptoapi加解密程序问题
只看楼主
jim0128
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2013-5-24
结帖率:0
已结贴  问题点数:20 回复次数:2 
有关cryptoapi加解密程序问题
#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 CSP
    if(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;
}


程序运行有问题。。。求修改




搜索更多相关主题的帖子: 解密 include 
2013-05-24 06:31
yuccn
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:何方
等 级:版主
威 望:167
帖 子:6809
专家分:42393
注 册:2010-12-16
得分:10 
有什么问题也的说明一下吧

我行我乐
我的博客:
http://blog.yuccn. net
2013-05-24 10:20
邓士林
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:淮河河畔
等 级:贵宾
威 望:61
帖 子:2391
专家分:13384
注 册:2013-3-3
得分:10 
呵呵,这么长,你说明下最好

Maybe
2013-05-25 16:57



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-407894-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.101462 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved