- Generate A JWT Token From the private key generated as input.
C++
```C++
/**
* Calculates issued at / expiration times for JWT and places the time, as a
* Unix timestamp, in the strings passed to the function. The time_size
* parameter specifies the length of the string allocated for both iat and exp.
*/
static void GetIatExp(char* iat, char* exp, int time_size) {
// TODO(#72): Use time.google.com for iat
time_t now_seconds = time(NULL);
snprintf(iat, time_size, "%lu", now_seconds);
snprintf(exp, time_size, "%lu", now_seconds + 3600);
if (TRACE) {
printf("IAT: %s\n", iat);
printf("EXP: %s\n", exp);
}
}
static int GetAlgorithmFromString(const char* algorithm) {
if (strcmp(algorithm, "RS256") == 0) {
return JWT_ALG_RS256;
}
if (strcmp(algorithm, "ES256") == 0) {
return JWT_ALG_ES256;
}
return -1;
}
/**
* Calculates a JSON Web Token (JWT) given the path to a EC private key .
* Returns the JWT as a string that the caller must
* free.
*/
static char* CreateJwt(const char* ec_private_path,
const char* algorithm) {
char iat_time[sizeof(time_t) * 3 + 2];
char exp_time[sizeof(time_t) * 3 + 2];
uint8_t* key = NULL; // Stores the Base64 encoded certificate
size_t key_len = 0;
jwt_t* jwt = NULL;
int ret = 0;
char* out = NULL;
// Read private key from file
FILE* fp = fopen(ec_private_path, "r");
if (fp == NULL) {
printf("Could not open file: %s\n", ec_private_path);
return "";
}
fseek(fp, 0L, SEEK_END);
key_len = ftell(fp);
fseek(fp, 0L, SEEK_SET);
key = malloc(sizeof(uint8_t) * (key_len + 1)); // certificate length + \0
fread(key, 1, key_len, fp);
key[key_len] = '\0';
fclose(fp);
// Get JWT parts
GetIatExp(iat_time, exp_time, sizeof(iat_time));
jwt_new(&jwt);
// Write JWT
ret = jwt_add_grant(jwt, "iat", iat_time);
if (ret) {
printf("Error setting issue timestamp: %d\n", ret);
}
ret = jwt_add_grant(jwt, "exp", exp_time);
if (ret) {
printf("Error setting expiration: %d\n", ret);
}
ret = jwt_set_alg(jwt, GetAlgorithmFromString(algorithm), key, key_len);
if (ret) {
printf("Error during set alg: %d\n", ret);
}
out = jwt_encode_str(jwt);
if (!out) {
perror("Error during token creation:");
}
// Print JWT
if (TRACE) {
printf("JWT: [%s]\n", out);
}
jwt_free(jwt);
free(key);
return out;
}
```
Java
```Java
static MqttCallback mCallback;
static long MINUTES_PER_HOUR = 60;
/** Create a Omnicore JWT signed with the given RSA key. */
private static String createJwtRsa( String privateKeyFile)
throws NoSuchAlgorithmException, IOException, InvalidKeySpecException {
DateTime now = new DateTime();
// Create a JWT to authenticate this device. The device will be disconnected after the token
// expires, and will have to reconnect with a new token.
JwtBuilder jwtBuilder =
Jwts.builder()
.setIssuedAt(now.toDate())
.setExpiration(now.plusMinutes(20).toDate())
byte[] keyBytes = Files.readAllBytes(Paths.get(privateKeyFile));
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return jwtBuilder.signWith(SignatureAlgorithm.RS256, kf.generatePrivate(spec)).compact();
}
```
Golang
```Golang
import (
"errors"
"io/ioutil"
"time"
jwt "github.com/golang-jwt/jwt"
)
// createJWT creates a Omnicore JWT for the given subscription id.
// algorithm can be one of ["RS256", "ES256"].
func createJWT( privateKeyPath string, algorithm string, expiration time.Duration) (string, error) {
claims := jwt.StandardClaims{
IssuedAt: time.Now().Unix(),
ExpiresAt: time.Now().Add(expiration).Unix(),
}
keyBytes, err := ioutil.ReadFile(privateKeyPath)
if err != nil {
return "", err
}
token := jwt.NewWithClaims(jwt.GetSigningMethod(algorithm), claims)
switch algorithm {
case "RS256":
privKey, _ := jwt.ParseRSAPrivateKeyFromPEM(keyBytes)
return token.SignedString(privKey)
case "ES256":
privKey, _ := jwt.ParseECPrivateKeyFromPEM(keyBytes)
return token.SignedString(privKey)
}
return "", errors.New("Cannot find JWT algorithm. Specify 'ES256' or 'RS256'")
}
```
Nodejs
```Nodejs
const createJwt = ( privateKeyFile, algorithm) => {
// Create a JWT to authenticate this device. The device will be disconnected
// after the token expires, and will have to reconnect with a new token. The
const token = {
iat: parseInt(Date.now() / 1000),
exp: parseInt(Date.now() / 1000) + 20 * 60, // 20 minutes
};
const privateKey = readFileSync(privateKeyFile);
return jwt.sign(token, privateKey, {algorithm: algorithm});
};
```
Python
```python
def create_jwt( private_key_file, algorithm):
"""Creates a JWT (https://jwt.io) to establish an MQTT connection.
Args:
private_key_file: A path to a file containing either an RSA256 or
ES256 private key.
algorithm: The encryption algorithm to use. Either 'RS256' or 'ES256'
Returns:
A JWT generated from the given private key, which
expires in 20 minutes. After 20 minutes, your client will be
disconnected, and a new JWT will have to be generated.
Raises:
ValueError: If the private_key_file does not contain a known key.
"""
token = {
# The time that the token was issued at
"iat": datetime.datetime.now(tz=datetime.timezone.utc),
# The time the token expires.
"exp": datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(minutes=20),
}
# Read the private key file.
with open(private_key_file, "r") as f:
private_key = f.read()
print(
"Creating JWT using {} from private key file {}".format(
algorithm, private_key_file
)
)
return jwt.encode(token, private_key, algorithm=algorithm)
```