[Answered]: JWT component for ESP-IDF (JSON Web Tokens)

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

[Answered]: JWT component for ESP-IDF (JSON Web Tokens)

Postby kolban » Sun Aug 19, 2018 8:09 pm

When using certain cloud IoT services such as Google Cloud Platform (GCP) we have to authenticate with the cloud by providing a JSON Web Token (JWT) ... see:

https://jwt.io/

While there are many libraries available, the number of such libraries for C/C++ is relatively low. I had a quick look through them and none are immediately useable on the ESP-IDF platform. They either use their own JSON parsers (not cJSON) or require a full "openssl" stack (where we use mbedtls).

As such, these projects would appear to need porting or a new JWT written for our own needs. I'm contemplating having a go at this but before embarking on that quest, I want to see if either it is already done or if someone else has a project in flight down this path?

So ... anyone using JWT with ESP-IDF? If not, anyone interested in this area besides myself?
Last edited by kolban on Sun Aug 26, 2018 12:25 am, edited 1 time in total.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
Available for ESP32 consulting.

p-rimes
Posts: 63
Joined: Thu Jun 08, 2017 6:20 pm

Re: JWT component for ESP-IDF (JSON Web Tokens)

Postby p-rimes » Mon Aug 20, 2018 6:51 pm

Only a few mbedTLS commands needed. You might find this (GPL) implementation useful, although it is GCP specific, it does overview the signing process (any functions using the mbedtls_ API) for both RS256 and ES256.

https://github.com/mongoose-os-libs/gcp ... _gcp.c#L69

s.allasia
Posts: 17
Joined: Tue Jan 09, 2018 3:12 pm

Re: JWT component for ESP-IDF (JSON Web Tokens)

Postby s.allasia » Thu Aug 23, 2018 12:36 pm

Hi kolban,
I'm interisting to use GCLOUD (IOT core): I'm trying to sign my mqtt password with JSON Web Token (JWT) but actually I can't generate the digital signature with RSASSA-PKCS1-v1_5 using SHA-256.
I followed istructions on https://tools.ietf.org/html/rfc7518#section-3.3, but the final signature I can't do it: I don't understand the last step of the signature.
My topic:
https://www.esp32.com/viewtopic.php?f=2&t=6879
Any idea?
Thanks

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: JWT component for ESP-IDF (JSON Web Tokens)

Postby kolban » Thu Aug 23, 2018 3:00 pm

Howdy,
This is exactly my puzzle too. While JWT is generic, my practical need is for GCP (Google Cloud Platform). I'm in no immediate rush and haven't started digging too deeply. My first thought was this thread to see if anyone has walked this pass previously. The Mongoose OS implementation looks good. There are also some other open source JWT implementations on Github but these leverage richer openssl than we have in ESP-IDF. If you are working on a direct implementation of the JWT RFC directly, I for one would be delighted to collaborate with you and others as long as the end result is open source free distribution on Github.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
Available for ESP32 consulting.

foxbat
Posts: 1
Joined: Sat Aug 25, 2018 5:46 pm

Re: JWT component for ESP-IDF (JSON Web Tokens)

Postby foxbat » Sat Aug 25, 2018 6:09 pm

I have managed to get GCP connectivity working with mbedTLS using the RS256 scheme and just ESP-IDF/freertos. My code is scattered across a few C++ classes so not so simple to copy/paste here but the steps aren't too hard. I'll detail them here.

Generate a 2048 bit RSA keypair. Store the public half in the IOT console. GCP does not support less than 2048 bits for RSA.

Get your private key into your program however you want. I reference it as a file in component.mk. Load it up using the mbedtls_pk_parse_key() function:

Code: Select all

mbedtls_pk_init(&_context);                                     // this just zeros out the internal pointers

int rc = mbedtls_pk_parse_key(
    &_context,
    (const uint8_t *) privateKey.c_str(),
    privateKey.length() + 1,
    nullptr,
    0);


Create the first two parts of the JWT as per the standard. The first part should be a base64 representation of this:

Code: Select all

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


The second part should be a base64 encoding of this:

Code: Select all

{
  "iat": 1535218434,
  "exp": 1535222034,
  "aud": "YOUR-GCP-PROJECT-ID"
}


I don't know whether GCP validates "iat" so I always knock it back 10 minutes to account for clock differences. I set "exp" to +3600 seconds.

VERY IMPORTANT: The base64 alphabet must be the URL-safe alphabet with no "=" padding, ie. this:

Code: Select all

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_


Concatenate your two base64 fragments separated by a "." and feed that string first into a SHA256 hash and then a signature. The signature will be 256 bytes long:

Code: Select all

  uint8_t hash[32];
  int rc = mbedtls_md(
        mbedtls_md_info_from_type(MBEDTLS_MD_SHA256),
        (const uint8_t *)str.c_str(), str.length(), hash);

  size_t sig_len = mbedtls_pk_get_len(context);
  uint8_t *sig=(uint8_t *)calloc(sig_len,1);

  // sign the hash

  rc = mbedtls_pk_sign(
        context,
        MBEDTLS_MD_SHA256,
      hash,
      sizeof(hash),
      sig,
      &sig_len,
      NULL,NULL);


Base64 encode your signature and append it with another "." separator to the first two parts.

I can then use that JWT to make successful calls to Google over an SSL connection. If you still get problems after doing all then double and triple check your project/registry/device identifiers in all the places you need to specify them in the call. Use the online debugger at jwt.io to check your JWT against your public key. Don't even bother trying Google until jwt.io tells you that your signature is valid.

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: JWT component for ESP-IDF (JSON Web Tokens)

Postby kolban » Sun Aug 26, 2018 12:24 am

Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
Available for ESP32 consulting.

Who is online

Users browsing this forum: Google [Bot] and 5 guests