Using DPAPI in unreal to encrypt and decrypt user input, but the decryption doesn't match the original input

73 views Asked by At

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

0

There are 0 answers