调用CryptoApi接口实现数据的加解密,代码如下:
//本程序通过调用CSP实现文件AES_128加解密功能
#include "stdafx.h"
#include <windows.h>
#include <wincrypt.h>
#define BLOCK_SIZE 1024
/*****************************************************
*函数名:EncryptFile
*功 能:加密文件
*入 参:PCHAR szSource, 待加密的文件名
PCHAR szDestination, 加密后的文件名
PCHAR passwd); 加密口令
*出 参:无
*返回值:BOOL,TRU为加密成功,FALSE为加密失败
******************************************************/
BOOL EncryptFile(PCHAR szSource,
PCHAR szDestination,
PCHAR passwd);
/*****************************************************
*函数名:DecryptFile
*功 能:解密文件
*入 参:PCHAR szSource, 待加密的文件名
PCHAR szDestination, 加密后的文件名
PCHAR passwd); 解密口令
*出 参:无
*返回值:BOOL,TRU为加密成功,FALSE为加密失败
******************************************************/
BOOL DecryptFile(PCHAR szSource,
PCHAR szDestination,
PCHAR passwd);
int _tmain(int argc, CHAR* argv[])
{
CHAR szEncSource[] = "test.txt";
CHAR szEncDes[] = "test_enc.txt";
CHAR szDecSource[] = "test_enc.txt";
CHAR szDecDes[] = "test_dec.txt";
CHAR * passwd = "123456";
BOOL bRet = EncryptFile(szEncSource, szEncDes, passwd);
if(bRet)
printf("EncryptFile success!\n");
bRet = DecryptFile(szDecSource, szDecDes, passwd);
if(bRet)
printf("DecryptFile success!\n");
getchar();
return 0;
}
BOOL EncryptFile(PCHAR szSource,
PCHAR szDestination,
PCHAR passwd)
{
//声明变量
FILE* fSource = NULL;
FILE* fDestination = NULL;
if((fSource = fopen(szSource, "rb")) == NULL)
{
return FALSE;
}
if((fDestination = fopen(szDestination, "wb")) == NULL)
{
return FALSE;
}
//一、获得一个CSP句柄
HCRYPTPROV hCryptProv;
BOOL bRet = CryptAcquireContext(
&hCryptProv,
NULL, //密钥容器名,NULL表示使用默认容器
NULL, //CSP_NAME
PROV_RSA_AES,
0
);
if(!bRet)
{
bRet = CryptAcquireContext(
&hCryptProv,
NULL, //密钥容器名,NULL表示使用默认容器
NULL, //CSP_NAME
PROV_RSA_AES,
CRYPT_NEWKEYSET //创建密钥容器
);
if(!bRet)
{
printf("CryptAcquireContext fail!");
return FALSE;
}
}
//创建一个会话密钥(session key),会话密钥也叫对称密钥
// 一个Session是指从调用函数CryptAcquireContext到调用函数CryptReleaseContext 期间的阶段。
//会话密钥只能存在于一个会话过程
HCRYPTHASH hCryptHash;
//创建hash对象
bRet = CryptCreateHash( hCryptProv,
CALG_MD5,
0,
0,
&hCryptHash);
if(!bRet)
{
printf("CryptCreateHash fail!");
return FALSE;
}
//用输入的密码作哈稀散列
bRet = CryptHashData( hCryptHash,
(BYTE*)passwd,
strlen(passwd),
0
);
if(!bRet)
{
printf("CryptHashData fail!");
return FALSE;
}
//用哈稀散列生成会话密钥
HCRYPTKEY hCryptKey;
bRet = CryptDeriveKey(hCryptProv,
CALG_AES_128,
hCryptHash,
CRYPT_EXPORTABLE,
&hCryptKey
);
CryptDestroyHash(hCryptHash);
if(!bRet)
{
printf("CryptDeriveKey fail!");
return FALSE;
}
//对文件进行加密,hCryptKey已经与加密算法相关联了CALG_AES_128
while(TRUE)
{
//分组加密,分组大小1024
CHAR buf[BLOCK_SIZE] = {0};
DWORD nReadLen = fread(buf, 1, BLOCK_SIZE, fSource);
if(nReadLen <= 0)
break;
CryptEncrypt(hCryptKey,
NULL,//如果数据同时进行散列和加密,这里传入一个散列对象
feof(fSource),//如果是最后一个块为TRUE
0,
(BYTE*)buf,//输入被加密的数据,输出加密数据
&nReadLen,//输入输入数据长度,输出加密后数据长度
BLOCK_SIZE//buf的大小
);
fwrite(buf, 1, nReadLen, fDestination);
}
//加密完成,释放
fclose(fSource);
fclose(fDestination);
if(hCryptKey)
CryptDestroyKey(hCryptKey);
if(hCryptHash)
CryptDestroyHash(hCryptHash);
if(hCryptProv)
CryptReleaseContext(hCryptProv, 0);
return TRUE;
}
BOOL DecryptFile(PCHAR szSource,
PCHAR szDestination,
PCHAR passwd)
{
//声明变量
FILE* fSource = NULL;
FILE* fDestination = NULL;
if((fSource = fopen(szSource, "rb")) == NULL)
{
return FALSE;
}
if((fDestination = fopen(szDestination, "wb")) == NULL)
{
return FALSE;
}
//一、获得一个CSP句柄
HCRYPTPROV hCryptProv;
BOOL bRet = CryptAcquireContext(
&hCryptProv,
NULL, //密钥容器名,NULL表示使用默认容器
NULL, //用户登录名
PROV_RSA_AES,
0
);
if(!bRet)
{
bRet = CryptAcquireContext(
&hCryptProv,
NULL, //密钥容器名,NULL表示使用默认容器
NULL, //用户登录名
PROV_RSA_AES,
CRYPT_NEWKEYSET //创建密钥容器
);
if(!bRet)
{
printf("CryptAcquireContext fail!");
return FALSE;
}
}
//创建一个会话密钥(session key),会话密钥也叫对称密钥
// 一个Session是指从调用函数CryptAcquireContext到调用函数CryptReleaseContext 期间的阶段。
//会话密钥只能存在于一个会话过程
HCRYPTHASH hCryptHash;
//创建hash对象
bRet = CryptCreateHash( hCryptProv,
CALG_MD5,
0,
0,
&hCryptHash);
if(!bRet)
{
printf("CryptCreateHash fail!");
return FALSE;
}
//用输入的密码作哈稀散列
bRet = CryptHashData( hCryptHash,
(BYTE*)passwd,
strlen(passwd),
0
);
if(!bRet)
{
printf("CryptHashData fail!");
return FALSE;
}
//用哈稀散列生成会话密钥
HCRYPTKEY hCryptKey;
bRet = CryptDeriveKey( hCryptProv,
CALG_AES_128,
hCryptHash,
CRYPT_EXPORTABLE,
&hCryptKey
);
if(!bRet)
{
printf("CryptDeriveKey fail!");
return FALSE;
}
//对文件进行解密,hCryptKey已经与加密算法相关联了CALG_AES_128
while(TRUE)
{
//分组加密,分组大小1024
CHAR buf[BLOCK_SIZE] = {0};
DWORD nReadLen = fread(buf, 1, BLOCK_SIZE, fSource);
if(nReadLen <= 0)
break;
CryptDecrypt(hCryptKey,
NULL,//如果数据同时进行散列和加密,这里传入一个散列对象
feof(fSource),//如果是最后一个块为TRUE
0,
(BYTE*)buf,//输入被加密的数据,输出加密数据
&nReadLen//输入输入数据长度,输出加密后数据长度
);
fwrite(buf, 1, nReadLen, fDestination);
}
//加密完成,释放
fclose(fSource);
fclose(fDestination);
if(hCryptKey)
CryptDestroyKey(hCryptKey);
if(hCryptHash)
CryptDestroyHash(hCryptHash);
if(hCryptProv)
CryptReleaseContext(hCryptProv, 0);
return TRUE;
}