Skip to content

Joris Vergeer

Just some software engineer with some skills

Menu
  • Home
Menu

[C++/QT/OpenSSL/JWT] Minimalistic implementation to create a signed JTW token.

Posted on March 22, 2023 by joris

This code should be quite self explanatory.

#include <QSharedPointer>

#include <QJsonObject>
#include <QJsonDocument>

#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/sha.h>

bool tryCalculateRS256Signature(const QByteArray& data, const QString& privateKeyPem, QByteArray& signature)
{
    QByteArray privateKeyPemBytes = privateKeyPem.toUtf8();

    auto bio = QSharedPointer<BIO>(BIO_new_mem_buf(privateKeyPemBytes.constData(), -1), &BIO_free_all);
    if (!bio) {
        qDebug() << "Error loading pem";
        return false;
    }

    auto rsa = QSharedPointer<RSA>(PEM_read_bio_RSAPrivateKey(bio.data(), nullptr, nullptr, nullptr), &RSA_free);
    if (!rsa) {
        qDebug() << "Error loading private key";
        return false;
    }

    QByteArray sha256_hash(SHA256_DIGEST_LENGTH, 0);
    SHA256(reinterpret_cast<const unsigned char*>(data.constData()), data.length(), reinterpret_cast<unsigned char*>(sha256_hash.data()));

    QByteArray signatureBuffer(RSA_size(rsa.data()), 0);
    unsigned int signatureLength = 0;

    if (RSA_sign(NID_sha256, reinterpret_cast<unsigned char*>(sha256_hash.data()), SHA256_DIGEST_LENGTH, reinterpret_cast<unsigned char*>(signatureBuffer.data()), &signatureLength, rsa.data()) != 1) {
        qDebug() << "Error signing data";
        return false;
    }

    signature = signatureBuffer.left(signatureLength);

    return true;
}

bool tryCreateJwtToken(const QJsonObject& payload, const QString& privateKeyPem, QString& token)
{
    QJsonObject header;
    header["alg"] = "RS256";
    header["typ"] = "JWT";

    QJsonDocument headerDoc;
    headerDoc.setObject(header);

    QByteArray headerBytes = headerDoc.toJson(QJsonDocument::Compact);

    QJsonDocument payloadDoc;
    payloadDoc.setObject(payload);
    QByteArray payloadBytes = payloadDoc.toJson(QJsonDocument::Compact);

    QString headerAndBody =
            QString(headerBytes.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals))
            + "."
            + QString(payloadBytes.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals));

    QByteArray signature;
    if(!tryCalculateRS256Signature(headerAndBody.toUtf8(), privateKeyPem, signature))
    {
        qDebug() << "Failed to generate JWT signature";
        return false;
    }

    token = headerAndBody + "." + signature.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);

    return true;
}

And this is how you can use it. Of course you should never have your private key in your code.

int main(int argc, char *argv[])
{
    QString privateKeyPem  =
            "-----BEGIN PRIVATE KEY-----\r\n"
            "YOUR PRIVATE KEY HERE\r\n"
            "-----END PRIVATE KEY-----\r\n";

    QJsonObject payload;
    payload["name"] = "Johny Doe";

    QString jwt;
    tryCreateJwtToken(payload, privateKeyPem, jwt);

    qDebug() << "jwt: " << jwt;
}
  • jwt
  • qt
  • Work

    Currently working for and owner of RetailEntertainment B.V.
    • MKB-Muziek
    • Zorgscherm
    • Zorgstand
    • [Hashicorp Vault/PostgreSQL] Cleanup of roles with permissions and ownership
    • [C++/QT/OpenSSL/JWT] Minimalistic implementation to create a signed JTW token.
    • [C++/QT] QFuture delay method
    • [Vite] Copy vite build output to destination directory
    • [Python][Clang] Extract variabele value from a c++ file in python
    • May 2024 (1)
    • March 2023 (2)
    • February 2023 (1)
    • January 2023 (1)
    • July 2020 (1)
    • November 2019 (1)
    • May 2019 (1)
    • March 2019 (2)
    • DevOps
    • Programming
    • Uncategorized
    • Web

    Meta

    • Log in
    • Entries feed
    • Comments feed
    • WordPress.org
    © 2025 Joris Vergeer | Powered by Minimalist Blog WordPress Theme