WindowsAPI编程核心技术-加密技术

CryptoAPI

HASH

CryptAcquireContext

获取特定CSP内特定密钥容器句柄。

1
2
3
4
5
6
7
8
9
10
11
12
BOOL WINAPI CryptAcquireContext(
_Out_ HCRYPTPROV *phProv,
//CSP句柄指针
_In_ LPCTSTR pszContainer,
//密钥容器名称
_In_ LPCTSTR pszProvider,
//CSP名称
_In_ DWORD dwProvType,
//获取提供程序的类型
_In_ DWORD dwFlags
//标志
)//成功TRUE 失败FALSE

CryptCreateHash

创建空HASH对象。

1
2
3
4
5
6
7
8
9
10
11
12
BOOL WINAPI CryptCreateHash(
_In_ HCRYPTPROV hProv,
//CSP句柄
_In_ ALG_ID Algid,
//要使用的HASH算法ID CALG_MD5 CALG_SHA1 CALG_SHA256等
_In_ HCRYPTKEY hKey,
//对于非键控算法必须为0
_In_ DWORD dwFlags,
//通常0
_Out_ HCRYPTHASH *phHash
//新HASH对象地址
)//成功TRUE 失败FALSE

CryptHashData

数据添加到HASH对象并计算。

1
2
3
4
5
6
7
8
9
10
BOOL WINAPI CryptHashData(
_In_ HCRYPTHASH hHash,
//HASH对象句柄
_In_ BYTE *pbData,
//要添加的数据的缓冲区指针
_In_ DWORD dwDataLen,
//大小
_In_ DWORD dwFlags
//通常0
)//成功TRUE 失败FALSE

CryptGetHashParam

从HASH对象中获取指定参数值。

1
2
3
4
5
6
7
8
9
10
11
12
BOOL WINAPI CryptGetHashParam(
_In_ HCRYPTHASH hHash,
//HASH对象句柄
_In_ DWORD dwParam,
//查询类型 HP_ALGID算法 HP_HASHSIZE结果字节数 HP_HASHVAL结果
_Out_ BYTE *pbData,
//接收指定值的数据缓冲区指针
_Inout_ DWORD *pdwDataLen,
//指向pbData大小的指针
_In_ DWORD dwFlags
//保留0
)//成功TRUE 失败FALSE

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <cstdio>
BOOL CalculateHash(PBYTE pData, DWORD dwDataLength, ALG_ID algHashType, PBYTE* ppHashData, PDWORD pdwHashDataLength) {
HCRYPTPROV hCryptProv = NULL;
HCRYPTHASH hCryptHash = NULL;
DWORD dwHashDataLength = 0, dwTemp = 0;
BYTE* pHashData = NULL;
BOOL bRet = FALSE;
do {
bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
if (bRet == FALSE)
break;
bRet = ::CryptCreateHash(hCryptProv, algHashType, NULL, NULL, &hCryptHash);
if (FALSE == bRet)
break;
bRet = ::CryptHashData(hCryptHash, pData, dwDataLength, 0);
if (FALSE == bRet)
break;
dwTemp = sizeof(dwHashDataLength);
bRet = ::CryptGetHashParam(hCryptHash, HP_HASHSIZE, (BYTE*)(&dwHashDataLength), &dwTemp, 0);
if (FALSE == bRet)
break;
pHashData = new BYTE[dwHashDataLength];
if (NULL == pHashData) {
bRet = FALSE;
break;
};
::RtlZeroMemory(pHashData, dwHashDataLength);
bRet = ::CryptGetHashParam(hCryptHash, HP_HASHVAL, pHashData, &dwHashDataLength, 0);
if (FALSE == bRet)
break;
} while (FALSE);
if (bRet == TRUE) {
for (size_t nIdx = 0; nIdx < dwHashDataLength; nIdx++)
printf("%02X", pHashData[nIdx]);
putchar('\n');
};
if (NULL != pHashData) {
delete[]pHashData;
pHashData = NULL;
};
if (NULL != hCryptProv) {
::CryptReleaseContext(hCryptProv, 0);
hCryptProv = NULL;
};
if (NULL != hCryptHash) {
::CryptDestroyHash(hCryptHash);
hCryptHash = NULL;
};
return bRet;
};

