有关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;
}
程序运行有问题。。。求修改