使用 CryptoAPI 加密(源代码)

#include "stdafx.h" #include <Windows.h> #include <WinCrypt.h> #include <stdio.h> #include <iostream> using namespace std; //确定使用RC2块编码或是RC4流式编码 #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 const char* g_szDst = "./dst.txt"; BOOL EncryptWord(LPCTSTR lpszSrc, LPTSTR lpszDst, LPCTSTR lpszPwd); BOOL DecryptWord(LPCTSTR lpszSrc, LPTSTR lpszDst, LPCTSTR lpszPwd); int main() { TCHAR szSrc[MAX_PATH] = {0}; TCHAR szDst[MAX_PATH] = {0}; TCHAR szPwd[MAX_PATH] = {0}; TCHAR szVal[MAX_PATH] = {0}; cout << "please input encrypt string:" << endl; cin >> szSrc; cout << "enter pwd:" << endl; cin >> szPwd; EncryptWord(szSrc, szDst, szPwd); cout << "encrypt dst word:" << endl; cout << szDst << endl; DecryptWord(szDst, szVal, szPwd); cout << "decrypt word:" << endl; cout << szVal << endl; return 0; } BOOL EncryptWord(LPCTSTR lpszSrc, LPTSTR lpszDst, LPCTSTR lpszPwd) { HCRYPTPROV hProv = NULL; HCRYPTKEY hKey = NULL; HCRYPTKEY hChgKey = NULL; HCRYPTHASH hHash = NULL; DWORD dwKeyBlobLen = 0; PBYTE pbKeyBlob = NULL; //连接缺省的CSP CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0); if (NULL == lpszPwd)//口令为空,使用随机产生的会话密钥加密 { //产生随机会话密钥 CryptGenKey(hProv, ENCRYPT_ALGORITHM, CRYPT_EXPORTABLE, &hKey); //取得密钥交换对的公共密钥 CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hChgKey); //计算隐码长度并分配缓冲区 CryptExportKey(hKey, hChgKey, SIMPLEBLOB, 0, NULL, &dwKeyBlobLen); pbKeyBlob = (PBYTE)new char[dwKeyBlobLen + 1]; CryptExportKey(hKey, hChgKey, SIMPLEBLOB, 0, pbKeyBlob, &dwKeyBlobLen); //释放密钥交换对的句柄 CryptDestroyKey(hChgKey); hChgKey = NULL; FILE* fp = fopen(g_szDst, "wb"); fwrite(&dwKeyBlobLen, sizeof(DWORD), 1, fp); fwrite(pbKeyBlob, 1, dwKeyBlobLen, fp); fclose(fp); } else //口令不为空,使用从口令派生出的密钥加密文件 { CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash); //建立散列表 CryptHashData(hHash, (const LPBYTE)lpszPwd, strlen(lpszPwd), 0); //散列口令,从散列表中派生密钥 CryptDeriveKey(hProv, ENCRYPT_ALGORITHM, hHash, 0, &hKey); //删除散列表 CryptDestroyKey(hHash); hHash = 0; } //计算一次加密的数据字节数,必须为ENCRYPT_BLOCK_SIZE的整数倍 DWORD dwBlockLen = MAX_PATH - MAX_PATH % ENCRYPT_BLOCK_SIZE; DWORD dwBufLen = dwBlockLen; //如果使用块编码,则需要额外空间 if (ENCRYPT_BLOCK_SIZE > 1) { dwBufLen = dwBlockLen + ENCRYPT_BLOCK_SIZE; } //分配缓冲区 strcpy(lpszDst, lpszSrc); CryptEncrypt(hKey, 0, TRUE, 0, (LPBYTE)lpszDst, &dwBlockLen, dwBufLen); return TRUE; } BOOL DecryptWord(LPCTSTR lpszSrc, LPTSTR lpszDst, LPCTSTR lpszPwd) { HCRYPTPROV hProv = NULL; HCRYPTKEY hKey = NULL; HCRYPTKEY hChgKey = NULL; HCRYPTHASH hHash = NULL; DWORD dwKeyBlobLen = 0; PBYTE pbKeyBlob = NULL; CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0); if (NULL == lpszPwd) { //口令为空,使用存储在加密文件中的会话密钥解密 //读隐码的长度并分配内存 FILE* fp = fopen(g_szDst, "rb"); fread(&dwKeyBlobLen, sizeof(DWORD), 1, fp); fread(pbKeyBlob, 1, dwKeyBlobLen, fp); fclose(fp); CryptImportKey(hProv, pbKeyBlob, dwKeyBlobLen, 0, 0, &hKey); } else { //口令不为空, 使用从口令派生出的密钥解密文件 CryptCreateHash(hProv, CALG_MD5, NULL, 0, &hHash); CryptHashData(hHash, (const LPBYTE)lpszPwd, strlen(lpszPwd), 0); CryptDeriveKey(hProv, ENCRYPT_ALGORITHM, hHash, 0, &hKey); CryptDestroyHash(hHash); hHash = NULL; } //计算一次加密的数据字节数,必须为ENCRYPT_BLOCK_SIZE的整数倍 DWORD dwBlockLen = MAX_PATH - MAX_PATH % ENCRYPT_BLOCK_SIZE; DWORD dwBufLen = dwBlockLen; //如果使用块编码,则需要额外空间 if (ENCRYPT_BLOCK_SIZE > 1) { dwBufLen = dwBlockLen + ENCRYPT_BLOCK_SIZE; } strcpy(lpszDst, lpszSrc); CryptDecrypt(hKey, 0, TRUE, 0, (LPBYTE)lpszDst, &dwBlockLen); return TRUE; } 

你可能感兴趣的:(Algorithm,加密,解密,null,Path,FP)