AES

CryptDeriveKey

从基础数据值派生出加密会话密钥。

1
2
3
4
5
6
7
8
9
10
11
12
BOOL WINAPI CryptDeriveKey(
_In_ HCRYPTPROV hProv,
//CSP句柄
_In_ ALG_ID Algid,
//要为其生成密钥对称加密算法的ID CALG_AES_128默认 CALG_DES
_In_ HCRYPTHASH hBaseData,
//基础数据
_In_ DWORD dwFlags,
//生成密钥类型 有枚举值
_Inout_ HCRYPTKEY* phKey
//接收新生成密钥句柄地址
)//成功TRUE 失败FALSE

CryptEntrypt

加密数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
BOOL WINAPI CryptEncrypt(
_In_ HCRYPTKEY hKey,
//加密密钥
_In_ HCRYPTHASH hHash,
//HASH对象 不HASH为NULL
_In_ BOOL Final,
//是否为最后一个块
_In_ DWORD dwFlags,
//保留0
_Inout_ BYTE* pbData,
//要加密的明文缓冲区指针 接收密文
_Inout_ DWORD* pdwDataLen,
//读缓冲区中明文大小 写密文大小
_In_ DWORD dwBufLen
//明文缓冲区总大小
)//成功TRUE 失败FALSE

CryptDecrypt

解密数据。

1
2
3
4
5
6
7
8
BOOL WINAPI CryptDecrypt( //都同上 懒得写了
_In_ HCRYPTKEY hKey,
_In_ HCRYPTHASH hHash,
_In_ BOOL Final,
_In_ DWORD dwFlags,
_Inout_ BYTE* pbData,
_Inout_ DWORD* pdwDataLen
)

例子

