[Answered]: JWT component for ESP-IDF (JSON Web Tokens)
[Answered]: JWT component for ESP-IDF (JSON Web Tokens)
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?
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
Re: JWT component for ESP-IDF (JSON Web Tokens)
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
https://github.com/mongoose-os-libs/gcp ... _gcp.c#L69
Re: JWT component for ESP-IDF (JSON Web Tokens)
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:
viewtopic.php?f=2&t=6879
Any idea?
Thanks
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:
viewtopic.php?f=2&t=6879
Any idea?
Thanks
Re: JWT component for ESP-IDF (JSON Web Tokens)
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.
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
Re: JWT component for ESP-IDF (JSON Web Tokens)
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:
Create the first two parts of the JWT as per the standard. The first part should be a base64 representation of this:
The second part should be a base64 encoding of this:
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:
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:
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.
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);
Code: Select all
{
"alg": "RS256",
"typ": "JWT"
}
Code: Select all
{
"iat": 1535218434,
"exp": 1535222034,
"aud": "YOUR-GCP-PROJECT-ID"
}
VERY IMPORTANT: The base64 alphabet must be the URL-safe alphabet with no "=" padding, ie. this:
Code: Select all
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_
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);
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.
Re: JWT component for ESP-IDF (JSON Web Tokens)
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
Re: [Answered]: JWT component for ESP-IDF (JSON Web Tokens)
Hi,
Do JWT should get generate from given user name and password.
We will allow user and password to get set/change
Is cookie auth on mongoose web server different from JWT?
I guess I can return pre-generated JWT for my user admin. and return in http hearder and receive via http header.
Thanks,
Naeem
Do JWT should get generate from given user name and password.
We will allow user and password to get set/change
Is cookie auth on mongoose web server different from JWT?
I guess I can return pre-generated JWT for my user admin. and return in http hearder and receive via http header.
Thanks,
Naeem
Re: [Answered]: JWT component for ESP-IDF (JSON Web Tokens)
Hi Kolban,
I managed to get your example working perfectly with RSA keys so thanks for that. I am now looking at generating a JWT using EC keys for Google Cloud Platform. Have you had any luck implementing this?
I managed to get your example working perfectly with RSA keys so thanks for that. I am now looking at generating a JWT using EC keys for Google Cloud Platform. Have you had any luck implementing this?
Last edited by jamiehug on Tue Apr 02, 2019 8:18 am, edited 1 time in total.
Re: [Answered]: JWT component for ESP-IDF (JSON Web Tokens)
Hi Kolban,
Thanks for your work on the JWT example, I got it to work perfectly with RSA keys. I am now looking to generate a JWT token for Google IoT MQTT comms using EC keypairs (I have generated an EC key pair and saved the private/public keys into a .pem file that I read in on the esp32). See Google's specs on how they specify the format of the JWT below. Using mbedtls_pk_sign and changing the header of the JWT to ES256 does not seem to work, I am not sure if mbedtls_pk_sign is using ECDSA? I have also created a JWT for the keypair using the Google JWT example to test the rest of my MQTT program works by the way. Would really appreciate the help.
https://cloud.google.com/iot/docs/how-t ... tials/jwts
Thanks for your work on the JWT example, I got it to work perfectly with RSA keys. I am now looking to generate a JWT token for Google IoT MQTT comms using EC keypairs (I have generated an EC key pair and saved the private/public keys into a .pem file that I read in on the esp32). See Google's specs on how they specify the format of the JWT below. Using mbedtls_pk_sign and changing the header of the JWT to ES256 does not seem to work, I am not sure if mbedtls_pk_sign is using ECDSA? I have also created a JWT for the keypair using the Google JWT example to test the rest of my MQTT program works by the way. Would really appreciate the help.
https://cloud.google.com/iot/docs/how-t ... tials/jwts
-
- Posts: 7
- Joined: Mon Apr 13, 2020 9:09 pm
Re: [Answered]: JWT component for ESP-IDF (JSON Web Tokens)
I am using an UWP app to talk to my ESP32 via SPP and bluetooth classic. I am able to open a socket to my ESP-32 and send a JSON message over bluetooth to it, and confirmed that I received it via the serial port monitoring:
How in my C++ ESP-IDF code should I decode my token so that I can read the header and payload elements?
And how do I encrypt my message in the UWP C# app and decrypt it in my C++ ESP-IDF app?
As you can see it got the JSON message, but I was ambitious and added a JWT token at the top. You'll notice that the token JSON is signed and encoded in UTF8 bytes too. I generated it using .NET standard 2.0 library in my UWP app:V (361538) TARDIS: ::receiveMessage() - {"IdToken":"eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lICI6ImhlbGxvICIsInNjb3BlIjoiaHR0cDovL2R1bW15LmNvbS8ifQ.FPkHESpldjwEsdE_ii8936gFq4pfptl3b6ao13BTLZk","Command":"testing 4","TimeSent":{"Ticks":0,"Days":0,"Hours":0,"Milliseconds":0,"Minutes":0,"Seconds":0,"TotalDays":0,"TotalHours":0,"TotalMilliseconds":0,"TotalMinutes":0,"TotalSeconds":0},"TimeReceived":{"Ticks":0,"Days":0,"Hours":0,"Milliseconds":0,"Minutes":0,"Seconds":0,"TotalDays":0,"TotalHours":0,"TotalMilliseconds":0,"TotalMinutes":0,"TotalSeconds":0}}�
Code: Select all
using System.Security;
using System.Text;
using System.IdentityModel;
using Microsoft.IdentityModel;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
// Create Security key using private key above:
// not that latest version of JWT using Microsoft namespace instead of System
var securityKey = new Microsoft
.IdentityModel.Tokens.SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
// Also note that securityKey length should be >256b
// so you have to make sure that your private key has a proper length
//
var credentials = new Microsoft.IdentityModel.Tokens.SigningCredentials
(securityKey, SecurityAlgorithms.HmacSha256Signature);
// Finally create a Token
var header = new JwtHeader(credentials);
string alg = header.Alg;
//Some PayLoad that contain information about the customer
var payload = new JwtPayload
{
{ "some ", "hello "},
{ "scope", "http://dummy.com/"},
};
//
var secToken = new JwtSecurityToken(header, payload);
var handler = new JwtSecurityTokenHandler();
// Token to String so you can use it in your client
string tokenString = handler.WriteToken(secToken);
And how do I encrypt my message in the UWP C# app and decrypt it in my C++ ESP-IDF app?
Who is online
Users browsing this forum: No registered users and 376 guests