Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. JWT/QByteArray::toBase64() adding a character at the end
Qt 6.11 is out! See what's new in the release blog

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

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 2 Posters 1.8k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    mgreenish
    wrote on last edited by
    #1

    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:
    eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJtaWtlLmdyZWVuaXNoQGFkZGhhcHRpY3MuY29tIiwiZGF0YSI6eyJjaWQiOiIxMDgwMTA4MDAwIiwibGljX2lkIjoiNSIsIm1vZHVsZXMiOjF9LCJleHAiOiIyMDE4LTA5LTI5VDE2OjE0OjQ0LTA0OjAwIiwiaWF0IjoiMjAxNy0wOS0yOVQxNjoxNDo0NC0wNDowMCIsImlzcyI6IkFkZCBIYXB0aWNzIn0.wiJ5D6zkk_K0JYizYQ-nAjlrEfZKyhIjOF8NcDLXnwWEGEzAjovcfUsLAcioVYBKhzVlOMydAPluTOfAD81H0Q

    QT correctly base64 decodes the header and payload
    Header:
    {
    "alg": "HS512",
    "typ": "JWT"
    }
    Payload:
    {
    "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();

    eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9

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

    eyJhdWQiOiJtaWtlLmdyZWVuaXNoQGFkZGhhcHRpY3MuY29tIiwiZGF0YSI6eyJjaWQiOiIxMDgwMTA4MDAwIiwibGljX2lkIjoiNSIsIm1vZHVsZXMiOjF9LCJleHAiOiIyMDE4LTA5LTI5VDE2OjE0OjQ0LTA0OjAwIiwiaWF0IjoiMjAxNy0wOS0yOVQxNjoxNDo0NC0wNDowMCIsImlzcyI6IkFkZCBIYXB0aWNzIn0=

    From my jwt above, the payload should be
    eyJhdWQiOiJtaWtlLmdyZWVuaXNoQGFkZGhhcHRpY3MuY29tIiwiZGF0YSI6eyJjaWQiOiIxMDgwMTA4MDAwIiwibGljX2lkIjoiNSIsIm1vZHVsZXMiOjF9LCJleHAiOiIyMDE4LTA5LTI5VDE2OjE0OjQ0LTA0OjAwIiwiaWF0IjoiMjAxNy0wOS0yOVQxNjoxNDo0NC0wNDowMCIsImlzcyI6IkFkZCBIYXB0aWNzIn0

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

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mgreenish
      wrote on last edited by mgreenish
      #2

      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:
      "\xC2"y\x0F\xAC\xE4\x90\xAD\tb,\xD8""Bp#\x96\xB1\x1F""d\xAC\xA1"3\x85\xF0\xD7\x03-y\xF0XA\x84\xCC\b\xE8\xBD\xC7\xD4\xB0\xB0\x1C\x8A\x85X\x04\xA8sVS\x8C\xC9\xD0\x0F\x96\xE4\xCE|\x00\xFC\xD4}\x10"

      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?

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi,

        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.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        M 1 Reply Last reply
        1
        • SGaistS SGaist

          Hi,

          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.

          M Offline
          M Offline
          mgreenish
          wrote on last edited by
          #4

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

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved