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的信息摘要

#include <iostream>
#include <Windows.h>
#include <string>
#include <sha.h>
#include <md5.h>
#include <crc.h>
#include <files.h>
#include <hex.h> #pragma comment(lib, "cryptlib.lib")
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 能够缓存数据到块中并根据需要填充。

#include<cryptlib.h>
#include<osrng.h>
#include<iostream>
#include<files.h>
#include<aes.h>
#include<modes.h>
#include<hex.h> #pragma comment(lib, "cryptlib.lib")
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模式加密与解密指定字符串。如果需要针对字符串进行加解密则需要使用以下代码实现.

#include<cryptlib.h>
#include<osrng.h>
#include<iostream>
#include<files.h>
#include<aes.h>
#include<modes.h>
#include<hex.h> #pragma comment(lib, "cryptlib.lib")
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的块大小的倍数.

#include<cryptlib.h>
#include<osrng.h>
#include<iostream>
#include<files.h>
#include<aes.h>
#include<modes.h>
#include<hex.h> #pragma comment(lib, "cryptlib.lib")
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 加密:

#include<cryptlib.h>
#include<iostream>
#include <Windows.h> #pragma comment(lib, "cryptlib.lib")
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加解密:

#include<cryptlib.h>
#include<osrng.h>
#include<iostream>
#include <Windows.h>
#include<files.h>
#include<base64.h>
#include<modes.h>
#include<hex.h> #pragma comment(lib, "cryptlib.lib")
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值.

#include<cryptlib.h>
#include<iostream>
#include <Windows.h> #pragma comment(lib, "cryptlib.lib")
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生成公钥与私钥,然后在进行加密.

#include<iostream>
#include <Windows.h> 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加密一般使用公钥加密私钥解密,先生成公钥与私钥,然后使用这两份密钥对字符串等数据进行操作.

#include<cryptlib.h>
#include<osrng.h>
#include<iostream>
#include<files.h>
#include <Windows.h>
#include <rsa.h>
#include <hex.h>
#include<modes.h> #pragma comment(lib, "cryptlib.lib")
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加密解密:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <Windows.h> //计算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[])
{
}

C/C++ Crypto密码库调用方法的更多相关文章

  1. Phpcms v9系统类库与函数库调用方法

    在分享了n多phpcms的教程后,cmsyou继续分享关于phpcms v9系统类库与函数库的调用方法. 系统类库位于系统的 /libs/functions目录下面,函数库文件名为*.func.php ...

  2. Eclipse中Android公共库的正确建立及调用方法

    Eclipse中Android公共库的正确建立及调用方法 引言 之前一直头痛于没有办法在多个程序中共享资源,用作公共类库的方法也是使用的导出jar再导入的办法,现在终于初步搞明白了,可算解脱了~,分享 ...

  3. android开发源代码分析--多个activity调用多个jni库的方法

    android开发源代码分析--多个activity调用多个jni库的方法 有时候,我们在开发android项目时会遇到须要调用多个native c/jni库文件,下面是本人以前实现过的方法,假设有知 ...

  4. 一个简单的C共享库的创建及Python调用此库的方法

    /********************************************************************* * Author  : Samson * Date    ...

  5. C#调用js库的方法

    前言 用.net6开发一个Winform程序,处理Excel文件,并把结果导出Excel文件. 要用到两个算法,一是turf.js库的booleanPointInPolygon方法,判断经纬度坐标是否 ...

  6. golang 编译或链接 c语言动态、静态库的方法, golang 与 c语言 相互调用

    1.golang链接c静态库的方法可以见这个示例: https://github.com/atercattus/go-static-link-example https://github.com/sh ...

  7. (转)libcurl库使用方法,好长,好详细。

    一.ibcurl作为是一个多协议的便于客户端使用的URL传输库,基于C语言,提供C语言的API接口,支持DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP ...

  8. MySQL程序端启动密码错误解决方法

    MySQL程序端启动密码错误解决方法 一般启动MySQL程序端,都是用mysql -uroot -p命令,当然前提是你的环境变量已经配好了. 为了连接服务器,当调用mysql时,通常需要提供一个MyS ...

  9. C# 读写opc ua服务器,浏览所有节点,读写节点,读历史数据,调用方法,订阅,批量订阅操作

    OPC UA简介 OPC是应用于工业通信的,在windows环境的下一种通讯技术,原有的通信技术难以满足日益复杂的环境,在可扩展性,安全性,跨平台性方面的不足日益明显,所以OPC基金会在几年前提出了面 ...

  10. python中requests库使用方法详解

    目录 python中requests库使用方法详解 官方文档 什么是Requests 安装Requests库 基本的GET请求 带参数的GET请求 解析json 添加headers 基本POST请求 ...

随机推荐

  1. POJ 2484博弈——对称法

    题目链接:http://poj.org/problem?id=2484 题意:Alice和Bob玩游戏,从一堆圆环形排列的硬币中拿硬币,每次可以拿一个或者两个,但必须拿连续的(两个中间有空位也视为不连 ...

  2. AtCoder Beginner Contest 163 (6/6)

    比赛链接:Here AB水题, C - management 题意:给一棵 \(N(2\le N\le2e5)\)​ 个节点的有根树,求每个节点的儿子数. 思路:由于输入直接给的是每个节点的父节点,直 ...

  3. Android 3分钟带你入门开发测试

    作者:Zhu Yifei 作为一名合格的开发人员,基本的开发测试能力必不可少,开发测试分单元测试和UI测试,通过开发测试可以减少开发人员自测时间,提升开发质量.本篇文章可以帮助初级开发人员快速了解开发 ...

  4. 2020年了,再不会webpack敲得代码就不香了(近万字实战)

    https://zhuanlan.zhihu.com/p/99959392?utm_source=wechat_session&utm_medium=social&utm_oi=619 ...

  5. Bash 常用命令总结

    基础常用命令 某个命令 --h,对这个命令进行解释 某个命令 --help,解释这个命令(更详细) man某个命令,文档式解释这个命令(更更详细)(执行该命令后,还可以按/+关键字进行查询结果的搜索) ...

  6. python之排序的几种方法

    一.通过sort()可以快速实现数组的排序: 1 a=[2,3,1] 2 a.sort() 3 print(a) 打印返回结果: 二.如果不知道有sort()函数或者一些特殊场景需要排序时,如果解决呢 ...

  7. 机器学习-概率图模型系列-隐含马尔科夫-维特比算法解码隐藏序列-HMM模型参数估计-36

    目录 待补充 参考资料 刘建平博客 pinard

  8. Mysql 中 not in 的查询优化

    本文为博主原创,转载请注明出处: 最近做性能优化时,通过开启 MySQL 的慢日志查询配置,发现 有一条慢sql,在这里记录下分析和优化的过程. 该慢 sql 如下: select id from f ...

  9. Postman 压力测试

    本文为博主原创,未经允许不得转载: postman 还提供了接口压力测试的功能,通过这种方式可以测试接口性能. 若接口测试需要通过pre s单独封装进行计算一些参数时,可以参考我的上一篇博客: Pos ...

  10. C#调用C++——CLR方式

    一直是在写C#,最近接触到的项目中有C#调用C++接口的逻辑,自己学习了下,写个步骤日志,C#掉用C++的托管代码 项目分三个项目:1.底层C++动态库项目,2.中间层的CLR项目,3.上层的C#项目 ...