Java

To authenticate to the akenza MQTT broker using device credentials, a device must send a JSON Web Token (JWT, RFC 7519).

Each JWT is composed of three components: a header, a payload (containing a claim set), and a signature.

The full example can be found here.

Using an RSA Private Key

/**
 * Create a JWT for the given device id, signed with the given RSA private key.
 */
private static String createJwtRS(String privateKeyFile, String audience, String deviceId, int tokenExpMinutes) throws JOSEException, IOException {
    String keyString = Files.readString(Paths.get(privateKeyFile));
    JWK jwk = JWK.parseFromPEMEncodedObjects(keyString);
    RSAKey rsaKey = jwk.toRSAKey();
    
    JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
            .subject(deviceId)
            .audience(String.format("https://%s/devices/%s", audience, deviceId))
            .expirationTime(Date.from(Instant.now().plus(Duration.ofMinutes(tokenExpMinutes))))
            .issueTime(Date.from(Instant.now()))
            .build();

    var header = new JWSHeader.Builder(JWSAlgorithm.RS256)
            .build();

    SignedJWT signedJWT = new SignedJWT(header, claimsSet);
    JWSSigner signer = new RSASSASigner(rsaKey);
    signedJWT.sign(signer);

    return signedJWT.serialize();
}

Using an EC Private Key

/**
 * Create a JWT for the given device id, signed with the given elliptic curve private key.
 */
private static String createJwtES(String privateKeyFile, String audience, String deviceId, int tokenExpMinutes) throws JOSEException, IOException {
    String keyString = Files.readString(Paths.get(privateKeyFile));
    JWK jwk = JWK.parseFromPEMEncodedObjects(keyString);
    ECKey ecKey = jwk.toECKey();

    JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
            .subject(deviceId)
            .audience(String.format("https://%s/devices/%s", audience, deviceId))
            .expirationTime(Date.from(Instant.now().plus(Duration.ofMinutes(tokenExpMinutes))))
            .issueTime(Date.from(Instant.now()))
            .build();

    var header = new JWSHeader.Builder(JWSAlgorithm.ES256)
            //TODO if multiple certificates are in use, provide the fingerprint
            //.keyID(getFingerPrint(publicKeyPEM))
            .build();

    SignedJWT signedJWT = new SignedJWT(header, claimsSet);
    JWSSigner signer = new ECDSASigner(ecKey);
    signedJWT.sign(signer);
    
    return signedJWT.serialize();
}

Last updated