不直接拿明文密钥加密,先把密钥进行MD5。AES一个组只能$128$位,密钥长度可以为$128$位、$192$位或$256$位。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <cstdio>
BOOL FileWriteBack(const char* pcszFilePathName, PBYTE pbData, SIZE_T nBufferSize) {
BOOL bRet = FALSE;
FILE* fp = NULL;
fp = fopen(pcszFilePathName, "wb");
if (NULL == fp)
return bRet;
fwrite(pbData, nBufferSize, 1, fp);
if (NULL != fp) {
fclose(fp);
fp = NULL;
};
return bRet;
};
BOOL ReadFromFile(LPCSTR lpcszFilePathName, PBYTE* ppData, DWORD& dwFileSize, size_t& nFileBufferLength) {
BOOL bRet = FALSE;
FILE* fp = NULL;
LONG lSize = 0;
PBYTE pbData = NULL;
fp = fopen(lpcszFilePathName, "rb");
if (NULL == fp)
return FALSE;
fseek(fp, 0, SEEK_END);
lSize = ftell(fp);
pbData = new BYTE[lSize * 16];
::RtlZeroMemory(pbData, lSize * 16);
dwFileSize = lSize;
nFileBufferLength = lSize * 16;
fseek(fp, 0, SEEK_SET);
fread(pbData, lSize, 1, fp);
if (NULL != fp) {
fclose(fp);
fp = NULL;
};
*ppData = pbData;
return TRUE;
}
BOOL AesEncrypt(const PBYTE pcszPassword, SIZE_T nPasswordLength,LPCSTR lpcszOrigFilePathName,LPCSTR lpcszEncFilePathName) {
BOOL bRet = FALSE;
HCRYPTPROV hCryptProv = NULL;
HCRYPTHASH hCryptHash = NULL;
HCRYPTKEY hCryptKey = NULL;
PBYTE pbData = NULL;
DWORD dwDataLength = 0;
SIZE_T nBufferLength=0;
do {
bRet = ReadFromFile(lpcszOrigFilePathName, &pbData, dwDataLength, nBufferLength);
bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
if (FALSE == bRet)
break;
bRet = ::CryptCreateHash(hCryptProv, CALG_MD5, NULL, 0, &hCryptHash);
if (FALSE == bRet)
break;
bRet = ::CryptHashData(hCryptHash, pcszPassword, nPasswordLength, 0);
if (FALSE == bRet)
break;
bRet = ::CryptDeriveKey(hCryptProv, CALG_AES_128, hCryptHash, CRYPT_EXPORTABLE, &hCryptKey);
if (FALSE == bRet)
break;
bRet = ::CryptEncrypt(hCryptKey, NULL, TRUE, 0, pbData, &dwDataLength, nBufferLength);
if (FALSE == bRet)
break;
bRet = FileWriteBack(lpcszEncFilePathName, pbData, dwDataLength);
} while (FALSE);
if (NULL != hCryptProv) {
::CryptReleaseContext(hCryptProv, 0);
hCryptProv = NULL;
};
if (NULL != hCryptHash) {
::CryptDestroyHash(hCryptHash);
hCryptHash = NULL;
};
if (NULL != hCryptKey) {
::CryptDestroyKey(hCryptKey);
hCryptKey = NULL;
};
if (NULL != pbData) {
delete[]pbData;
pbData = NULL;
};
return bRet;
};
BOOL AesDecrypt(const PBYTE pcszPassword, SIZE_T nPasswordLength, LPCSTR lpcszOrigFilePathName, LPCSTR lpcszEncFilePathName) {
BOOL bRet = FALSE;
HCRYPTPROV hCryptProv = NULL;
HCRYPTHASH hCryptHash = NULL;
HCRYPTKEY hCryptKey = NULL;
PBYTE pbData = NULL;
DWORD dwDataLength = 0;
SIZE_T nBufferLength = 0;
do {
bRet = ReadFromFile(lpcszOrigFilePathName, &pbData, dwDataLength, nBufferLength);
bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
if (FALSE == bRet)
break;
bRet = ::CryptCreateHash(hCryptProv, CALG_MD5, NULL, 0, &hCryptHash);
if (FALSE == bRet)
break;
bRet = ::CryptHashData(hCryptHash, pcszPassword, nPasswordLength, 0);
if (FALSE == bRet)
break;
bRet = ::CryptDeriveKey(hCryptProv, CALG_AES_128, hCryptHash, CRYPT_EXPORTABLE, &hCryptKey);
if (FALSE == bRet)
break;
bRet = ::CryptDecrypt(hCryptKey, NULL, TRUE, 0, pbData, &dwDataLength);
if (FALSE == bRet)
break;
bRet = FileWriteBack(lpcszEncFilePathName, pbData, dwDataLength);
if (FALSE == bRet)
break;
bRet = TRUE;
} while (FALSE);
if (NULL != hCryptProv) {
::CryptReleaseContext(hCryptProv, 0);
hCryptProv = NULL;
};
if (NULL != hCryptHash) {
::CryptDestroyHash(hCryptHash);
hCryptHash = NULL;
};
if (NULL != hCryptKey) {
::CryptDestroyKey(hCryptKey);
hCryptKey = NULL;
};
if (NULL != pbData) {
delete[]pbData;
pbData = NULL;
};
return bRet;
};

RSA

CryptGenKey

随机生成加密会话密钥或公钥/私钥对,返回句柄。

1
2
3
4
5
6
7
8
9
10
BOOL WINAPI CryptGenKey(
_In_ HCRYPTPROV hProv,
//CSP句柄
_In_ ALG_ID Algid,
//密钥算法
_In_ DWORD dwFlags,
//密钥类型
_Out_ HCRYPTKEY* phKey
//密钥或密钥对句柄
)//成功TRUE 失败FALSE

CryptExportKey

