How to Use DPAPI with Qt Framework to Encrypt and Decrypt Data

When dealing with data encryption and decryption in Windows operating systems, probably one of the best choices is to use the Data Protection API. In this post I’ll be sharing two simple functions that can be used to encrypt and decrypt data (such as passwords, recovery keys and so on) that you want to store in an easy, quick and highly protected manner. Needless to say, these functions can be used with C++ and Qt Framework.



First things first, we must add the following line to our *.pro file in order to use DPAPI.

LIBS += -lCrypt32

Next, we need to make sure we have added the following headers into our source code:

#include "windows.h"
#include "dpapi.h"

Now we can easily use the following function to encrypt our data (whatever it may be) and optionally add a description to it:

bool encrypt(const QByteArray &input, QByteArray &output, const QString &description = "")
{
    DATA_BLOB decryptedData;
    DATA_BLOB encryptedData;

    decryptedData.pbData = (BYTE*)input.data();
    decryptedData.cbData = input.length();

    if(CryptProtectData(&decryptedData,
                        description.toStdWString().c_str(),
                        NULL,
                        NULL,
                        NULL,
                        0,
                        &encryptedData))
    {
        output = QByteArray::fromRawData((char*)encryptedData.pbData, encryptedData.cbData);
        return true;
    }

    return false;
}

Or we can use this function to decrypt any data we encrypted using the previous function:

bool decrypt(const QByteArray &input, QByteArray &output, QString &description)
{
    DATA_BLOB encryptedData;
    DATA_BLOB decryptedData;
    LPWSTR descStr;

    encryptedData.pbData = (BYTE*)input.data();
    encryptedData.cbData = input.length();

    if(CryptUnprotectData(&encryptedData,
                          &descStr,
                          NULL,
                          NULL,
                          NULL,
                          0,
                          &decryptedData))
    {
        output = QByteArray::fromRawData((char*)decryptedData.pbData, decryptedData.cbData);
        description = QString::fromWCharArray(descStr);
        return true;
    }

    return false;
}


Below you can see two examples of how encrypt and decrypt functions are used in action. First, to encrypt:

QString password = "myverysecurepassword";
QString description = "This is some password.";
QByteArray encryptedPassword;
if(encrypt(password.toUtf8(), encryptedPassword, description))
{
    // do something with encryptedPassword
}

And then to decrypt:

QByteArray decryptedPassword;
QString description;
if(decrypt(encryptedPassword, decryptedPassword, description))
{
    // do something with decryptedPassword and description
}

The official DPAPI header documentations from Microsoft helped me a lot when I was writing this post. Refer to them and you’ll be fine, otherwise you can post your questions below in the comments section.



Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.