-
您的位置:首页 → 资讯 → 教你一招 → 简单实现强大的加密功能——CryptoAPI
简单实现强大的加密功能——CryptoAPI
时间:2004/10/15 1:17:00来源:本站整理作者:蓝点我要评论(0)
-
CryptoAPI是Microsoft提供的加密应用程序接口,他其实是一组函数,他为许多高级安全性服务提供了基础,包括用于电子商务的SET,用于加密客户机/服务器消息的PCT,用于在各个平台之间来回传递机密数据和密钥的PFX,代码签名等等。
支持这种功能的主要有2000/XP(98和ME下不详)
其配置信息(密钥)主要在
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft
\ Cryptography \Defaults
HKEY_CURRENT_USER\ Software \ Microsoft
\ Cryptography \Providers
中,
下面以两个文件加密与解密的C程序片断为例,演示一下CryptoAPI的强大功能。这两个程序均为Win32控制台应用,程序省略了出错处理,实际运行时请加入。
----1. 文件加密
#include
#include
#include
#include
//确定使用RC2块编码或是RC4流式编码,这就是CryptoAPI支持的两种基本编码方式
#ifdef USE_BLOCK_CIPHER
#define ENCRYPT_ALGORITHMCALG_RC2
#define ENCRYPT_BLOCK_SIZE8
#else
#define ENCRYPT_ALGORITHMCALG_RC4
#define ENCRYPT_BLOCK_SIZE1
#endif
void CAPIDecryptFile(PCHAR szSource,
PCHAR szDestination, PCHAR szPassword);
void _cdecl main(int argc, char *argv[])
{
PCHAR szSource= NULL;
PCHAR szDestination = NULL;
PCHAR szPassword= NULL;
// 验证参数个数
if(argc != 3 && argc != 4) {
printf(“USAGE: decrypt < source file >
< dest file > [ ]\n");
exit(1);
}
//读取参数.
szSource= argv[1];
szDestination = argv[2];
if(argc == 4) {
szPassword = argv[3];
}
CAPIDecryptFile(szSource, szDestination, szPassword);
}
/*szSource为要加密的文件名称,
szDestination为加密过的文件名称,
szPassword为加密口令*/
void CAPIEncryptFile(PCHAR szSource,
PCHAR szDestination, PCHAR szPassword)
{
FILE *hSource = NULL;
FILE *hDestination = NULL;
INT eof = 0;
HCRYPTPROV hProv = 0;
HCRYPTKEY hKey = 0;
HCRYPTKEY hXchgKey = 0;
HCRYPTHASH hHash = 0;
PBYTE pbKeyBlob = NULL;
DWORD dwKeyBlobLen;
PBYTE pbBuffer = NULL;
DWORD dwBlockLen;
DWORD dwBufferLen;
DWORD dwCount;
hSource= fopen(szSource,“rb"));// 打开源文件
hDestination = fopen(szDestination,“wb") ;//.打开目标文件
// 连接缺省的CSP,密码服务提供者模块(CSP),这是通过WIN系统中捆绑的RSA Base Provider实现的。
CryptAcquireContext(&hProv, NULL, NULL,
PROV_RSA_FULL, 0));
if(szPassword == NULL) {
//口令为空,使用随机产生的会话密钥加密
// 产生随机会话密钥。
CryptGenKey(hProv, ENCRYPT_ALGORITHM,
CRYPT_EXPORTABLE, &hKey)
// 取得密钥交换对的公共密钥
CryptGetUserKey(hProv, AT_KEYEXCHANGE,
&hXchgKey);
// 计算隐码长度并分配缓冲区
CryptExportKey(hKey, hXchgKey,
SIMPLEBLOB, 0, NULL, &dwKeyBlobLen);
pbKeyBlob=malloc(dwKeyBlobLen)) == NULL) ;
// 将会话密钥输出至隐码
CryptExportKey(hKey, hXchgKey,
SIMPLEBLOB, 0, pbKeyBlob, &dwKeyBlobLen));
// 释放密钥交换对的句柄
CryptDestroyKey(hXchgKey);
hXchgKey = 0;
// 将隐码长度写入目标文件
fwrite(&dwKeyBlobLen, sizeof(DWORD), 1, hDestination);
//将隐码长度写入目标文件
fwrite(pbKeyBlob,1,dwKeyBlobLen, hDestination);
} else {
//口令不为空, 使用从口令派生出的密钥加密文件
CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
// 建立散列表
CryptHashData(hHash, szPassword, strlen(szPassword), 0);
//散列口令
// 从散列表中派生密钥
CryptDeriveKey(hProv, ENCRYPT_ALGORITHM, hHash, 0, &hKey);
// 删除散列表
CryptDestroyHash(hHash);
hHash = 0;
}
//计算一次加密的数据字节数,
必须为ENCRYPT_BLOCK_SIZE的整数倍
dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
//如果使用块编码,则需要额外空间
if(ENCRYPT_BLOCK_SIZE > 1) {
dwBufferLen=dwBlockLen + ENCRYPT_BLOCK_SIZE;
} else {
dwBufferLen = dwBlockLen;
}
//分配缓冲区
pbBuffer = malloc(dwBufferLen);
//加密源文件并写入目标文件
do {
// 从源文件中读出dwBlockLen个字节
dwCount = fread(pbBuffer, 1, dwBlockLen, hSource);
eof = feof(hSource);
//加密数据
CryptEncrypt(hKey, 0, eof, 0, pbBuffer, &dwCount, dwBufferLen);
// 将加密过的数据写入目标文件
fwrite(pbBuffer, 1, dwCount, hDestination);
} while(!feof(hSource));
printf("OK\n");
......//关闭文件、释放内存
}
----2 文件解密
void CAPIDecryptFile(PCHAR szSource,
PCHAR szDestination, PCHAR szPassword)
{
......//变量声明、文件操作同文件加密程序
CryptAcquireContext(&hProv, NULL, NULL,
PROV_RSA_FULL, 0);
if(szPassword == NULL) {
// 口令为空,使用存储在加密文件中的会话密钥解密
// 读隐码的长度并分配内存
fread(&dwKeyBlobLen,sizeof(DWORD),1,hSource);
pbKeyBlob=malloc(dwKeyBlobLen))== NULL);
// 从源文件中读隐码.
fread(pbKeyBlob, 1, dwKeyBlobLen, hSource);
// 将隐码输入CSP
CryptImportKey(hProv, pbKeyBlob,
dwKeyBlobLen, 0, 0, &hKey);
} else {
// 口令不为空, 使用从口令派生出的密钥解密文件
CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
CryptHashData(hHash, szPassword, strlen
(szPassword), 0);
CryptDeriveKey(hProv, ENCRYPT_ALGORITHM,
hHash, 0, &hKey);
CryptDestroyHash(hHash);
hHash = 0;
}
dwBlockLen=1000-1000%ENCRYPT_BLOCK_SIZE;
if(ENCRYPT_BLOCK_SIZE > 1) {
dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;
} else {
dwBufferLen = dwBlockLen;
}
pbBuffer = malloc(dwBufferLen);
//解密源文件并写入目标文件
do {
dwCount = fread(pbBuffer, 1, dwBlockLen,
hSource);
eof = feof(hSource);
// 解密数据
CryptDecrypt(hKey, 0, eof, 0, pbBuffer, &dwCount);
// 将解密过的数据写入目标文件
fwrite(pbBuffer, 1, dwCount, hDestination);
} while(!feof(hSource));
printf(“OK\n");
......//关闭文件、释放内存
}
----以上代码在Windows 2000、Visual C++6.0环境中编译通过。
相关阅读
Windows错误代码大全 Windows错误代码查询激活windows有什么用Mac QQ和Windows QQ聊天记录怎么合并 Mac QQ和Windows QQ聊天记录Windows 10自动更新怎么关闭 如何关闭Windows 10自动更新windows 10 rs4快速预览版17017下载错误问题Win10秋季创意者更新16291更新了什么 win10 16291更新内容windows10秋季创意者更新时间 windows10秋季创意者更新内容kb3150513补丁更新了什么 Windows 10补丁kb3150513是什么
-
热门文章
电视盒子怎么看百度云迅雷9怎么关闭右侧 迅迅雷99.99下载不完怎么网易云音乐怎么上传歌
最新文章
2022支付宝万能福扫福微信迎新春状态怎么设
微信小老虎头像怎么设置 微信ID后面设置小老抖音压岁钱卡怎么获得2022 抖音压岁钱获取方微博隐私保护怎么设置 微博隐私保护功能完善今日头条2022年集卡活动开启时间 今日头条2
人气排行
智学网怎么登录 智学网怎么查分数 智学网统教你怎么写电子邮箱格式?以163和QQ邮箱为例腾讯大王卡用了后悔怎么办 腾讯大王卡值得办缺少或丢失xinput1_3.dll解决方法,xinput1应用程序无法正常启动0xc000007b解决方法快播关闭怎么办?快播不能用了怎么看片将pdf文件转换为word文件的最简单方法如何破解QQ空间密码和权限
查看所有0条评论>>