C/C++Cryptパスワードライブラリ呼び出しの実現方法
31120 ワード
CryptライブラリはC/C++の暗号化アルゴリズムライブラリです。この暗号化ライブラリはとても人気があります。基本的には市場の各種暗号解読アルゴリズムをカバーしています。以下のコードは勉強しています。まとめました。ここに置いて後期に必要な時に素早く解決できます。
プロジェクト住所:https://www.cryptopp.com/
Sha 256暗号化アルゴリズム
Shaシリーズの暗号化アルゴリズムは多くのものを含み、基本的には以下のいくつかのフォーマットの暗号化方式があり、ビット数が大きいほど暗号化強度が大きくなり、このアルゴリズムは一方向暗号化アルゴリズムとMD 5が似ていますが、安全性はMD 5より高いです。 SHA-1:ダイジェストを生成する性能はMD 5よりやや低い SHA-256:長さ256 bitの情報ダイジェスト を生成することができます。 SHA-224:長さ224 bitの情報ダイジェスト を生成することができます。 SHA-384:長さ384 bitを生成できる情報要約 SHA-512:長さ512 bitを生成できる情報ダイジェスト
AESは対称暗号化であり、AESは16、24または32バイトの鍵(それぞれ128、192、256ビットに対応)を使用することができる。Crypt++ライブラリデフォルトの鍵の長さは16バイト、つまりAES:DEFAULT_KEYLENGTH。
ECBおよびCBCモードに対しては、処理データはブロックサイズの倍数でなければならない。あるいは、このモードの対象をStreamTrans formationFilterで囲んで、フィルタの対象として使ってもいいです。StreamTrans formationFilterは、データをブロックにキャッシュし、必要に応じて充填することができる。
hashアルゴリズムを使って特定のファイルのHash値を計算します。
RSAアルゴリズムは公開鍵と秘密鍵の2つを含み、暗号化の際はRSAを使用して公開鍵と秘密鍵を生成して暗号化しています。
RSA暗号化は、一般的に公開鍵を使って秘密鍵を復号し、公開鍵と秘密鍵として使用し、この2つの鍵を使って文字列などのデータを操作する。
プロジェクト住所:https://www.cryptopp.com/
Sha 256暗号化アルゴリズム
Shaシリーズの暗号化アルゴリズムは多くのものを含み、基本的には以下のいくつかのフォーマットの暗号化方式があり、ビット数が大きいほど暗号化強度が大きくなり、このアルゴリズムは一方向暗号化アルゴリズムとMD 5が似ていますが、安全性はMD 5より高いです。
#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ビットに対応)を使用することができる。Crypt++ライブラリデフォルトの鍵の長さは16バイト、つまりAES:DEFAULT_KEYLENGTH。
ECBおよびCBCモードに対しては、処理データはブロックサイズの倍数でなければならない。あるいは、このモードの対象をStreamTrans formationFilterで囲んで、フィルタの対象として使ってもいいです。StreamTrans formationFilterは、データをブロックにキャッシュし、必要に応じて充填することができる。
#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;
}
AES 2暗号化:
#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("
");
// AES
AesEncrypt((BYTE *)"AAAVCDERFGTYHUJI", 16, pData, dwDataLength, dwBufferLength);
printf("AES [%d]: ", dwDataLength);
for (int i = 0; i < dwDataLength; i++)
{
printf("%02x ", pData[i]);
}
printf("
");
// 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;
}
Base 64の復号:
#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("
");
else if ((0 != i) && (0 == i % 8))
printf(" ");
printf("%02X ", pData[i]);
}
printf("
");
}
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("
", 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("
", 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("
", dwHashDataLength);
if (pHashData)
{
delete[]pHashData;
pHashData = NULL;
}
system("pause");
return 0;
}
RSA暗号化アルゴリズムRSAアルゴリズムは公開鍵と秘密鍵の2つを含み、暗号化の際は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("
");
//
GenerateKey(&pPublicKey, &dwPublicKeyLength, &pPrivateKey, &dwPrivateKeyLength);
printf(" : ");
for (int i = 0; i < dwPublicKeyLength; i++)
printf("%.2x", pPublicKey[i]);
printf("
");
printf(" : ");
for (int i = 0; i < dwPrivateKeyLength; i++)
printf("%.2x", pPrivateKey[i]);
printf("
");
//
RsaEncrypt(pPublicKey, dwPublicKeyLength, pData, dwDataLength, dwBufferLength);
printf(" : ");
for (int i = 0; i < dwDataLength; i++)
printf("%x", pData[i]);
printf("
");
//
RsaDecrypt(pPrivateKey, dwPrivateKeyLength, pData, dwDataLength);
printf(" : ");
for (int i = 0; i < dwDataLength; i++)
printf("%x", pData[i]);
printf("
");
delete[]pData;
delete[]pPrivateKey;
delete[]pPublicKey;
system("pause");
return 0;
}
CryptライブラリはRSA暗号化を実現します。RSA暗号化は、一般的に公開鍵を使って秘密鍵を復号し、公開鍵と秘密鍵として使用し、この2つの鍵を使って文字列などのデータを操作する。
#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
", lstrlen(szOriginalString), szOriginalString);
printf(" :\t[%d]%s
", strEncryptString.length(), strEncryptString.c_str());
printf(" :\t[%d]%s
", strDecryptString.length(), strDecryptString.c_str());
printf("
");
// --------------------------------------------------------------------------------------------------------------
/* */
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(" :
[%d]%s
", ::lstrlen(szOriginalString), szOriginalString);
printf(" :
[%d]%s
", strEncryptString_Mem.length(), strEncryptString_Mem.c_str());
printf(" :
[%d]%s
", strDecryptString_Mem.length(), strDecryptString_Mem.c_str());
system("pause");
return 0;
ここでC/C++Cryptパスワードライブラリの呼び出しの実現方法についての記事を紹介します。C++Cryptパスワードライブラリの詳細については、以前の記事を検索したり、下記の関連記事を見たりしてください。これからもよろしくお願いします。