1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
#include <iostream>
#include <cstring>
#include <string>
#include <fstream>
#include <utility>
#define _WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <Wincrypt.h>
std::pair<HCRYPTKEY, HCRYPTHASH> Encode(BYTE* Msg, DWORD Buffer, DWORD* Message_Size);
DWORD Decode(BYTE* Msg, DWORD Buffer, DWORD* Message_Size, std::pair<HCRYPTKEY, HCRYPTHASH>);
HCRYPTPROV cProvider;
int main()
{
std::string Data_To_Encrypt = "This Is Plain Text";
const DWORD Buffer_Size = 256;
if(Data_To_Encrypt.length() > Buffer_Size)
{
std::cout << "ERROR! BUFFER OVER RUN!\n";
return 1;
}
char RawData[Buffer_Size];
sprintf_s(RawData, Buffer_Size, Data_To_Encrypt.c_str());
BYTE* bRData = reinterpret_cast<BYTE*>(RawData);
DWORD Message_Size = Data_To_Encrypt.length() + 1;
std::pair<HCRYPTKEY, HCRYPTHASH> cKeyPair(Encode(bRData, Buffer_Size, &Message_Size));
///THE DATA IN 'RawData' IS NOW ENCRYPTED SEE OUTPUT IN "Message.txt"
Decode(bRData, Buffer_Size, &Message_Size, cKeyPair);
CryptReleaseContext(cProvider, 0);
return 0;
}
std::pair<HCRYPTKEY, HCRYPTHASH> Encode(BYTE* Msg, DWORD Buffer, DWORD* Message_Size)
{
std::ofstream oFile("Message.txt", std::ios_base::binary);
//std::cout << "DEBUG - Encoded Message Size: " << EncryptedSize << "\nMessage_Size: " << Message_Size << "\n\nMessage: " << Msg << "\n";
HCRYPTKEY cKey = NULL;
HCRYPTHASH cHash;
DWORD Blob_Size = 0;
BYTE* pcKeyBLOB;
try
{
//if(!CryptAcquireContextA(&cProvider, "My_Key", MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET)) ///CREATES NAMED KEY
//if(!CryptAcquireContextA(&cProvider, "My_Key", MS_DEF_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET)) ///DELETES NAMED KEY
if(!CryptAcquireContextA(&cProvider, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) ///CREATES TEMPORARY KEY.
{
throw 1;
}
if(!CryptGenKey(cProvider, CALG_RSA_KEYX, RSA1024BIT_KEY, &cKey)) ///GENERATE RANDOM SESSION KEY FROM THE PROVIDER
{
throw 2;
}
if(!CryptCreateHash(cProvider, CALG_MD5, 0, 0, &cHash)) ///GRAB HASH OBJECT FROM PROVIDER
{
throw 3;
}
if(!CryptEncrypt(cKey, cHash, TRUE, 0, Msg, Message_Size, Buffer)) ///ENCRYPT TARGET
{
throw 4;
}
oFile << "Encrypted Message: ";
oFile.write((char*)Msg, *Message_Size); ///YOU DON'T WANT, OR NEED THE STREAM OPERATOR HERE BECAUSE THE RESULTING DATA MAY INCLUDE WHITESPACE (WS) CHARACTERS
CryptExportKey(cKey, NULL, PUBLICKEYBLOB, CRYPT_OAEP, NULL, &Blob_Size); ///THIS IS M$'S WAY OF GETTING THE NECESSARY SIZE OF BLOB
//std::cout << "DEBUG - Blob_Size: " << Blob_Size << "\n" << GetLastError() << "\n";
pcKeyBLOB = new BYTE[Blob_Size]; ///DYNAMIC ALLOCATIONS OF PREVIOUSLY UNKNOWN SIZE ARRAY
if(!CryptExportKey(cKey, NULL, PUBLICKEYBLOB, CRYPT_OAEP, pcKeyBLOB, &Blob_Size)) ///EXPORT THE KEY USED TO A BLOB
{
throw 5;
}
oFile << "\n\n\n"; ///JUST SOME WS BETWEEN THE NON-SENSE AS A VISUAL AID
oFile << "Key Blob:\n"; ///THING OF THIS AS A "HEADER"
oFile.write((char*)pcKeyBLOB, Blob_Size); ///JUST LIKE THE ENCRYPTED MESSAGE. NO STREAM OPERATORS
std::cout << "\nDONE\n";
}
catch(int& Error)
{
std::cout << "\nError At: " << Error << "\nError Code: " << GetLastError() << "\n";
}
std::pair<HCRYPTKEY, HCRYPTHASH>cKHPair(std::make_pair(cKey, cHash));
memset(pcKeyBLOB, 0, Blob_Size); ///IN CASE THE CRYPTO PROVIDER DOES NOT ZERO OUT THE MEMORY THEMSELVES YOU SHOULD DO IT
delete [] pcKeyBLOB;
//CryptDestroyHash(cHash); ///NOTICE THAT THESE THREE ARE COMMENTED OUT
//CryptDestroyKey(cKey); ///RELEASING ANY OF THESE HERE PREVENTS YOU FROM DECRYPTING DATA LATER ON IN YOUR APP UNLESS YOU READ THE DATA BACK IN
//CryptReleaseContext(cProvider, 0); ///I ONLY LEFT THEM FOR THE PURPOSES OF THIS NOTE
oFile.close();
return cKHPair;
}
DWORD Decode(BYTE* Msg, DWORD Buffer, DWORD* Message_Size, std::pair<HCRYPTKEY, HCRYPTHASH> cKHPair)
{
if(!CryptDecrypt(cKHPair.first, cKHPair.second, TRUE, 0, Msg, Message_Size)) ///DECRYPTION ONCE YOU HAVE THE HASH AND KEY IS BRAIN DEAD EASY
{
std::cout << "FAILD TO DECRYPT MESSAGE! : " << GetLastError() << "\n";
}
printf_s("Ta-Da! : %s\nMessage Size: %d\n", Msg, *Message_Size);
return 0;
}
|