I'm prompting the user for input (a security token in this case). Then I'm encrypting it using DPAPI, and storing it in a text file for later use. The issue I'm having is that when I decrypt the file, it sometimes (often) has random trailing characters, and I can't figure out what the problem is.
Below are the functions I'm using to encrypt and decrypt the files
bool AuthManager::Encrypt(FString InString)
{
const int32 Size = InString.Len();
TArray<uint8> Data;
Data.AddUninitialized(Size);
StringToBytes(InString, Data.GetData(), Size);
// Encrypt data from DATA_BLOB DataIn to DATA_BLOB DataOut.
DATA_BLOB DataIn, DataOut;
BYTE* PbDataInput = Data.GetData();
const DWORD CBDataInput = strlen(reinterpret_cast<char*>(PbDataInput));
DataIn.pbData = PbDataInput;
DataIn.cbData = CBDataInput;
if(CryptProtectData(
&DataIn,
nullptr,
nullptr,
nullptr,
nullptr,
0,
&DataOut))
{
const char* EncryptedTokenFile = "path\\to\\encryptedTokenFile.txt";
std::ofstream EncryptedFile(EncryptedTokenFile, std::ios::out | std::ios::binary);
EncryptedFile.write(reinterpret_cast<char*>(&DataOut.cbData), sizeof(DataOut.cbData));
EncryptedFile.write(reinterpret_cast<char*>(DataOut.pbData), DataOut.cbData);
EncryptedFile.close();
LocalFree(DataOut.pbData);
}
else
{
UE_LOG(LogConsoleResponse, Error, TEXT("Encryption error using CryptProtectData."));
return false;
}
return true;
}
//////////////////////////////////////////////////////////////////////
bool AuthManager::Decrypt(FString& OutString)
{
const char* EncryptedTokenFile = "path\\to\\encryptedTokenFile.txt";
std::ifstream ReadEncryptedFile(EncryptedTokenFile, std::ios::in | std::ios::binary);
if(!ReadEncryptedFile.is_open())
{
UE_LOG(LogConsoleResponse, Error, TEXT("Cannot open %s. Please verify the file exists and is not read-protected."), *GetTokenFilePath());
return false;
}
// Encrypt data from DATA_BLOB DataIn to DATA_BLOB DataOut.
DATA_BLOB DataIn, DataOut;
LPWSTR DataDesc = nullptr;
ReadEncryptedFile.read(reinterpret_cast<char*>(&DataIn.cbData), sizeof(DataIn.cbData));
DataIn.pbData = new BYTE[DataIn.cbData];
ReadEncryptedFile.read(reinterpret_cast<char*>(DataIn.pbData), DataIn.cbData);
// Begin unprotect phase.
if (CryptUnprotectData(
&DataIn,
&DataDesc,
nullptr,
nullptr,
nullptr,
0,
&DataOut))
{
// Convert byte output into FString
OutString = BytesToString(DataOut.pbData, DataOut.cbData);
UE_LOG(LogConsoleResponse, Display, TEXT("The OutString is: %s"), *OutString);
LocalFree(DataOut.pbData);
LocalFree(DataDesc);
}
else
{
UE_LOG(LogConsoleResponse, Error, TEXT("Decryption error using CryptUnprotectData."));
return false;
}
return true;
}
I've tried increasing or decreasing the number of characters into the buffer, but it's inconsistent