从CSP导出加密密钥或密钥对。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
BOOL WINAPI CryptExportKey(
_In_ HCRYPTKEY hKey,
//要导出的密钥句柄
_In_ HCRYPTKEY hExpKey,
//目标用户密钥句柄
_In_ DWORD dwBlobType,
//导出的类型
_In_ DWORD dwFlags,
//附加选项
_Out_ BYTE* pbData,
//接收数据缓冲区指针 NULL就塞到pdwDataLen
_Inout_ DWORD* pdwDataLen
//缓冲区大小
)//成功TRUE 失败FALSE

CryptImportKey

将密钥从密钥BLOB导入CSP中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
BOOL WINAPI CryptImportKey(
_In_ HCRYPTPROV hProv,
//CSP句柄
_In_ BYTE* pbData,
//密钥BLOB
_In_ DWORD dwDataLen,
//BLOB长度
_In_ HCRYPTKEY hPubKey,
//?
_In_ DWORD dwFlags,
//?
_Out_ HCRYPTKEY* phKey
//接收导入键句柄HCRYPTKEY的指针
)//成功TRUE 失败FALSE

例子

导出公钥/私钥都要重复导两次,第一次只导出大小,动态申请足够内存后再导出密钥。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
BOOL GenerateKey(PBYTE* ppPublicKey, PDWORD pdwPublicKeyLength, PBYTE* ppPrivateKey, PDWORD pdwPrivateKeyLength) {
HCRYPTPROV hCryptProv = NULL;
HCRYPTKEY hCryptKey = NULL;
DWORD dwPublicKeyLength = 0, dwPrivateKeyLength = 0;
PBYTE pPublicKey = NULL, pPrivateKey = NULL;
BOOL bRet = FALSE;
do {
bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0);
if (FALSE == bRet)
break;
bRet = ::CryptGenKey(hCryptProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hCryptKey);
if (FALSE == bRet)
break;
bRet = ::CryptExportKey(hCryptKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwPublicKeyLength);
if (FALSE == bRet)
break;
pPublicKey = new BYTE[dwPublicKeyLength];
::RtlZeroMemory(pPublicKey, NULL, PUBLICKEYBLOB, 0, pPublicKey, &dwPublicKeyLength);
bRet = ::CryptExportKey(hCryptKey, NULL, PUBLICKEYBLOB, 0, pPublicKey, &dwPublicKeyLength);
if (FALSE == bRet)
break;
bRet = ::CryptExportKey(hCryptKey, NULL, PRIVATEKEYBLOB, 0, NULL, &dwPrivateKeyLength);
if (FALSE == bRet)
break;
pPrivateKey = new BYTE[dwPrivateKeyLength];
::RtlZeroMemory(pPrivateKey, NULL, PRIVATEKEYBLOB, 0, pPrivateKey, &dwPrivateKeyLength);
bRet = ::CryptExportKey(hCryptKey, NULL, PRIVATEKEYBLOB, 0, pPrivateKey, &dwPrivateKeyLength);
if (FALSE == bRet)
break;
bRet = TRUE;
*ppPublicKey = pPublicKey;
*pdwPublicKeyLength = dwPublicKeyLength;
*ppPrivateKey = pPrivateKey;
*pdwPrivateKeyLength = dwPrivateKeyLength;
} while (FALSE);
if (hCryptKey != NULL) {
::CryptDestroyKey(hCryptKey);
hCryptKey = NULL;
};
if (hCryptProv != NULL) {
::CryptReleaseContext(hCryptProv, 0);
hCryptProv = NULL;
};
if (pPublicKey != NULL) {
delete[]pPublicKey;
pPublicKey = NULL;
};
if (pPrivateKey != NULL) {
delete[]pPrivateKey;
pPrivateKey = NULL;
};
return bRet;
};
BOOL RsaEncrypt(PBYTE pPublicKey, DWORD dwPublicKeyLength, PBYTE pData, DWORD& dwDataLength, DWORD dwBufferLength) {
HCRYPTPROV hCryptProv = NULL;
HCRYPTKEY hCryptKey = NULL;
BOOL bRet = FALSE;
do {
bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0);
if (FALSE == bRet)
break;
bRet = ::CryptImportKey(hCryptProv, pPublicKey, dwPublicKeyLength, NULL, 0, &hCryptKey);
if (FALSE == bRet)
break;
bRet = ::CryptEncrypt(hCryptKey, NULL, TRUE, 0, pData, &dwDataLength, dwBufferLength);
if (FALSE == bRet)
break;
} while (FALSE);
if (hCryptProv != NULL) {
::CryptReleaseContext(hCryptProv, 0);
hCryptProv = NULL;
};
if (hCryptKey != NULL) {
::CryptDestroyKey(hCryptKey);
hCryptKey = NULL;
};
return bRet;
};
BOOL RsaDecrypt(PBYTE pPrivateKey, DWORD dwPrivateKeyLength, PBYTE pData, DWORD& dwDataLength, DWORD dwBufferLength) {
HCRYPTPROV hCryptProv = NULL;
HCRYPTKEY hCryptKey = NULL;
BOOL bRet = FALSE;
do {
bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0);
if (FALSE == bRet)
break;
bRet = ::CryptImportKey(hCryptProv, pPrivateKey, dwPrivateKeyLength, NULL, 0, &hCryptKey);
if (FALSE == bRet)
break;
bRet = ::CryptEncrypt(hCryptKey, NULL, TRUE, 0, pData, &dwDataLength, dwBufferLength);
if (FALSE == bRet)
break;
} while (FALSE);
if (hCryptProv != NULL) {
::CryptReleaseContext(hCryptProv, 0);
hCryptProv = NULL;
};
if (hCryptKey != NULL) {
::CryptDestroyKey(hCryptKey);
hCryptKey = NULL;
};
return bRet;
};

