Crypto 库是C/C++的加密算法库,这个加密库很流行,基本上涵盖了市面上的各类加密解密算法,以下代码是我在学习是总结的,放到这里用于后期需要时能够快速解决问题。
项目地址:https://www.cryptopp.com/
Sha256加密算法: Sha系列加密算法包括很多,基本上有以下几种格式的加密方式,位数越大加密强度越大,此算法属于单向加密算法与MD5类似但安全性高于MD5。
SHA-1:生成摘要的性能比MD5略低 SHA-256:可以生成长度256bit的信息摘要 SHA-224:可以生成长度224bit的信息摘要 SHA-384:可以生成长度384bit的信息摘要 SHA-512:可以生成长度512bit的信息摘要
using namespace std; | |
using namespace CryptoPP; | |
// 计算文件的 SHA256 值 | |
string CalSHA256_ByFile(char *pszFileName) | |
{ | |
string value; | |
SHA256 sha256; | |
FileSource(pszFileName, true, new HashFilter(sha256, new HexEncoder(new StringSink(value)))); | |
return value; | |
} | |
// 计算数据的 SHA256 值 | |
string CalSHA256_ByMem(PBYTE pData, DWORD dwDataSize) | |
{ | |
string value; | |
SHA256 sha256; | |
StringSource(pData, dwDataSize, true, new HashFilter(sha256, new HexEncoder(new StringSink(value)))); | |
return value; | |
} | |
int main(int argc, char * argv[]) | |
{ | |
string src = "hello lyshark"; | |
string dst; | |
// 单独计算MD5值的使用 | |
MD5 md5; | |
StringSource(src, true, new HashFilter(md5, new HexEncoder(new StringSink(dst)))); | |
cout << "计算字符串MD5: " << dst << endl; | |
// 单独计算CRC32值 | |
CRC32 crc32; | |
StringSource(src, true, new HashFilter(crc32, new HexEncoder(new StringSink(dst)))); | |
cout << "计算字符串CRC32: " << dst << endl; | |
// 计算一个数组 | |
BYTE pArrayData[] = { 10, 20, 30, 40, 50 }; | |
DWORD dwArraySize = sizeof(pArrayData); | |
dst.clear(); | |
StringSource(pArrayData, dwArraySize, true, new HashFilter(md5, new HexEncoder(new StringSink(dst)))); | |
cout << "计算数组的MD5: " << dst << endl; | |
// 直接对文件计算Sha256散列值 | |
string sha = CalSHA256_ByFile("c://BuidIAT.exe"); | |
cout << "文件散列值: " << sha << endl; | |
// 读入文件到内存后计算 | |
HANDLE hFile = CreateFile(L"c://BuidIAT.exe", GENERIC_READ, FILE_SHARE_READ, NULL, | |
OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL); | |
DWORD dwFileSize = GetFileSize(hFile, NULL); | |
BYTE *pData = new BYTE[dwFileSize]; | |
ReadFile(hFile, pData, dwFileSize, NULL, NULL); | |
string sha2 = CalSHA256_ByMem(pData, dwFileSize); | |
cout << "内存中文件散列值: " << sha2.c_str() << endl; | |
system("pause"); | |
return 0; | |
} |
AES 加密与解密: AES是对称加密,AES可使用16,24或32字节密钥(分别对应128,192和256位)。 Crypto++ 库缺省的密钥长度是16字节,也就是 AES:: DEFAULT_KEYLENGTH。
对于 ECB 和 CBC 模式,处理的数据必须是块大小的倍数。或者,你可以用 StreamTransformationFilter 围绕这个模式对象,并把它作为一个过滤器对象。StreamTransformationFilter 能够缓存数据到块中并根据需要填充。
using namespace std; | |
using namespace CryptoPP; | |
int main(int argc, char * argv[]) | |
{ | |
cout << "Key 长度: " << AES::DEFAULT_KEYLENGTH << endl; | |
cout << "最小长度: " << AES::MIN_KEYLENGTH << endl; | |
cout << "最大长度: " << AES::MAX_KEYLENGTH << endl; | |
cout << "Block Size: " << AES::BLOCKSIZE << endl; | |
AutoSeededRandomPool rand; | |
// 产生一个随机数的密钥 | |
SecByteBlock Key(0x00, AES::DEFAULT_KEYLENGTH); | |
rand.GenerateBlock(Key, Key.size()); | |
// 产生一个随机的初始向量 | |
SecByteBlock ival(AES::BLOCKSIZE); | |
rand.GenerateBlock(ival, ival.size()); | |
byte plainText[] = "hello lyshark"; | |
size_t Textlen = std::strlen((char*)plainText) + 1; | |
cout << "待加密字符串长度: " << Textlen << endl; | |
// 加密字符串 | |
CFB_Mode<AES>::Encryption cfbEncryption(Key, Key.size(), ival); | |
cfbEncryption.ProcessData(plainText, plainText, Textlen); | |
cout << "显示加密后的十六进制数: "; | |
StringSource strSource1(plainText, Textlen, true, new HexEncoder(new FileSink(cout))); | |
// 解密字符串 并将数据输出到Cout流上 | |
CFB_Mode<AES>::Decryption cfbDecryption(Key, Key.size(), ival); | |
cfbDecryption.ProcessData(plainText, plainText, Textlen); | |
cout << endl << "显示解密后的十六进制数: "; | |
StringSource strSource2(plainText, Textlen, true, new HexEncoder(new FileSink(cout))); | |
cout << endl; | |
system("pause"); | |
return 0; | |
} |
以下代码使用CBC模式加密与解密指定字符串。如果需要针对字符串进行加解密则需要使用以下代码实现.
using namespace std; | |
using namespace CryptoPP; | |
int main(int argc, char * argv[]) | |
{ | |
// 开辟空间并将空间赋予初始值0 | |
byte key[CryptoPP::AES::DEFAULT_KEYLENGTH], iv[CryptoPP::AES::BLOCKSIZE]; | |
memset(key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH); | |
memset(iv, 0x00, CryptoPP::AES::BLOCKSIZE); | |
// 指定需要加密的字符串与 | |
std::string plaintext = "hello lyshark this is palintext"; | |
std::string ciphertext; | |
std::string decryptedtext; | |
// 输出加密前字符串长度 | |
std::cout << "加密前字符串长度: " << plaintext.size() << " bytes" << std::endl; | |
std::cout << plaintext; | |
std::cout << std::endl << std::endl; | |
// 创建并开始加密字符串 | |
CryptoPP::AES::Encryption aesEncryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH); | |
CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, iv); | |
CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink(ciphertext)); | |
stfEncryptor.Put(reinterpret_cast<const unsigned char*>(plaintext.c_str()), plaintext.length()); | |
stfEncryptor.MessageEnd(); | |
// 输出密文长度 | |
std::cout << "加密密文长度: " << ciphertext.size() << " bytes" << std::endl; | |
for (int i = 0; i < ciphertext.size(); i++) | |
{ | |
std::cout << "0x" << std::hex << (0xFF & static_cast<byte>(ciphertext[i])) << " "; | |
} | |
std::cout << std::endl << std::endl; | |
// 解密被加密的字符串 | |
CryptoPP::AES::Decryption aesDecryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH); | |
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, iv); | |
CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink(decryptedtext)); | |
stfDecryptor.Put(reinterpret_cast<const unsigned char*>(ciphertext.c_str()), ciphertext.size()); | |
stfDecryptor.MessageEnd(); | |
// 输出解密后的字符串长度 | |
std::cout << "解密后的字符串: " << std::endl; | |
std::cout << decryptedtext; | |
std::cout << std::endl << std::endl; | |
system("pause"); | |
return 0; | |
} |
下面的示例使用CFB模式实现快速对字符串进行加解密,该模式的数据的长度并不需要是AES的块大小的倍数.
using namespace std; | |
using namespace CryptoPP; | |
int main(int argc, char * argv[]) | |
{ | |
AutoSeededRandomPool rand; | |
// 生成随机Key | |
SecByteBlock key(0x00, AES::DEFAULT_KEYLENGTH); | |
rand.GenerateBlock(key, key.size()); | |
// 生成随机IV值 | |
byte iv[AES::BLOCKSIZE]; | |
rand.GenerateBlock(iv, AES::BLOCKSIZE); | |
// 需要加密的字符串 | |
char plainText[] = "hello lyshark"; | |
int messageLen = (int)strlen(plainText) + 1; | |
// 执行快速加密 | |
CFB_Mode<AES>::Encryption cfbEncryption(key, key.size(), iv); | |
cfbEncryption.ProcessData((byte*)plainText, (byte*)plainText, messageLen); | |
cout << "加密后的数据: " << plainText << endl; | |
// 执行快速解密 | |
CFB_Mode<AES>::Decryption cfbDecryption(key, key.size(), iv); | |
cfbDecryption.ProcessData((byte*)plainText, (byte*)plainText, messageLen); | |
cout << "解密后的数据: " << plainText << endl; | |
system("pause"); | |
return 0; | |
} |
AES2 加密:
using namespace std; | |
using namespace CryptoPP; | |
// AES加密 | |
BOOL AesEncrypt(BYTE *pPassword, DWORD dwPasswordLength, BYTE *pData, DWORD &dwDataLength, DWORD dwBufferLength) | |
{ | |
BOOL bRet = TRUE; | |
HCRYPTPROV hCryptProv = NULL; | |
HCRYPTHASH hCryptHash = NULL; | |
HCRYPTKEY hCryptKey = NULL; | |
do | |
{ | |
// 获取CSP句柄 | |
bRet = CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT); | |
if (FALSE == bRet) | |
break; | |
// 创建HASH对象 | |
bRet = CryptCreateHash(hCryptProv, CALG_MD5, NULL, 0, &hCryptHash); | |
if (FALSE == bRet) | |
break; | |
// 对密钥进行HASH计算 | |
bRet = CryptHashData(hCryptHash, pPassword, dwPasswordLength, 0); | |
if (FALSE == bRet) | |
break; | |
// 使用HASH来生成密钥 | |
bRet = CryptDeriveKey(hCryptProv, CALG_AES_128, hCryptHash, CRYPT_EXPORTABLE, &hCryptKey); | |
if (FALSE == bRet) | |
break; | |
// 加密数据 | |
bRet = CryptEncrypt(hCryptKey, NULL, TRUE, 0, pData, &dwDataLength, dwBufferLength); | |
if (FALSE == bRet) | |
break; | |
} while (FALSE); | |
// 关闭释放 | |
if (hCryptKey) | |
CryptDestroyKey(hCryptKey); | |
if (hCryptHash) | |
CryptDestroyHash(hCryptHash); | |
if (hCryptProv) | |
CryptReleaseContext(hCryptProv, 0); | |
return bRet; | |
} | |
// AES解密 | |
BOOL AesDecrypt(BYTE *pPassword, DWORD dwPasswordLength, BYTE *pData, DWORD &dwDataLength, DWORD dwBufferLength) | |
{ | |
BOOL bRet = TRUE; | |
HCRYPTPROV hCryptProv = NULL; | |
HCRYPTHASH hCryptHash = NULL; | |
HCRYPTKEY hCryptKey = NULL; | |
do | |
{ | |
// 获取CSP句柄 | |
bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT); | |
if (FALSE == bRet) | |
break; | |
// 创建HASH对象 | |
bRet = CryptCreateHash(hCryptProv, CALG_MD5, NULL, 0, &hCryptHash); | |
if (FALSE == bRet) | |
break; | |
// 对密钥进行HASH计算 | |
bRet = CryptHashData(hCryptHash, pPassword, dwPasswordLength, 0); | |
if (FALSE == bRet) | |
break; | |
// 使用HASH来生成密钥 | |
bRet = CryptDeriveKey(hCryptProv, CALG_AES_128, hCryptHash, CRYPT_EXPORTABLE, &hCryptKey); | |
if (FALSE == bRet) | |
break; | |
// 解密数据 | |
bRet = CryptDecrypt(hCryptKey, NULL, TRUE, 0, pData, &dwDataLength); | |
if (FALSE == bRet) | |
break; | |
} while (FALSE); | |
// 关闭释放 | |
if (hCryptKey) | |
CryptDestroyKey(hCryptKey); | |
if (hCryptHash) | |
CryptDestroyHash(hCryptHash); | |
if (hCryptProv) | |
CryptReleaseContext(hCryptProv, 0); | |
return bRet; | |
} | |
int main(int argc, char * argv[]) | |
{ | |
BYTE pData[MAX_PATH] = { 0 }; | |
DWORD dwDataLength = 0, dwBufferLength = MAX_PATH; | |
lstrcpy((char *)pData, "hello lyshark"); | |
dwDataLength = 1 + lstrlen((char *)pData); | |
// 原始十六进制数据 | |
printf("AES 原始数据 [%d]: ", dwDataLength); | |
for (int i = 0; i < dwDataLength; i++) | |
{ | |
printf("%02x ", pData[i]); | |
} | |
printf("\n\n"); | |
// AES 加密 | |
AesEncrypt((BYTE *)"AAAVCDERFGTYHUJI", 16, pData, dwDataLength, dwBufferLength); | |
printf("AES 加密后 [%d]: ", dwDataLength); | |
for (int i = 0; i < dwDataLength; i++) | |
{ | |
printf("%02x ", pData[i]); | |
} | |
printf("\n\n"); | |
// AES 解密 | |
AesDecrypt((BYTE *)"AAAVCDERFGTYHUJI", 16, pData, dwDataLength, dwBufferLength); | |
printf("AES 解密后 [%d]: ", dwDataLength); | |
for (int i = 0; i < dwDataLength; i++) | |
{ | |
printf("%02x ", pData[i]); | |
} | |
system("pause"); | |
return 0; | |
} |
Base64加解密:
using namespace std; | |
using namespace CryptoPP; | |
void DisplayHex(BYTE *pData, DWORD dwSize) | |
{ | |
for (int i = 0; i < dwSize; i++) | |
{ | |
if ((0 != i) && (0 == i % 16)) | |
printf("\n"); | |
else if ((0 != i) && (0 == i % 8)) | |
printf(" "); | |
printf("%02X ", pData[i]); | |
} | |
printf("\n"); | |
} | |
int main(int argc, char * argv[]) | |
{ | |
unsigned char plainText[] = "hello lyshark"; | |
// 对字符串编码 | |
string encoded; | |
Base64Encoder encoder; | |
encoder.Put(plainText, sizeof(plainText)); | |
encoder.MessageEnd(); | |
word64 size = encoder.MaxRetrievable(); | |
if (size) | |
{ | |
encoded.resize(size); | |
encoder.Get((byte *)&encoded[0], encoded.size()); | |
} | |
cout << "编码后的数据: " << encoded << endl; | |
// 对字符串解码 | |
string decoded; | |
Base64Decoder decoder; | |
decoder.Put((byte *)encoded.data(), encoded.size()); | |
decoder.MessageEnd(); | |
size = decoder.MaxRetrievable(); | |
if (size && size <= SIZE_MAX) | |
{ | |
decoded.resize(size); | |
decoder.Get((byte *)&decoded[0], decoded.size()); | |
} | |
cout << "对字符串解码: " << decoded; | |
// 输出解码字符串的十六进制格式 | |
char szOriginalData[] = "hello lyshark"; | |
cout << "字符串十六进制格式: "; | |
DisplayHex((BYTE *)szOriginalData, (1 + lstrlen(szOriginalData))); | |
system("pause"); | |
return 0; | |
} |
Hash加密算法: 使用hash算法计算特定文件的Hash值.
using namespace std; | |
using namespace CryptoPP; | |
BOOL GetFileData(char *pszFilePath, BYTE **ppFileData, DWORD *pdwFileDataLength) | |
{ | |
BOOL bRet = TRUE; | |
BYTE *pFileData = NULL; | |
DWORD dwFileDataLength = 0; | |
HANDLE hFile = NULL; | |
DWORD dwTemp = 0; | |
do | |
{ | |
hFile = CreateFile(pszFilePath, GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | | |
FILE_SHARE_WRITE, NULL, OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE, NULL); | |
if (INVALID_HANDLE_VALUE == hFile) | |
{ | |
bRet = FALSE; | |
break; | |
} | |
dwFileDataLength = ::GetFileSize(hFile, NULL); | |
pFileData = new BYTE[dwFileDataLength]; | |
if (NULL == pFileData) | |
{ | |
bRet = FALSE; | |
break; | |
} | |
RtlZeroMemory(pFileData, dwFileDataLength); | |
ReadFile(hFile, pFileData, dwFileDataLength, &dwTemp, NULL); | |
// 返回 | |
*ppFileData = pFileData; | |
*pdwFileDataLength = dwFileDataLength; | |
} while (FALSE); | |
if (hFile) | |
CloseHandle(hFile); | |
return bRet; | |
} | |
BOOL CalculateHash(BYTE *pData, DWORD dwDataLength, ALG_ID algHashType, | |
BYTE **ppHashData, DWORD *pdwHashDataLength) | |
{ | |
HCRYPTPROV hCryptProv = NULL; | |
HCRYPTHASH hCryptHash = NULL; | |
BYTE *pHashData = NULL; | |
DWORD dwHashDataLength = 0; | |
DWORD dwTemp = 0; | |
BOOL bRet = FALSE; | |
do | |
{ | |
// 获得指定CSP的密钥容器的句柄 | |
bRet = CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT); | |
if (FALSE == bRet) | |
break; | |
// 创建一个HASH对象, 指定HASH算法 | |
bRet = CryptCreateHash(hCryptProv, algHashType, NULL, NULL, &hCryptHash); | |
if (FALSE == bRet) | |
break; | |
// 计算HASH数据 | |
bRet = ::CryptHashData(hCryptHash, pData, dwDataLength, 0); | |
if (FALSE == bRet) | |
break; | |
// 获取HASH结果的大小 | |
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); | |
// 获取HASH结果数据 | |
bRet = CryptGetHashParam(hCryptHash, HP_HASHVAL, pHashData, &dwHashDataLength, 0); | |
if (FALSE == bRet) | |
break; | |
// 返回数据 | |
*ppHashData = pHashData; | |
*pdwHashDataLength = dwHashDataLength; | |
} while (FALSE); | |
// 释放关闭 | |
if (FALSE == bRet) | |
{ | |
if (pHashData) | |
{ | |
delete[]pHashData; | |
pHashData = NULL; | |
} | |
} | |
if (hCryptHash) | |
CryptDestroyHash(hCryptHash); | |
if (hCryptProv) | |
CryptReleaseContext(hCryptProv, 0); | |
return bRet; | |
} | |
int main(int argc, char * argv[]) | |
{ | |
BYTE *pData = NULL; | |
DWORD dwDataLength = 0; | |
BYTE *pHashData = NULL; | |
DWORD dwHashDataLength = 0; | |
// 获取文件流数据 | |
GetFileData("c://BuidIAT.exe", &pData, &dwDataLength); | |
// 计算 MD5 | |
CalculateHash(pData, dwDataLength, CALG_MD5, &pHashData, &dwHashDataLength); | |
printf("MD5 Hash -> "); | |
for (int i = 0; i < dwHashDataLength; i++) | |
printf("%x", pHashData[i]); | |
printf("\n\n", dwHashDataLength); | |
if (pHashData) | |
{ | |
delete[]pHashData; | |
pHashData = NULL; | |
} | |
// 计算 SHA1 | |
CalculateHash(pData, dwDataLength, CALG_SHA1, &pHashData, &dwHashDataLength); | |
printf("SHA1 -> "); | |
for (int i = 0; i < dwHashDataLength; i++) | |
printf("%x", pHashData[i]); | |
printf("\n\n", dwHashDataLength); | |
if (pHashData) | |
{ | |
delete[]pHashData; | |
pHashData = NULL; | |
} | |
// 计算 SHA256 | |
CalculateHash(pData, dwDataLength, CALG_SHA_256, &pHashData, &dwHashDataLength); | |
printf("SHA256 -> "); | |
for (int i = 0; i < dwHashDataLength; i++) | |
printf("%x", pHashData[i]); | |
printf("\n\n", dwHashDataLength); | |
if (pHashData) | |
{ | |
delete[]pHashData; | |
pHashData = NULL; | |
} | |
system("pause"); | |
return 0; | |
} |
RSA加密算法: RSA算法包括公钥与私钥两部,加密时会先使用RSA生成公钥与私钥,然后在进行加密.
using namespace std; | |
// 生成公钥和私钥 | |
BOOL GenerateKey(BYTE **ppPublicKey, DWORD *pdwPublicKeyLength, BYTE **ppPrivateKey, DWORD *pdwPrivateKeyLength) | |
{ | |
BOOL bRet = TRUE; | |
HCRYPTPROV hCryptProv = NULL; | |
HCRYPTKEY hCryptKey = NULL; | |
BYTE *pPublicKey = NULL; | |
DWORD dwPublicKeyLength = 0; | |
BYTE *pPrivateKey = NULL; | |
DWORD dwPrivateKeyLength = 0; | |
do | |
{ | |
// 获取CSP句柄 | |
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, 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, dwPrivateKeyLength); | |
bRet = CryptExportKey(hCryptKey, NULL, PRIVATEKEYBLOB, 0, pPrivateKey, &dwPrivateKeyLength); | |
if (FALSE == bRet) | |
break; | |
// 返回数据 | |
*ppPublicKey = pPublicKey; | |
*pdwPublicKeyLength = dwPublicKeyLength; | |
*ppPrivateKey = pPrivateKey; | |
*pdwPrivateKeyLength = dwPrivateKeyLength; | |
} while (FALSE); | |
// 释放关闭 | |
if (hCryptKey) | |
CryptDestroyKey(hCryptKey); | |
if (hCryptProv) | |
CryptReleaseContext(hCryptProv, 0); | |
return bRet; | |
} | |
// 公钥加密数据 | |
BOOL RsaEncrypt(BYTE *pPublicKey, DWORD dwPublicKeyLength, BYTE *pData, DWORD &dwDataLength, DWORD dwBufferLength) | |
{ | |
BOOL bRet = TRUE; | |
HCRYPTPROV hCryptProv = NULL; | |
HCRYPTKEY hCryptKey = NULL; | |
do | |
{ | |
// 获取CSP句柄 | |
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 (hCryptKey) | |
CryptDestroyKey(hCryptKey); | |
if (hCryptProv) | |
CryptReleaseContext(hCryptProv, 0); | |
return bRet; | |
} | |
// 私钥解密数据 | |
BOOL RsaDecrypt(BYTE *pPrivateKey, DWORD dwProvateKeyLength, BYTE *pData, DWORD &dwDataLength) | |
{ | |
BOOL bRet = TRUE; | |
HCRYPTPROV hCryptProv = NULL; | |
HCRYPTKEY hCryptKey = NULL; | |
do | |
{ | |
// 获取CSP句柄 | |
bRet = CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0); | |
if (FALSE == bRet) | |
break; | |
// 导入私钥 | |
bRet = CryptImportKey(hCryptProv, pPrivateKey, dwProvateKeyLength, NULL, 0, &hCryptKey); | |
if (FALSE == bRet) | |
break; | |
// 解密数据 | |
bRet = CryptDecrypt(hCryptKey, NULL, TRUE, 0, pData, &dwDataLength); | |
if (FALSE == bRet) | |
break; | |
} while (FALSE); | |
// 释放并关闭 | |
if (hCryptKey) | |
CryptDestroyKey(hCryptKey); | |
if (hCryptProv) | |
CryptReleaseContext(hCryptProv, 0); | |
return bRet; | |
} | |
int main(int argc, char * argv[]) | |
{ | |
BYTE *pPublicKey = NULL; | |
DWORD dwPublicKeyLength = 0; | |
BYTE *pPrivateKey = NULL; | |
DWORD dwPrivateKeyLength = 0; | |
BYTE *pData = NULL; | |
DWORD dwDataLength = 0; | |
DWORD dwBufferLength = 4096; | |
pData = new BYTE[dwBufferLength]; | |
RtlZeroMemory(pData, dwBufferLength); | |
lstrcpy((char *)pData, "hello lyshark"); | |
dwDataLength = 1 + lstrlen((char *)pData); | |
// 输出加密前原始数据 | |
printf("加密前原始数据: "); | |
for (int i = 0; i < dwDataLength; i++) | |
printf("%x", pData[i]); | |
printf("\n\n"); | |
// 生成公钥和私钥 | |
GenerateKey(&pPublicKey, &dwPublicKeyLength, &pPrivateKey, &dwPrivateKeyLength); | |
printf("公钥: "); | |
for (int i = 0; i < dwPublicKeyLength; i++) | |
printf("%.2x", pPublicKey[i]); | |
printf("\n\n"); | |
printf("私钥: "); | |
for (int i = 0; i < dwPrivateKeyLength; i++) | |
printf("%.2x", pPrivateKey[i]); | |
printf("\n\n"); | |
// 使用公钥加密 | |
RsaEncrypt(pPublicKey, dwPublicKeyLength, pData, dwDataLength, dwBufferLength); | |
printf("公钥加密: "); | |
for (int i = 0; i < dwDataLength; i++) | |
printf("%x", pData[i]); | |
printf("\n\n"); | |
// 使用私钥解密 | |
RsaDecrypt(pPrivateKey, dwPrivateKeyLength, pData, dwDataLength); | |
printf("私钥解密: "); | |
for (int i = 0; i < dwDataLength; i++) | |
printf("%x", pData[i]); | |
printf("\n\n"); | |
delete[]pData; | |
delete[]pPrivateKey; | |
delete[]pPublicKey; | |
system("pause"); | |
return 0; | |
} |
Crypt库实现RSA加密: RSA加密一般使用公钥加密私钥解密,先生成公钥与私钥,然后使用这两份密钥对字符串等数据进行操作.
using namespace std; | |
using namespace CryptoPP; | |
// 定义全局随机数池 | |
RandomPool & GlobalRNG(); | |
RandomPool & GlobalRNG() | |
{ | |
static RandomPool randomPool; | |
return randomPool; | |
} | |
// 生成RSA密钥对 | |
BOOL GenerateRSAKey(DWORD dwRSAKeyLength, char *pszPrivateKeyFileName, char *pszPublicKeyFileName, BYTE *pSeed, DWORD dwSeedLength) | |
{ | |
RandomPool randPool; | |
randPool.Put(pSeed, dwSeedLength); | |
// 生成RSA私钥 | |
RSAES_OAEP_SHA_Decryptor priv(randPool, dwRSAKeyLength); | |
HexEncoder privFile(new FileSink(pszPrivateKeyFileName)); // 打开文件实行序列化操作 | |
priv.DEREncode(privFile); | |
privFile.MessageEnd(); | |
// 生成RSA公钥 | |
RSAES_OAEP_SHA_Encryptor pub(priv); | |
HexEncoder pubFile(new FileSink(pszPublicKeyFileName)); // 打开文件实行序列化操作 | |
pub.DEREncode(pubFile); // 写密码对象pub到文件对象pubFile里 | |
pubFile.MessageEnd(); | |
return TRUE; | |
} | |
/* 此处的加密算法是通过文件中的公钥与私钥进行加密的*/ | |
// RSA加密字符串 | |
string RSA_Encrypt_ByFile(char *pszOriginaString, char *pszPublicKeyFileName, BYTE *pSeed, DWORD dwSeedLength) | |
{ | |
RandomPool randPool; | |
randPool.Put(pSeed, dwSeedLength); | |
FileSource pubFile(pszPublicKeyFileName, TRUE, new HexDecoder); | |
RSAES_OAEP_SHA_Encryptor pub(pubFile); | |
// 加密 | |
string strEncryptString; | |
StringSource(pszOriginaString, TRUE, new PK_EncryptorFilter(randPool, pub, new HexEncoder(new StringSink(strEncryptString)))); | |
return strEncryptString; | |
} | |
// RSA解密字符串 | |
string RSA_Decrypt_ByFile(char *pszEncryptString, char *pszPrivateKeyFileName) | |
{ | |
FileSource privFile(pszPrivateKeyFileName, TRUE, new HexDecoder); | |
RSAES_OAEP_SHA_Decryptor priv(privFile); | |
string strDecryptString; | |
StringSource(pszEncryptString, TRUE, new HexDecoder(new PK_DecryptorFilter(GlobalRNG(), priv, new StringSink(strDecryptString)))); | |
return strDecryptString; | |
} | |
/* 通过在内存中的密钥对进行加密与解密 */ | |
// RSA加密字符串 | |
string RSA_Encrypt_ByMem(char *pszOriginaString, char *pszMemPublicKey, BYTE *pSeed, DWORD dwSeedLength) | |
{ | |
RandomPool randPool; | |
randPool.Put(pSeed, dwSeedLength); | |
StringSource pubStr(pszMemPublicKey, TRUE, new HexDecoder); | |
RSAES_OAEP_SHA_Encryptor pub(pubStr); | |
// 加密 | |
string strEncryptString; | |
StringSource(pszOriginaString, TRUE, new PK_EncryptorFilter(randPool, pub, new HexEncoder(new StringSink(strEncryptString)))); | |
return strEncryptString; | |
} | |
// RSA解密字符串 | |
string RSA_Decrypt_ByMem(char *pszEncryptString, char *pszMemPrivateKey) | |
{ | |
StringSource privStr(pszMemPrivateKey, TRUE, new HexDecoder); | |
RSAES_OAEP_SHA_Decryptor priv(privStr); | |
string strDecryptString; | |
StringSource(pszEncryptString, TRUE, new HexDecoder(new PK_DecryptorFilter(GlobalRNG(), priv, new StringSink(strDecryptString)))); | |
return strDecryptString; | |
} | |
int main(int argc, char * argv[]) | |
{ | |
// 指定公钥与私钥所在文件目录 | |
char szPrivateFile[] = "c://private.key"; | |
char szPublicFile[] = "c://public.key"; | |
// 指定一串随机数种子 | |
char szSeed[] = "ABCDESGHETYSQDGH"; | |
// 以下就是待加密的字符串 | |
char szOriginalString[] = "hello lyshark"; | |
/* 此处是从文件中读取出公钥与私钥对特定字符串进行加密与解密 */ | |
// 生成RSA公私密钥对 | |
GenerateRSAKey(1024, szPrivateFile, szPublicFile, (BYTE *)szSeed, lstrlen(szSeed)); | |
// RSA公钥加密字符串 | |
string strEncryptString = RSA_Encrypt_ByFile(szOriginalString, szPublicFile, (BYTE *)szSeed, lstrlen(szSeed)); | |
// RSA私钥解密字符串 | |
string strDecryptString = RSA_Decrypt_ByFile((char *)strEncryptString.c_str(), szPrivateFile); | |
// 显示 | |
printf("原文字符串:\t[%d]%s\n", lstrlen(szOriginalString), szOriginalString); | |
printf("密文字符串:\t[%d]%s\n", strEncryptString.length(), strEncryptString.c_str()); | |
printf("明文字符串:\t[%d]%s\n", strDecryptString.length(), strDecryptString.c_str()); | |
printf("\n\n"); | |
// -------------------------------------------------------------------------------------------------------------- | |
/* 此处是在内存中对指定字符串进行解密*/ | |
char g_szPubKey[] = "填充公钥"; | |
char g_szPrivKey[] = "填充私钥"; | |
// RSA公钥加密字符串 | |
string strEncryptString_Mem = RSA_Encrypt_ByMem(szOriginalString, g_szPubKey, (BYTE *)szSeed, ::lstrlen(szSeed)); | |
// RSA私钥解密字符串 | |
string strDecryptString_Mem = RSA_Decrypt_ByMem((char *)strEncryptString_Mem.c_str(), g_szPrivKey); | |
// 显示 | |
printf("原文字符串:\n[%d]%s\n", ::lstrlen(szOriginalString), szOriginalString); | |
printf("密文字符串:\n[%d]%s\n", strEncryptString_Mem.length(), strEncryptString_Mem.c_str()); | |
printf("明文字符串:\n[%d]%s\n", strDecryptString_Mem.length(), strDecryptString_Mem.c_str()); | |
system("pause"); | |
return 0; | |
} |
AES加密解密:
//计算hash值 | |
BOOL CalculateHash(BYTE* pData, DWORD dwDataLength, ALG_ID algHashType, BYTE** ppHashData, DWORD* pdwHashDataLength) | |
{ | |
BOOL bRet = FALSE; | |
HCRYPTPROV hCryptProv = NULL; | |
HCRYPTHASH hCryptHash = NULL; | |
DWORD dwTemp = 0; | |
DWORD dwHashDataLength = 0; | |
BYTE* pHashData = NULL; | |
// 获得指定CSP的密钥容器的句柄 | |
bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT); | |
if (FALSE == bRet) | |
{ | |
return FALSE; | |
} | |
// 创建一个HASH对象, 指定HASH算法 | |
bRet = ::CryptCreateHash(hCryptProv, algHashType, NULL, NULL, &hCryptHash); | |
if (FALSE == bRet) | |
{ | |
CryptReleaseContext(hCryptProv, 0); | |
return FALSE; | |
} | |
// 计算HASH数据 | |
bRet = ::CryptHashData(hCryptHash, pData, dwDataLength, 0); | |
if (FALSE == bRet) | |
{ | |
CryptDestroyHash(hCryptHash); | |
CryptReleaseContext(hCryptProv, 0); | |
return FALSE; | |
} | |
// 获取HASH结果的大小 | |
dwTemp = sizeof(dwHashDataLength); | |
bRet = ::CryptGetHashParam(hCryptHash, HP_HASHSIZE, (BYTE*)(&dwHashDataLength), &dwTemp, 0); | |
if (FALSE == bRet) | |
{ | |
CryptDestroyHash(hCryptHash); | |
CryptReleaseContext(hCryptProv, 0); | |
return FALSE; | |
} | |
// 申请内存 | |
pHashData = new BYTE[dwHashDataLength]{ 0 }; | |
if (NULL == pHashData) | |
{ | |
CryptDestroyHash(hCryptHash); | |
CryptReleaseContext(hCryptProv, 0); | |
return FALSE; | |
} | |
// 获取HASH结果数据 | |
bRet = ::CryptGetHashParam(hCryptHash, HP_HASHVAL, pHashData, &dwHashDataLength, 0); | |
if (FALSE == bRet) | |
{ | |
delete[] pHashData; | |
pHashData = NULL; | |
CryptDestroyHash(hCryptHash); | |
CryptReleaseContext(hCryptProv, 0); | |
return FALSE; | |
} | |
// 返回数据 | |
*ppHashData = pHashData; | |
*pdwHashDataLength = dwHashDataLength; | |
// 释放关闭 | |
CryptDestroyHash(hCryptHash); | |
CryptReleaseContext(hCryptProv, 0); | |
return TRUE; | |
} | |
// AES加密 | |
BOOL AesEncrypt(BYTE* pPassword, DWORD dwPasswordLength, BYTE* pData, DWORD& dwDataLength, DWORD dwBufferLength) | |
{ | |
BOOL bRet = TRUE; | |
HCRYPTPROV hCryptProv = NULL; | |
HCRYPTHASH hCryptHash = NULL; | |
HCRYPTKEY hCryptKey = NULL; | |
do { | |
// 获取CSP句柄 | |
bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT); | |
if (FALSE == bRet) | |
{ | |
break; | |
} | |
// 创建HASH对象 | |
bRet = ::CryptCreateHash(hCryptProv, CALG_MD5, NULL, 0, &hCryptHash); | |
if (FALSE == bRet) | |
{ | |
break; | |
} | |
// 对密钥进行HASH计算 计算出密钥的MD5值 | |
bRet = ::CryptHashData(hCryptHash, pPassword, dwPasswordLength, 0); | |
if (FALSE == bRet) | |
{ | |
break; | |
} | |
// 使用HASH来生成密钥 | |
bRet = ::CryptDeriveKey(hCryptProv, CALG_AES_128, hCryptHash, CRYPT_EXPORTABLE, &hCryptKey); | |
if (FALSE == bRet) | |
{ | |
break; | |
} | |
// 加密数据 | |
bRet = ::CryptEncrypt(hCryptKey, NULL, TRUE, 0, pData, &dwDataLength, dwBufferLength); | |
if (FALSE == bRet) | |
{ | |
break; | |
} | |
} while (FALSE); | |
// 关闭释放 | |
if (hCryptKey) | |
{ | |
CryptDestroyKey(hCryptKey); | |
} | |
if (hCryptHash) | |
{ | |
CryptDestroyHash(hCryptHash); | |
} | |
if (hCryptProv) | |
{ | |
CryptReleaseContext(hCryptProv, 0); | |
} | |
return bRet; | |
} | |
// AES解密 | |
BOOL AesDecrypt(BYTE* pPassword, DWORD dwPasswordLength, BYTE* pData, DWORD& dwDataLength) | |
{ | |
BOOL bRet = TRUE; | |
HCRYPTPROV hCryptProv = NULL; | |
HCRYPTHASH hCryptHash = NULL; | |
HCRYPTKEY hCryptKey = NULL; | |
do | |
{ | |
// 获取CSP句柄 | |
bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT); | |
if (FALSE == bRet) | |
{ | |
break; | |
} | |
// 创建HASH对象 | |
bRet = ::CryptCreateHash(hCryptProv, CALG_MD5, NULL, 0, &hCryptHash); | |
if (FALSE == bRet) | |
{ | |
break; | |
} | |
// 对密钥进行HASH计算 | |
bRet = ::CryptHashData(hCryptHash, pPassword, dwPasswordLength, 0); | |
if (FALSE == bRet) | |
{ | |
break; | |
} | |
// 使用HASH来生成密钥 | |
bRet = ::CryptDeriveKey(hCryptProv, CALG_AES_128, hCryptHash, CRYPT_EXPORTABLE, &hCryptKey); | |
if (FALSE == bRet) | |
{ | |
break; | |
} | |
// 解密数据 | |
bRet = ::CryptDecrypt(hCryptKey, NULL, TRUE, 0, pData, &dwDataLength); | |
if (FALSE == bRet) | |
{ | |
break; | |
} | |
} while (FALSE); | |
// 关闭释放 | |
if (hCryptKey) | |
{ | |
CryptDestroyKey(hCryptKey); | |
} | |
if (hCryptHash) | |
{ | |
CryptDestroyHash(hCryptHash); | |
} | |
if (hCryptProv) | |
{ | |
CryptReleaseContext(hCryptProv, 0); | |
} | |
return bRet; | |
} | |
int main(int argc, char * argv[]) | |
{ | |
} |