简单实现强大的加密功能——CryptoAPI
发布时间:2019-12-13 04:18:57 所属栏目:MsSql教程 来源:蓝点
导读:CryptoAPI是Microsoft提供的加密应用程序接口,他其实是一组函数,他为许多高级安全性服务提供了基础,包括用于电子商务的SET,用于加密客户机/服务器消息的PCT,用于在各个平台之间来回传递机密数据和密钥的PFX,代码签名等等。 支持这种功能的主要有2000/
CryptoAPI是Microsoft提供的加密应用程序接口,他其实是一组函数,他为许多高级安全性服务提供了基础,包括用于电子商务的SET,用于加密客户机/服务器消息的PCT,用于在各个平台之间来回传递机密数据和密钥的PFX,代码签名等等。 支持这种功能的主要有2000/XP(98和ME下不详) 其配置信息(密钥)主要在 HKEY_LOCAL_MACHINESOFTWAREMicrosoft 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_ALGORITHM??CALG_RC2 #define ENCRYPT_BLOCK_SIZE??8 #else #define ENCRYPT_ALGORITHM??CALG_RC4 #define ENCRYPT_BLOCK_SIZE??1 #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("OKn"); ......//关闭文件、释放内存 } ----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(“OKn"); ......//关闭文件、释放内存 } ----以上代码在Windows 2000、Visual C++6.0环境中编译通过。 (编辑:91站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |