JWT validation



  • I am working to decode a Json Web Token that is received as a certificate. The JWT is base64 encoded.

    For the header of the JWT, I start with the following:

    eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9
    

    I base64 unecode and convert to a json document.

    QJsonDocument jdocHeader = QJsonDocument::fromJson( QByteArray::fromBase64( QString("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9").toUtf8() ) );
    

    When I convert to an object:

    QJsonObject jobjHeader = jdocHeader.object();
    

    I get what I expect:

    {
    "typ": "JWT",
    "alg": "HS512"
    }

    When I try to go back:

    QByteArray qsHeader64 = QString( jdocHeader.toJson(QJsonDocument::JsonFormat::Compact).toBase64() );
    

    I don't get the same original string, I get:

    eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9
    

    If I use QJsonDocument::JsonFormat::Indented, I also don't get the original string. What's going on?


  • Qt Champions 2016

    Hi
    Disclaimer. ultra tired so test might be incorrect.
    Anyway

     QByteArray input = QByteArray::fromBase64( QString("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9").toUtf8() );
      qDebug() << input.size() << "IN:>" << input.toStdString().c_str();
      QJsonDocument jdocHeader = QJsonDocument::fromJson( input ) ;
    
      QJsonObject jobjHeader = jdocHeader.object();
      qDebug() << jobjHeader;
    
      QByteArray qsHeader64 =  jdocHeader.toJson(QJsonDocument::JsonFormat::Compact);//.toBase64() ;
      qDebug() << qsHeader64.size() << "OUT:>" << QString(qsHeader64);
    
      qDebug() << qsHeader64.toBase64();
      qDebug() << "------------does order matter-------";
      qDebug() << QByteArray("123456789").toBase64();
      qDebug() << QByteArray("987654321").toBase64();
    
    

    result
    27 IN:> {"typ":"JWT","alg":"HS512"}
    QJsonObject({"alg":"HS512","typ":"JWT"})
    27 OUT:> "{"alg":"HS512","typ":"JWT"}"
    "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9"
    ------------does order matter-------
    "MTIzNDU2Nzg5"
    "OTg3NjU0MzIx"

    So it seems that the keys in the jsonobject are in other order and hence the base64 string becomes different.



  • Wow, nice find!! I've looked at this so long I didn't notice the difference in the order of the key-value pairs between the decoding by the debugger on jwt.io and the decoding performed by QJsonDocument::fromJson( ... ).object(). I confirm that I seem the same difference when stepping through the code.

    So it seems either the ::fromJson or the .object is switching the order of the keys. If I do QJsonDocument::toJson( QJsonDocument::fromJson( ... ) ), the keys are already switched so it seems the fromJson() is switching them. This seems like a bug to me, no?

    Any ideas for a work around?


  • Qt Champions 2016

    I got lucky ;)
    Well the order of keys is not really guaranteed as it just a map and its based on lookup so im not sure it qualifies as a bug.

    I would try to create an new jsonobject with the keys and see if inserting order is
    fixed/deterministic and if yes, you could take the values and inset in new object and base64 that.



  • @mrjj Seems the json order is alphabetical in qt and you are right, it's not considered as a bug as the order "shouldn't'" be important.


  • Qt Champions 2016

    @mgreenish
    Im assume it comes from the internal structure used to keep the keys/value pairs but i didnt check the code to verify that.
    I can see that is very annoying with JWT due to the nature of the service.
    Im not sure what you need to do with it or if creating a new object can fix it.
    In case you decide to use an other json lib, i can highly recommend
    https://github.com/bblanchon/ArduinoJson
    I didnt test if it would keep order but so far i didnt notice it didnt any re-order and we are using ith with base64 (to avoid clear text transfer) and not seen any issue.
    (but no promises ;)
    Its header only so really easy to get going.



  • I worked around it by making the key order alphabetical when I generate the JWT on the server side. This is solved.


Log in to reply
 

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