Crypto++

安装

Github下载源码,打开“cryptest.sln”解决方案,编译“cryptlib”项目工程,找到“cryptopp890\x64\Output\Debug\cryptlib.lib”。

把cryptlib.lib和按照需要选择性地拷贝.h文件到当前工程下。

编译时需要检查编译cryptlib.lib和当前工程的“C\C++”->“代码生成”->“运行库”的选项是否一致,同时注意x86和x64一致。

HASH

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <string>
#include "cryptopp\\sha.h"
#include "cryptopp\\files.h"
#include "cryptopp\\hex.h"
using namespace std;
using namespace CryptoPP;
#pragma comment(lib,"cryptopp\\cryptlib.lib")
string CalSHA1_ByFile(char* pszFileName) { //计算文件的SHA1
string value;
SHA1 sha1; //可相应改成SHA256 MD5等
FileSource(pszFileName, true, new HashFilter(sha1, new HexEncoder(new StringSink(value)))); //修改同上
return value;
};
string CalSHA1_ByMem(PBYTE pData, DWORD dwDataSize) { //计算数据的SHA1
string value;
SHA1 sha1;
StringSource(pData, dwDataSize, true, new HashFilter(sha1, new HexEncoder(new StringSink(value))));
return value;
};

AES

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include "cryptopp\\aes.h"
using namespace CryptoPP;
#pragma comment(lib,"cryptopp\\cryptlib.lib")
BOOL AES_Encrypt(PBYTE pOriginalData, DWORD dwOriginalDataSize, PBYTE pAESKey, DWORD dwAESKeySize, PBYTE* ppEncryptData, PDWORD pdwEncryptData) {
AESEncryption aesEncryptor; //加密器
unsigned char inBlock[AES::BLOCKSIZE]; //加密原文数据块
unsigned char outBlock[AES::BLOCKSIZE]; //加密后密文数据块
unsigned char xorBlock[AES::BLOCKSIZE]; //必须全0
DWORD dwOffset = 0;
PBYTE pEncryptData = NULL;
DWORD dwEncryptDataSize = 0;
DWORD dwQuotient = dwOriginalDataSize / AES::BLOCKSIZE;
DWORD dwRemaind = dwOriginalDataSize % AES::BLOCKSIZE;
if (0 != dwRemaind)
dwQuotient++;
dwEncryptDataSize = dwQuotient * AES::BLOCKSIZE;
pEncryptData = new BYTE[dwEncryptDataSize];
if (NULL == pEncryptData)
return FALSE;
aesEncryptor.SetKey(pAESKey, dwAESKeySize);
do {
::RtlZeroMemory(inBlock, AES::BLOCKSIZE);
::RtlZeroMemory(xorBlock, AES::BLOCKSIZE);
::RtlZeroMemory(outBlock, AES::BLOCKSIZE);
if (dwOffset <= (dwOriginalDataSize - AES::BLOCKSIZE))
::RtlCopyMemory(inBlock, (PVOID)(pOriginalData + dwOffset), AES::BLOCKSIZE);
else
::RtlCopyMemory(inBlock, (PVOID)(pOriginalData + dwOffset), (dwOriginalDataSize - dwOffset));
aesEncryptor.ProcessAndXorBlock(inBlock, xorBlock, outBlock);
::RtlCopyMemory((PVOID)(pEncryptData + dwOffset), outBlock, AES::BLOCKSIZE);
dwOffset = dwOffset + AES::BLOCKSIZE;
dwQuotient--;
} while (0 < dwQuotient);
*ppEncryptData = pEncryptData;
*pdwEncryptData = dwEncryptDataSize;
return TRUE;
};
BOOL AES_Decrypt(PBYTE pEncryptData, DWORD dwEncryptDataSize, PBYTE pAESKey, DWORD dwAESKeySize, PBYTE* ppDecryptData, PDWORD pdwDecryptData) {
AESDecryption aesDecryptor;
unsigned char inBlock[AES::BLOCKSIZE];
unsigned char outBlock[AES::BLOCKSIZE];
unsigned char xorBlock[AES::BLOCKSIZE];
DWORD dwOffset = 0;
PBYTE pDecryptData = NULL;
DWORD dwDecryptDataSize = 0;
DWORD dwQuotient = dwEncryptDataSize / AES::BLOCKSIZE;
DWORD dwRemaind = dwEncryptDataSize % AES::BLOCKSIZE;
if (0 != dwRemaind)
dwQuotient++;
dwDecryptDataSize = dwQuotient * AES::BLOCKSIZE;
pDecryptData = new BYTE[dwDecryptDataSize];
if (NULL == pDecryptData)
return FALSE;
aesDecryptor.SetKey(pAESKey, dwAESKeySize);
do {
::RtlZeroMemory(inBlock, AES::BLOCKSIZE);
::RtlZeroMemory(xorBlock, AES::BLOCKSIZE);
::RtlZeroMemory(outBlock, AES::BLOCKSIZE);
if (dwOffset <= (dwDecryptDataSize - AES::BLOCKSIZE))
::RtlCopyMemory(inBlock, (PVOID)(pEncryptData + dwOffset), AES::BLOCKSIZE);
else
::RtlCopyMemory(inBlock, (PVOID)(pEncryptData + dwOffset), (dwEncryptDataSize - dwOffset));
aesDecryptor.ProcessAndXorBlock(inBlock, xorBlock, outBlock);
::RtlCopyMemory((PVOID)(pDecryptData + dwOffset), outBlock, AES::BLOCKSIZE);
dwOffset = dwOffset + AES::BLOCKSIZE;
dwQuotient--;
} while (0 < dwQuotient);
*ppDecryptData = pDecryptData;
*pdwDecryptData = dwDecryptDataSize;
return TRUE;
};

RSA

用随机数生成公私钥对并保存到文件中,公钥加密时用公钥文件加密文件或数据,解密同理。代码自己去找,这里不写了。