使用 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;
}
 

你可能感兴趣的:(windows,FP)