Trying to write code to change the registry keys with c++ after endless amount of time I reached this point but this code still does not edit the registry even when running as admin
to change the registry 4 functions are needed according to this question which I used and every single one of them returns a zero which means that the function completed without errors but still no values are changed in the registry gui
the SecurityHealth strartup service is running on my machine and has the path %windir%\system32\SecurityHealthSystray.exe and type REG_EXPAND_SZ
I even tried creating a new entry similar to the SecurityHealth and still nothing is changed
I am compiling as admin and running as admin
HKEY open_reg()
{
int result;
LPCSTR lpSubKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";
HKEY hKey;
result = RegOpenKeyExA(HKEY_LOCAL_MACHINE, lpSubKey, 0, KEY_QUERY_VALUE|KEY_WRITE|KEY_READ|KEY_SET_VALUE, &hKey);
if ( result != 0)
{
cout << " Failed to open registry. - [ "<< result<< "]" <<endl;
}
else
{
cout << "Found registry key. - [" << result<<"]" << endl;
}
return hKey;
}
HKEY find_reg_value(HKEY handle)
{
LPCSTR lpValueName = "SecurityHealth";
DWORD BufferSize = TOTALBYTES;
DWORD cbData;
int dwRet;
PPERF_DATA_BLOCK PerfData = (PPERF_DATA_BLOCK) malloc( BufferSize );
cbData = BufferSize;
cout << "\nRetrieving the data..." << endl;
dwRet = RegQueryValueExA( handle,
lpValueName,
NULL,
NULL,
(LPBYTE) PerfData,
&cbData );
if ( dwRet == 0 )
{
cout << "Successfully quered [" << dwRet << "]"<<endl;
}
else
{
cout << "Failed to query Error code : [" << dwRet << "]"<<endl;
}
return handle;
}
void set_reg_value(HKEY handle)
{
int result;
LPCSTR lpValueName = "SecurityHealth";
std::string file = "C:\\Windows\\System32\\cmd.exe";
const char * sth = file.c_str();
unsigned char m_Test[file.size()];
strcpy((char*)m_Test, sth);
DWORD DATA_SIZE = file.size()+1;
result = RegSetValueExA(handle,lpValueName,0,REG_EXPAND_SZ,m_Test,DATA_SIZE);
if ( result == 0 )
{
cout << "Successfully changed value [" << result << "]"<<endl;
}
else
{
cout << "Failed to change value Error code : [" << result << "]"<<endl;
}
RegCloseKey (handle);
}
int main()
{
cout << "testing windows registry " << endl;
HKEY reg_handle = open_reg();
HKEY handler = find_reg_value(reg_handle);
set_reg_value(handler);
system("PAUSE");
return 0;
}
the compiled exe output in the terminal
testing windows registry
Found registry key. - [0]
Retrieving the data...
Successfully quered [0]
Successfully changed value [0]
Press any key to continue . . .
Compiled with g++ regutil.cpp
I suspect you are compiling as a 32-bit program but looking at a 64-bit registry. Switch to compiling as 64-bit instead. (There is a 32-bit registry instead, which can be found buried within the 64-bit hives but you likely want to change the actual 64-bit version).
every single one of them returns a zero which means that the function completed without errors but still no values are changed in the registry GUI
The only way that can happen is if either:
You are not updating the GUI after making the changes.
you are modifying a different area of the Registry then you are viewing, ie if you are modifying the 32bit Registry but viewing the 64bit Registry, or vice versa. Read up about the Registry Redirector, Registry Keys Affected by WOW64 and Accessing an Alternate Registry View on MSDN for more details about working with the 32bit and 64bit Registry views.
That being said, there are a number of other mistakes in your code.
Try something more like this instead:
HKEY open_reg()
{
HKEY hKey = NULL;
int result = RegOpenKeyExA( HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
0,
KEY_QUERY_VALUE | KEY_SET_VALUE /* | KEY_WOW64_(32|64)KEY if needed */,
&hKey );
if ( result != 0 )
{
cout << " Failed to open Registry, Error " << result << endl;
return NULL;
}
else
{
cout << "Opened Registry key" << endl;
return hKey;
}
}
void query_reg_value(HKEY handle)
{
DWORD cbBuffer = TOTALBYTES;
std::vector<char> buffer(cbBuffer);
cout << "\nRetrieving the data..." << endl;
int result = RegQueryValueExA( handle,
"SecurityHealth",
NULL,
NULL,
reinterpret_cast<LPBYTE>(buffer.data()),
&cbBuffer );
if ( result == 0 )
{
cout << "Successfully quered: ";
while (cbBuffer != 0 && buffer[cbBuffer-1] == '\0') --cbBuffer; // ignore null terminator(s)
cout.write(buffer.data(), cbBuffer);
cout << endl;
}
else
{
cout << "Failed to query, Error " << result << endl;
}
}
void set_reg_value(HKEY handle)
{
std::string file = "C:\\Windows\\System32\\cmd.exe";
int result = RegSetValueExA( handle,
"SecurityHealth",
0,
REG_EXPAND_SZ,
reinterpret_cast<LPCBYTE>(file.c_str()),
file.size()+1);
if ( result == 0 )
{
cout << "Successfully changed value" << endl;
}
else
{
cout << "Failed to change value, Error " << result << endl;
}
}
int main()
{
cout << "testing Windows Registry" << endl;
HKEY hKey = open_reg();
if (hKey) {
query_reg_value(hKey);
set_reg_value(hKey);
RegCloseKey(hKey);
}
system("PAUSE");
return 0;
}
However, it should be noted that only admin users have write access to HKLM keys by default, most users have read-only access. As such, it is not a good idea to open a key under HKLM for both reading and writing at the time same, unless you know what you are doing. You should open a key for reading only, read from it, and close it. Same for writing. For instance:
HKEY open_reg(bool isWriting)
{
HKEY hKey = NULL;
int result = RegOpenKeyExA( HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
0,
(isWriting ? KEY_SET_VALUE : KEY_QUERY_VALUE) /* | KEY_WOW64_(32|64)KEY if needed */,
&hKey );
if ( result != 0 )
{
cout << " Failed to open Registry, Error " << result << endl;
return NULL;
}
else
{
cout << "Opened registry key" << endl;
return hKey;
}
}
void query_reg_value()
{
HKEY hKey = open_reg(false);
if (!hKey) return;
DWORD cbBuffer = TOTALBYTES;
std::vector<char> buffer(cbBuffer);
cout << "\nRetrieving the data..." << endl;
int result = RegQueryValueExA( hKey,
"SecurityHealth",
NULL,
NULL,
reinterpret_cast<LPBYTE>(buffer.data()),
&cbBuffer );
if ( result == 0 )
{
cout << "Successfully quered: ";
while (cbBuffer != 0 && buffer[cbBuffer-1] == '\0') --cbData; // ignore null terminator(s)
cout.write(buffer.data(), cbBuffer);
cout << endl;
}
else
{
cout << "Failed to query, Error " << result << endl;
}
RegCloseKey(hKey);
}
void set_reg_value()
{
HKEY hKey = open_reg(true);
if (!hKey) return;
std::string file = "C:\\Windows\\System32\\cmd.exe";
int result = RegSetValueExA( hKey,
"SecurityHealth",
0,
REG_EXPAND_SZ,
reinterpret_cast<LPCBYTE>(file.c_str()),
file.size()+1);
if ( result == 0 )
{
cout << "Successfully changed value" << endl;
}
else
{
cout << "Failed to change value, Error " << result << endl;
}
RegCloseKey(hKey);
}
int main()
{
cout << "testing Windows Registry" << endl;
query_reg_value();
set_reg_value();
system("PAUSE");
return 0;
}
I study CNG API, I try to encrypt a file and then decrypt it. To get the key I use SHA512, for AES encryption, with the following code:
#include <QCoreApplication>
#include <windows.h>
#include <wincrypt.h>
#include <bcrypt.h>
#include <fstream>
#include <iostream>
#include <QDebug>
#include <tchar.h>
using namespace std;
int main(int argc, char *argv[])
{
srand(time(NULL));
const int blockSize = 64;
const int buffSize = 512;
DWORD cbHashObject = 0, cbData = 0, cbKeyObject = 0, cbKeyData = 0, cbBlockLen = 0, cbCipherData = 0, cbPlainData = 0, cbBlob = 0;
PBYTE pbHashObject = NULL;
PBYTE pbKeyObject = NULL;
BCRYPT_ALG_HANDLE hAlg;
BCRYPT_HASH_HANDLE hHashB;
BCRYPT_KEY_HANDLE hKey;
NTSTATUS status;
PBYTE pbHash, pbIV, pbBlob = NULL;
PBYTE pbPlainData = NULL, pbCipherData = NULL;
BYTE* password = (BYTE*)"pass";
QCoreApplication a(argc, argv);
char *buff = new char[buffSize + 1];
if (!BCRYPT_SUCCESS(status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA512_ALGORITHM, NULL, 0)))
{
DWORD dwErr = GetLastError();
qDebug()<<"ERROR1 " << hex << status << " E: " << hex << dwErr;
}
if (!BCRYPT_SUCCESS(status = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (PBYTE)&cbHashObject, sizeof(DWORD), &cbData, 0)))
{
DWORD dwErr = GetLastError();
qDebug()<<"ERROR2 " << hex << status << " E: " << hex << dwErr;
}
pbHashObject = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbHashObject);
if (!BCRYPT_SUCCESS(status = BCryptCreateHash(hAlg, &hHashB, pbHashObject, cbHashObject, NULL, 0, 0)))
{
DWORD dwErr = GetLastError();
qDebug()<<"ERROR3 " << hex << status << " E: " << hex << dwErr;
}
ZeroMemory(buff, buffSize + 1);
if (!BCRYPT_SUCCESS(status = BCryptHashData(hHashB, (PBYTE)password, strlen((char*)password)*sizeof(BYTE), 0)))
{
DWORD dwErr = GetLastError();
qDebug()<<"ERROR5 " << hex << status << " E: " << hex << dwErr;
}
cbHashObject = 0, cbData = 0;
if (!BCRYPT_SUCCESS(status = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, (PBYTE)&cbHashObject, sizeof(DWORD), &cbData, 0)))
{
DWORD dwErr = GetLastError();
qDebug()<<"ERROR6 " << hex << status << " E: " << hex << dwErr;
}
pbHash = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbHashObject);
if (!BCRYPT_SUCCESS(status = BCryptFinishHash(hHashB, pbHash, cbHashObject, 0)))
{
DWORD dwErr = GetLastError();
qDebug()<<"ERROR7 " << hex << status << " E: " << hex << dwErr;
}
char *str_hash = new char[cbHashObject*2+1];
for(int i = 0; i < cbHashObject;i++)
sprintf(str_hash+2*i,"%02X",pbHash[i]);
cout << "PASSWORD SHA512 = " <<str_hash<< endl << endl;
ZeroMemory(str_hash, cbHashObject);
if (!BCRYPT_SUCCESS(status = BCryptDestroyHash(hHashB)))
{
DWORD dwErr = GetLastError();
qDebug()<<"ERROR8 " << hex << status << " E: " << hex << dwErr;
}
if (!BCRYPT_SUCCESS(status = BCryptCloseAlgorithmProvider(hAlg, 0)))
{
DWORD dwErr = GetLastError();
qDebug()<<"ERROR9 " << hex << status << " E: " << hex << dwErr;
}
if (!BCRYPT_SUCCESS(status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_AES_ALGORITHM, NULL, 0)))
{
DWORD dwErr = GetLastError();
qDebug()<<"ERROR10 " << hex << status << " E: " << hex << dwErr;
}
if (!BCRYPT_SUCCESS(status = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (PBYTE)&cbKeyObject, sizeof(DWORD), &cbKeyData, 0)))
{
DWORD dwErr = GetLastError();
qDebug()<<"ERROR11 " << hex << status << " E: " << hex << dwErr;
}
if(!BCRYPT_SUCCESS(status = BCryptSetProperty(hAlg, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0)))
{
DWORD dwErr = GetLastError();
qDebug()<<"ERROR12 " << hex << status << " E: " << hex << dwErr;
}
pbKeyObject = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbKeyObject);
if(!BCRYPT_SUCCESS(status = BCryptGetProperty(hAlg, BCRYPT_BLOCK_LENGTH, (PBYTE)&cbBlockLen, sizeof(DWORD), &cbData, 0)))
{
DWORD dwErr = GetLastError();
qDebug()<<"ERROR13 " << hex << status << " E: " << hex << dwErr;
}
pbIV= (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbBlockLen+1);
for(int i(0); i < cbBlockLen; i++)
{
//pbIV[i]=rand();
pbIV[i]=0xAA;
}
for(int i = 0; i < cbBlockLen ;i++)
sprintf(str_hash+2*i,"%02X",pbIV[i]);
cout << "\n\nIV = " << str_hash;
if(!BCRYPT_SUCCESS(status = BCryptGenerateSymmetricKey(hAlg, &hKey, pbKeyObject, cbKeyObject, pbHash, cbHashObject, 0)))
{
DWORD dwErr = GetLastError();
qDebug()<<"ERROR14 " << hex << status << " E: " << hex << dwErr;
}
if(!BCRYPT_SUCCESS(status = BCryptExportKey(hKey,NULL,BCRYPT_OPAQUE_KEY_BLOB,NULL,0,&cbBlob,0)))
{
DWORD dwErr = GetLastError();
qDebug()<<"ERROR15 " << hex << status << " E: " << hex << dwErr;
}
pbBlob = (PBYTE)HeapAlloc(GetProcessHeap (), 0, cbBlob);
if(!BCRYPT_SUCCESS(status = BCryptExportKey(hKey,NULL,BCRYPT_OPAQUE_KEY_BLOB,pbBlob,cbBlob,&cbBlob,0)))
{
DWORD dwErr = GetLastError();
qDebug()<<"ERROR16 " << hex << status << " E: " << hex << dwErr;
}
ifstream f1("..\\1.txt");
ofstream f2("..\\2.txt", ios_base::trunc);
pbPlainData = (PBYTE)HeapAlloc(GetProcessHeap(), 0, blockSize + 1);
ZeroMemory(pbPlainData, blockSize + 1);
f1.read((char*)pbPlainData, blockSize);
if(!BCRYPT_SUCCESS(status = BCryptEncrypt(hKey, (BYTE*)pbPlainData, blockSize, NULL, 0, NULL, NULL, 0, &cbCipherData, BCRYPT_BLOCK_PADDING)))
{
DWORD dwErr = GetLastError();
qDebug()<<"ERROR15 " << hex << status << " E: " << hex << dwErr;
}
pbCipherData = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbCipherData + 1);
ZeroMemory(pbCipherData, cbCipherData + 1);
do {
if (!BCRYPT_SUCCESS(status = BCryptEncrypt(hKey, (BYTE*)pbPlainData, blockSize, NULL, 0, NULL, (BYTE*)pbCipherData, cbCipherData, &cbData, BCRYPT_BLOCK_PADDING)))
{
DWORD dwErr = GetLastError();
qDebug()<<"ERROR17 " << hex << status << " E: " << dwErr;
}
f2.write((char*)pbCipherData, cbData);
f2.flush();
f1.read((char*)pbPlainData, blockSize);
} while(!f1.eof());
f1.close();
f2.close();
BCryptDestroyKey(hKey);
HeapFree(GetProcessHeap(), 0, pbPlainData);
HeapFree(GetProcessHeap(), 0, pbCipherData);
pbPlainData = NULL;
pbCipherData = NULL;
memset(pbIV, 0xAA, cbBlockLen);
memset(pbKeyObject, 0 , cbKeyObject);
if(!BCRYPT_SUCCESS(status = BCryptImportKey(hAlg,NULL,BCRYPT_OPAQUE_KEY_BLOB,&hKey,pbKeyObject,cbKeyObject,pbBlob,cbBlob,0)))
{
DWORD dwErr = GetLastError();
qDebug()<<"ERROR18 " << hex << status << " E: " << hex << dwErr;
}
ifstream f3("..\\2.txt");
ofstream f4("..\\3.txt", ios_base::trunc);
pbCipherData = (PBYTE)HeapAlloc(GetProcessHeap(), 0, blockSize + 1);
ZeroMemory(pbCipherData, blockSize + 1);
f3.read((char*)pbCipherData, blockSize);
if(!BCRYPT_SUCCESS(status = BCryptEncrypt(hKey, (BYTE*)pbCipherData, blockSize, NULL, NULL, 0, NULL, 0, &cbPlainData, BCRYPT_BLOCK_PADDING)))
{
DWORD dwErr = GetLastError();
qDebug()<<"ERROR19 " << hex << status << " E: " << hex << dwErr;
}
pbPlainData = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbPlainData);
ZeroMemory(pbPlainData, cbPlainData);
do{
if (!BCRYPT_SUCCESS(status = BCryptEncrypt(hKey, (BYTE*)pbCipherData, blockSize, NULL, NULL, 0, (BYTE*)pbPlainData, cbPlainData, &cbData, BCRYPT_BLOCK_PADDING)))
{
DWORD dwErr = GetLastError();
qDebug()<<"ERROR20 " << hex << status << " E: " << dwErr;
}
f4.write((char*)pbPlainData, cbData);
f4.flush();
f3.read((char*)pbCipherData, blockSize);
}while(!f3.eof());
f3.close();
f4.close();
return a.exec();
}
At first thought that the problem was in IV, however I removed it and nothing has changed. Here are examples:
Before encryption(1.txt):
1234567890
After encryption(2.txt):
O“сh4W;H;7Т†Gж
qї
–JmdВу•оё:s±°|kД'y|‰зXgK4ПбЖl©bЪmЗШоЏMfU¶ysr‰Ї[Іґћ·У:RљС
After decryption(3.txt):
ї
–JmdВу•оё:s_T–їя5rJ™U,ЁМЈ‘µМґВ0уБЉO ‰CifБZDЧЈ)Тў«э"ќкгИу}ШЩєьъ©фb\a[
I have solved your problem, on the last two lines (206,215) change BCryptEncrypt to BCryptDecrypt
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <wincrypt.h>
#include <bcrypt.h>
#include <fstream>
#include <iostream>
#include <tchar.h>
#pragma comment(lib, "bcrypt.lib")
using namespace std;
int main(int argc, char* argv[])
{
const int blockSize = 64;
const int buffSize = 512;
DWORD cbHashObject = 0, cbData = 0, cbKeyObject = 0, cbKeyData = 0, cbBlockLen = 0, cbCipherData = 0, cbPlainData = 0, cbBlob = 0;
PBYTE pbHashObject = NULL;
PBYTE pbKeyObject = NULL;
BCRYPT_ALG_HANDLE hAlg;
BCRYPT_HASH_HANDLE hHashB;
BCRYPT_KEY_HANDLE hKey;
NTSTATUS status;
PBYTE pbHash, pbIV, pbBlob = NULL;
PBYTE pbPlainData = NULL, pbCipherData = NULL;
BYTE* password = (BYTE*)"pass";
char* buff = new char[buffSize + 1];
if (!BCRYPT_SUCCESS(status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA512_ALGORITHM, NULL, 0)))
{
DWORD dwErr = GetLastError();
std::cout << "ERROR1 " << hex << status << " E: " << hex << dwErr;
}
if (!BCRYPT_SUCCESS(status = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (PBYTE)&cbHashObject, sizeof(DWORD), &cbData, 0)))
{
DWORD dwErr = GetLastError();
std::cout << "ERROR2 " << hex << status << " E: " << hex << dwErr;
}
pbHashObject = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbHashObject);
if (!BCRYPT_SUCCESS(status = BCryptCreateHash(hAlg, &hHashB, pbHashObject, cbHashObject, NULL, 0, 0)))
{
DWORD dwErr = GetLastError();
std::cout << "ERROR3 " << hex << status << " E: " << hex << dwErr;
}
ZeroMemory(buff, buffSize + 1);
if (!BCRYPT_SUCCESS(status = BCryptHashData(hHashB, (PBYTE)password, strlen((char*)password) * sizeof(BYTE), 0)))
{
DWORD dwErr = GetLastError();
std::cout << "ERROR5 " << hex << status << " E: " << hex << dwErr;
}
cbHashObject = 0, cbData = 0;
if (!BCRYPT_SUCCESS(status = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, (PBYTE)&cbHashObject, sizeof(DWORD), &cbData, 0)))
{
DWORD dwErr = GetLastError();
std::cout << "ERROR6 " << hex << status << " E: " << hex << dwErr;
}
pbHash = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbHashObject);
if (!BCRYPT_SUCCESS(status = BCryptFinishHash(hHashB, pbHash, cbHashObject, 0)))
{
DWORD dwErr = GetLastError();
std::cout << "ERROR7 " << hex << status << " E: " << hex << dwErr;
}
char* str_hash = new char[cbHashObject * 2 + 1];
for (int i = 0; i < cbHashObject; i++)
sprintf(str_hash + 2 * i, "%02X", pbHash[i]);
cout << "PASSWORD SHA512 = " << str_hash << endl << endl;
ZeroMemory(str_hash, cbHashObject);
if (!BCRYPT_SUCCESS(status = BCryptDestroyHash(hHashB)))
{
DWORD dwErr = GetLastError();
std::cout << "ERROR8 " << hex << status << " E: " << hex << dwErr;
}
if (!BCRYPT_SUCCESS(status = BCryptCloseAlgorithmProvider(hAlg, 0)))
{
DWORD dwErr = GetLastError();
std::cout << "ERROR9 " << hex << status << " E: " << hex << dwErr;
}
if (!BCRYPT_SUCCESS(status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_AES_ALGORITHM, NULL, 0)))
{
DWORD dwErr = GetLastError();
std::cout << "ERROR10 " << hex << status << " E: " << hex << dwErr;
}
if (!BCRYPT_SUCCESS(status = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (PBYTE)&cbKeyObject, sizeof(DWORD), &cbKeyData, 0)))
{
DWORD dwErr = GetLastError();
std::cout << "ERROR11 " << hex << status << " E: " << hex << dwErr;
}
if (!BCRYPT_SUCCESS(status = BCryptSetProperty(hAlg, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0)))
{
DWORD dwErr = GetLastError();
std::cout << "ERROR12 " << hex << status << " E: " << hex << dwErr;
}
pbKeyObject = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbKeyObject);
if (!BCRYPT_SUCCESS(status = BCryptGetProperty(hAlg, BCRYPT_BLOCK_LENGTH, (PBYTE)&cbBlockLen, sizeof(DWORD), &cbData, 0)))
{
DWORD dwErr = GetLastError();
std::cout << "ERROR13 " << hex << status << " E: " << hex << dwErr;
}
pbIV = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbBlockLen + 1);
for (int i(0); i < cbBlockLen; i++)
{
//pbIV[i]=rand();
pbIV[i] = 0xAA;
}
for (int i = 0; i < cbBlockLen; i++)
sprintf(str_hash + 2 * i, "%02X", pbIV[i]);
std::cout << "\n\nIV = " << str_hash;
if (!BCRYPT_SUCCESS(status = BCryptGenerateSymmetricKey(hAlg, &hKey, pbKeyObject, cbKeyObject, pbHash, cbHashObject, 0)))
{
DWORD dwErr = GetLastError();
std::cout << "ERROR14 " << hex << status << " E: " << hex << dwErr;
}
if (!BCRYPT_SUCCESS(status = BCryptExportKey(hKey, NULL, BCRYPT_OPAQUE_KEY_BLOB, NULL, 0, &cbBlob, 0)))
{
DWORD dwErr = GetLastError();
std::cout << "ERROR15 " << hex << status << " E: " << hex << dwErr;
}
pbBlob = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbBlob);
if (!BCRYPT_SUCCESS(status = BCryptExportKey(hKey, NULL, BCRYPT_OPAQUE_KEY_BLOB, pbBlob, cbBlob, &cbBlob, 0)))
{
DWORD dwErr = GetLastError();
std::cout << "ERROR16 " << hex << status << " E: " << hex << dwErr;
}
ifstream f1("C:\\LOL\\1.txt");
ofstream f2("C:\\LOL\\2.txt", ios_base::trunc);
pbPlainData = (PBYTE)HeapAlloc(GetProcessHeap(), 0, blockSize + 1);
ZeroMemory(pbPlainData, blockSize + 1);
f1.read((char*)pbPlainData, blockSize);
if (!BCRYPT_SUCCESS(status = BCryptEncrypt(hKey, (BYTE*)pbPlainData, blockSize, NULL, 0, NULL, NULL, 0, &cbCipherData, BCRYPT_BLOCK_PADDING)))
{
DWORD dwErr = GetLastError();
std::cout << "ERROR15 " << hex << status << " E: " << hex << dwErr;
}
pbCipherData = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbCipherData + 1);
ZeroMemory(pbCipherData, cbCipherData + 1);
do {
if (!BCRYPT_SUCCESS(status = BCryptEncrypt(hKey, (BYTE*)pbPlainData, blockSize, NULL, 0, NULL, (BYTE*)pbCipherData, cbCipherData, &cbData, BCRYPT_BLOCK_PADDING)))
{
DWORD dwErr = GetLastError();
std::cout << "ERROR17 " << hex << status << " E: " << dwErr;
}
f2.write((char*)pbCipherData, cbData);
f2.flush();
f1.read((char*)pbPlainData, blockSize);
} while (!f1.eof());
f1.close();
f2.close();
BCryptDestroyKey(hKey);
HeapFree(GetProcessHeap(), 0, pbPlainData);
HeapFree(GetProcessHeap(), 0, pbCipherData);
pbPlainData = NULL;
pbCipherData = NULL;
memset(pbIV, 0xAA, cbBlockLen);
memset(pbKeyObject, 0, cbKeyObject);
if (!BCRYPT_SUCCESS(status = BCryptImportKey(hAlg, NULL, BCRYPT_OPAQUE_KEY_BLOB, &hKey, pbKeyObject, cbKeyObject, pbBlob, cbBlob, 0)))
{
DWORD dwErr = GetLastError();
std::cout << "ERROR18 " << hex << status << " E: " << hex << dwErr;
}
ifstream f3("C:\\LOL\\2.txt");
ofstream f4("C:\\LOL\\3.txt", ios_base::trunc);
pbCipherData = (PBYTE)HeapAlloc(GetProcessHeap(), 0, blockSize + 1);
ZeroMemory(pbCipherData, blockSize + 1);
f3.read((char*)pbCipherData, blockSize);
if (!BCRYPT_SUCCESS(status = BCryptDecrypt(hKey, (BYTE*)pbCipherData, blockSize, NULL, NULL, 0, NULL, 0, &cbPlainData, BCRYPT_BLOCK_PADDING)))
{
DWORD dwErr = GetLastError();
std::cout << "ERROR19 " << hex << status << " E: " << hex << dwErr;
}
pbPlainData = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbPlainData);
ZeroMemory(pbPlainData, cbPlainData);
do {
if (!BCRYPT_SUCCESS(status = BCryptDecrypt(hKey, (BYTE*)pbCipherData, blockSize, NULL, NULL, 0, (BYTE*)pbPlainData, cbPlainData, &cbData, BCRYPT_BLOCK_PADDING)))
{
DWORD dwErr = GetLastError();
std::cout << "ERROR20 " << hex << status << " E: " << dwErr;
}
f4.write((char*)pbPlainData, cbData);
f4.flush();
f3.read((char*)pbCipherData, blockSize);
} while (!f3.eof());
f3.close();
f4.close();
return 0;
}
I'm studying it too right now. I'm able to crypt a file, but then I can't decrypt it!
Here is the code:
#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <bcrypt.h>
#pragma comment(lib, "bcrypt.lib")
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)
#define DATA_TO_ENCRYPT "Test Data"
static const BYTE rgbAES128Key[] =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
};
int main() {
BCRYPT_ALG_HANDLE hAesAlg = NULL;
BCRYPT_KEY_HANDLE hKey = NULL;
NTSTATUS status = STATUS_UNSUCCESSFUL;
DWORD cbCipherText = 0,
cbPlainText = 0,
cbData = 0,
cbKeyObject = 0,
cbBlockLen = 0,
cbBlob = 0;
PBYTE pbCipherText = NULL,
pbPlainText = NULL,
pbKeyObject = NULL,
pbIV = NULL,
pbBlob = NULL;
BOOL bResult = FALSE;
wchar_t default_key[] = L"3igcZhRdWq96m3GUmTAiv9";
wchar_t* key_str = default_key;
// Open an algorithm handle.
if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&hAesAlg, BCRYPT_AES_ALGORITHM, NULL, 0)))
{
wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
return 0;
}
// Calculate the size of the buffer to hold the KeyObject.
if (!NT_SUCCESS(status = BCryptGetProperty(hAesAlg, BCRYPT_OBJECT_LENGTH, (PBYTE)&cbKeyObject, sizeof(DWORD), &cbData, 0)))
{
wprintf(L"**** Error 0x%x returned by BCryptGetProperty\n", status);
return 0;
}
// Allocate the key object on the heap.
pbKeyObject = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbKeyObject);
if (NULL == pbKeyObject)
{
wprintf(L"**** memory allocation failed\n");
return 0;
}
// Generate the key from supplied input key bytes.
if (!NT_SUCCESS(status = BCryptGenerateSymmetricKey(hAesAlg, &hKey, pbKeyObject, cbKeyObject, (PBYTE)rgbAES128Key, sizeof(rgbAES128Key), 0)))
{
wprintf(L"**** Error 0x%x returned by BCryptGenerateSymmetricKey\n", status);
return 0;
}
// Save another copy of the key for later.
if (!NT_SUCCESS(status = BCryptExportKey(hKey, NULL, BCRYPT_OPAQUE_KEY_BLOB, NULL, 0, &cbBlob, 0)))
{
wprintf(L"**** Error 0x%x returned by BCryptExportKey\n", status);
return 0;
}
// Allocate the buffer to hold the BLOB.
pbBlob = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbBlob);
if (NULL == pbBlob)
{
wprintf(L"**** memory allocation failed\n");
return 0;
}
if (!NT_SUCCESS(status = BCryptExportKey(
hKey,
NULL,
BCRYPT_OPAQUE_KEY_BLOB,
pbBlob,
cbBlob,
&cbBlob,
0)))
{
wprintf(L"**** Error 0x%x returned by BCryptExportKey\n", status);
return 0;
}
HANDLE hInpFile = CreateFileA("C:\\LOL\\file_1.encrypted", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (hInpFile == INVALID_HANDLE_VALUE) {
printf("Cannot open input file!\n");
system("pause");
return 0;
}
HANDLE hOutFile = CreateFileA("C:\\LOL\\file_1_decrypted.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hOutFile == INVALID_HANDLE_VALUE) {
printf("Cannot open output file!\n");
system("pause");
return 0;
}
const size_t chunk_size = 48;
BYTE chunk[chunk_size] = { 0 };
DWORD out_len = 0;
BOOL isFinal = FALSE;
DWORD readTotalSize = 0;
DWORD inputSize = GetFileSize(hInpFile, NULL);
while (bResult = ReadFile(hInpFile, chunk, chunk_size, &out_len, NULL)) {
if (0 == out_len) {
break;
}
readTotalSize += out_len;
if (readTotalSize == inputSize) {
isFinal = TRUE;
printf("Final chunk set.\n");
}
//
// Get the output buffer size.
//
if (!NT_SUCCESS(status = BCryptDecrypt(hKey, chunk, chunk_size, NULL, NULL, NULL, NULL, 0, &cbCipherText, BCRYPT_BLOCK_PADDING)))
{
wprintf(L"**** 1 Error 0x%x returned by BCryptEncrypt\n", status);
return 0;
}
pbCipherText = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbCipherText);
if (NULL == pbCipherText)
{
wprintf(L"**** memory allocation failed\n");
return 0;
}
// Use the key to encrypt the plaintext buffer.
// For block sized messages, block padding will add an extra block.
if (!NT_SUCCESS(status = BCryptDecrypt(hKey, chunk, chunk_size, NULL, NULL, NULL, pbCipherText, cbCipherText, &cbCipherText, BCRYPT_BLOCK_PADDING)))
{
wprintf(L"**** 2 Error 0x%x returned by BCryptEncrypt\n", status);
return 0;
}
if (!WriteFile(hOutFile, pbCipherText, cbCipherText, &cbData, NULL)) {
printf("writing failed!\n");
break;
}
}
}
The main change is the function name, from BCryptEncrypt to BCryptDerypt.
Also, the file names.
When I change to Decrypt, Irecieve "
**** 2 Error" error...
That's strange, because I use the same method, the same key...