JWT/QByteArray::toBase64() adding a character at the end

  • I am trying to validate a JWT received by a server running PHP5. The debugger of the jwt.io website says my jwt is valid but validation isn't working out for me with QT5.5.

    Below is my jwt:

    QT correctly base64 decodes the header and payload
    "alg": "HS512",
    "typ": "JWT"
    "aud": "mike.greenish@addhaptics.com",
    "data": {
    "cid": "1080108000",
    "lic_id": "5",
    "modules": 1
    "exp": "2018-09-29T16:14:44-04:00",
    "iat": "2017-09-29T16:14:44-04:00",
    "iss": "Add Haptics"

    When I re-base64 encode the header, it matches the original. When I re-base64 encode the payload it matches the original plus there is an extra '=' at the end.

    Header, json compacted then base64 encoded:
    qDebug() << m_jdocHeader.toJson(QJsonDocument::JsonFormat::Compact).toUtf8().toBase64();


    Payload, json compacted then base64 encoded:
    qDebug() << m_jdocPayload.toJson(QJsonDocument::JsonFormat::Compact).toUtf8().toBase64();


    From my jwt above, the payload should be

    So it seems is an extra '=' generated by QT that php doesn't.

  • Actually, I have to correct my above statement, the php code passes the base64 encoded string through a filter to make it url safe, apparently:

    public static function urlsafeB64Encode($input)
        return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));

    So that is how the extra '=' doesn't show up in the jwt generated by php.

    Nonetheless, even without the extra '=', when the 'header.payload' string is HMACSHA512 encoded, the signature calculated by QT doesn't match the signature in the jwt, so the validation fails.

    The signature is calculated as follows during validation:
    byteSignature = QMessageAuthenticationCode::hash( qba_Header + "." + qba_Payload, qbaSecret, QCryptographicHash::Sha512);

    original signature:

    calculated signature:
    "\x84\fA%\xE1\td \x9A\x1F\xCDH\xA7\x83\xB1\x85g\xAC\xE6\x1B\xA9\x00,\x1C""c\xCF\x00\x83\xD6\xC4\x98~X\xF1}D\x9C\x9A\xEE-O\xDAT\x1E\i=2\xDA%T\x16""f\xC2\xA3M\x99\x1C\x17?\xA6\x15)R"

    As a reference, the signature is calculated as follows in php:

        $segments = array();
        $segments[] = static::urlsafeB64Encode(static::jsonEncode($header));
        $segments[] = static::urlsafeB64Encode(static::jsonEncode($payload));
        $signing_input = implode('.', $segments);
        $signature = static::sign($signing_input, $key, $alg);
        $segments[] = static::urlsafeB64Encode($signature);
        return implode('.', $segments);

    Where static::sign returns:
    hash_hmac($alg, $signing_input, $key, true);

    Why is QT not calculating the signature in the same way?

  • Lifetime Qt Champion


    For the motivation behind the implementation, you should rather bring this question to the interest mailing list. You'll find there Qt's developers/maintainers. This forum is more user oriented.

  • @SGaist Thank you for the suggestion. I'll repost this there.

Log in to reply

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.