广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C/C++ Crypto密码库调用的实现方法
  • 741
分享到

C/C++ Crypto密码库调用的实现方法

2024-04-02 19:04:59 741人浏览 独家记忆
摘要

目录Sha256加密算法AES 加密与解密AES2 加密:Base64加解密:Hash加密算法RSA加密算法Crypt库实现RSA加密Crypto 库是C/C++的加密算法库,这个加

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;

到此这篇关于C/c++ Crypto密码库调用的实现方法的文章就介绍到这了,更多相关C++ Crypto密码库内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C/C++ Crypto密码库调用的实现方法

本文链接: https://www.lsjlt.com/news/129495.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C/C++ Crypto密码库调用的实现方法
    目录Sha256加密算法AES 加密与解密AES2 加密:Base64加解密:Hash加密算法RSA加密算法Crypt库实现RSA加密Crypto 库是C/C++的加密算法库,这个加...
    99+
    2022-11-12
  • c#调用c++的DLL的实现方法
    目录1.采用托管的方式进行调用,就和正常调用c#的dll一样2.非托管的方式进行调用C#是托管型代码,创建的对象会自动回收。C++是非托管型代码,创建的对象需要手动回收(有时不手动回...
    99+
    2022-11-13
  • C调用C++代码的方法步骤
    有时C程序里需要用到C++的类,但是C语言又不能直接调用类,这时需要把C++的类使用C接口封装后,再调用, 可以将封装后的C++代码编译成库文件,供C语言调用; 需要注意的是,封装的...
    99+
    2022-11-12
  • C#调用js库的方法示例代码
    目录前言安装ClearScript引入js文件创建V8ScriptEngine对象通过js引擎加载js文件C#调用js方法实现经纬度坐标纠偏C#调用js方法判断经纬度点位是否在多边形...
    99+
    2023-01-17
    C#调用js库 C# js库 C#调用js
  • C调用C++代码的方法是什么
    这篇文章主要介绍“C调用C++代码的方法是什么”,在日常操作中,相信很多人在C调用C++代码的方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C调用C++代码的方法是什么”的疑惑有所帮助!接下来,请跟...
    99+
    2023-06-25
  • C#调用js库的方法小结
    目录前言安装ClearScript引入js文件创建V8ScriptEngine对象通过js引擎加载js文件C#调用js方法实现经纬度坐标纠偏C#调用js方法判断经纬度点位是否在多边形...
    99+
    2023-05-14
    C#调用js
  • C++调用动态库和Python调用C++动态库的方法是什么
    这篇文章主要介绍“C++调用动态库和Python调用C++动态库的方法是什么”,在日常操作中,相信很多人在C++调用动态库和Python调用C++动态库的方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答...
    99+
    2023-07-05
  • SQLSERVER调用C#的代码实现
    简单例子 首先写一段简单的 C# 代码,然后把它编译成 dll。 namespace Bussiness { public class UserFunctions { public sta...
    99+
    2023-01-30
    SQLSERVER调用C#
  • C++代码调用C#代码的过程怎么实现
    这篇文章主要讲解了“C++代码调用C#代码的过程怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++代码调用C#代码的过程怎么实现”吧!首先建立一个C#工程Class Library...
    99+
    2023-06-17
  • c++动态库调用的实现
    目录一、生成dll二、调用dll在平时的开发中某些情况,动态库和静态库是程序开发的不二法门,例如封装一个库,供别人调用(日志库、字符串处理库、设备信息采集库等),比如接入第三方系统或...
    99+
    2022-11-13
  • JNI实现最简单的JAVA调用C/C++代码
    JNI,是Java Native Interface的简称,中文是“Java本地调用”。通过这种技术可以做到以下两点: Java程序中的函数可以调用Native语言写的函数,Native一般指的是C/C++编写的函数。 Native程序...
    99+
    2023-05-31
    java jni ava
  • Python使用Crypto库实现加密解密的示例详解
    目录一:crypto库安装二:python使用crypto1:crypto的加密解密组件des.py2:crypto组件使用知识补充一:crypto库安装 pycrypto,pycr...
    99+
    2023-01-11
    Python Crypto加密解密 Python Crypto加密 Python Crypto解密 Python Crypto
  • C#后台调用WebApi接口的实现方法
    目录1.WebRequest方式2.HttpClient 方式1.WebRequest方式 private void button1_Click(object sender, Eve...
    99+
    2022-11-13
  • c++实现md5加密的代码
    最近发现md5加密算法挺有趣,特点是单向加密不可逆,加密后的字符串长度相等,于是就用C++尝试实现了一下 头文件定义 #ifndef __MD5_ENCODE_H__ #defin...
    99+
    2022-11-13
  • C#调用C++动态库接口函数和回调函数方法
    目录1. 前言2. 普通接口函数调用示例2.1 C++端编写接口2.2 C#端调用3. 回调函数调用示例3.1 C++端编写接口3.2 C#端调用1. 前言 需求: 当前C已经写好了...
    99+
    2022-11-13
  • C#实现加密的几种方法介绍
    1.ACSII码加密 //ACSII码加密 private static string ACSIIPWd(string rpwd) { ...
    99+
    2022-11-13
  • C++实现LeetCode(91.解码方法)
    [LeetCode] 91. Decode Ways 解码方法 A message containing letters from A-Z is being en...
    99+
    2022-11-12
  • golang调用c语言动态库方式实现
    下面我们自己在 Linux 下做一个动态库(.so 文件 - Shared Object),然在用 Go 来使用它。本文所用的操作系统为 Ubuntu18.04, 以 gcc 作为编...
    99+
    2022-11-12
  • C#反射调用拓展类方法实例代码
    目录C# 类拓展方法C#反射调用拓展类总结 今天封装Protobuf封包时候遇到一个问题; Protobuf的反序列化方法MergeFrom,是写在扩展类里的; C# 类拓...
    99+
    2022-11-13
  • Linux中rm命令使用及C/C++代码实现的方法
    本篇内容介绍了“Linux中rm命令使用及C/C++代码实现的方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!前言rm 命令是 Unix/...
    99+
    2023-06-30
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作