Step Up API Authentication
If you haven't already done so, please read our Basic API Authentication Guide here.
Basic information about JWT
- A JSON Web Token("JWT") is used by TxB partners who interact with our APIs on behalf of more than 1 client
- A JWT consists of a header, payload and a signature
- RSA key(private) with a unique 'kid' is used to sign the JWT. Partner exchanges public RSA key with TxB which will be used to validate the signature
- The claim in the payload has various identifiers namely, client(subject), partner(issuer), audience(txb), kid(from RSA key), sha256 hash of the mTLS cert
The guide below describes how to create and bind a JWT token, which may be included in the Authentication
input parameter and which will be presented alongside the mTLS certificate.
Step by Step Guide
Step 1 - Generate a public JWK using RSA KeyPair
Generate a one-time unique key ID:
String uniqueKeyId = String.valueOf(UUID.randomUUID())
This unique key Id will be used in RSAKey generation (this step) and also used again in Step 3 during JWT generation.
You can use uuid generator tools to create this via code or via tools available online.
Generate public JWK using a one-time generated RSA Key:
RSAKey rsaKey = new RSAKeyGenerator(2048)
.keyUse(KeyUse.SIGNATURE) // indicate the intended use of the key
.keyID(uniqueKeyId) //This static key Id will be used again in Step 3
.generate();
return rsaKey.toPublicJWK();
This is a one-time key setup and will be used in Step 3 to sign the JWT.
Send the output of rsaKey.toPublicJWK()
to TxB.
Step 2 - Calculate the certificate hash using thumbprint
Once you have the mTLS certificate, copy the text into the mTLSCert variable and run the code below to create the X509Certificate
object
String mTLSCert = "-----BEGIN CERTIFICATE-----\n"
+ "MIIFtzCCA5+gAwIBAgIRAJn6k32RASsmv/BtZ237xMAwDQYJKoZIhvcNAQELBQAw\n"
-----------------------------------------------------------------------
-----------------------------------------------------------------------
-----------------------------------------------------------------------
+ "-----END CERTIFICATE-----\n";
InputStream targetStream = new ByteArrayInputStream(mTLSCert.getBytes());
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
X509Certificate x509cert = (X509Certificate) certificateFactory.generateCertificate(targetStream);
Compute the SHA256 hash of the X509Certificate
object using below code:
private static String getThumbprint(X509Certificate cert)
throws NoSuchAlgorithmException, CertificateEncodingException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] der = cert.getEncoded();
md.update(der);
byte[] digest = md.digest();
String digestHex = DatatypeConverter.printHexBinary(digest);
return digestHex.toLowerCase();
}
private static String calculateSHA256(X509Certificate x509cert) {
String thumbprint = getThumbprint(x509cert);
byte[] decodedHex = Hex.decodeHex(x509cert);
return new String(Base64.getUrlEncoder().encode(
decodedHex)).replaceAll("=+$", "");
}
An example output of the SHA256 hash is - ikVs7R7oXt0Ll_EGWWCE6VaJv6myadr9giDODCzbvtM
. This value will be used in the JWT payload in step 3
Step 3 - Bind all of values together in JWT
Create a JWTClaims
object:
JwtClaims claims = new JwtClaims();
Set Expiration time on the claim:
claims.setExpirationTimeMinutesInTheFuture(5);
Set the Partner Identifier
provided by TxB:
claims.setIssuer("0EAA62456B3426NU962A296BC4C5F9C9"); // This will be the gseid value in the mTLS cert
Set the Client Identifier
provided by TxB:
claims.setSubject("7FNA456B34268NU6G9682A2964C5967F"); // This value will change based on the third party account
Set the audience as txb
:
claims.setAudience("txb");
Set a random ID for JWTId:
claims.setJwtId(String.valueOf(UUID.randomUUID()));
Set Current time as issuedAt
time:
claims.setIssuedAtToNow();
Set value of kid
from Step 1:
claims.setClaim("kid", uniqueKeyId);
Set cnf#x5t#S256
from output of Step 2:
claims.setClaim("cnf#x5t#S256", calculateSHA256(x509cert));
Sign the JWT using the RSAKey from Step 1:
JsonWebSignature jws = new JsonWebSignature();
jws.setPayload(claims.toJson());
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
jws.setKey(rsaKey.toPrivateKey()); // From Step 1
jws.setDoKeyValidation(false); // relaxes the key length requirement
Finally, return the JWT Output:
String jwtOut = jws.getCompactSerialization();
return jwtOut;
Your JWT will look something like this:
eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE2MDEyNjMyNzgsInN1YiI6IjdGTkE0NTZCMzQyNjhOVTZHOTY4MkEyOTY0QzU5NjdGIiwiYXVkIjoidHhiIiwianRpIjoiYjI5NGMxZjMtY2Y3OC00OTU4LWI3OGMtYTM0ZGE5MDhlMGM3IiwiaXNzIjoiMEVBQTYyNDU2QjM0MjZOVTk2MkEyOTZCQzRDNUY5QzkiLCJpYXQiOjE2MDEyNjI5NzgsImtpZCI6ImFlODVmZWU0LWQ5OGQtNGI4NS1iMDM0LTI5ZTgzMGE5ZjA0NyIsImNuZiN4NXQjUzI1NiI6ImlrVnM3UjdvWHQwTGxfRUdXV0NFNlZhSnY2bXlhZHI5Z2lET0RDemJ2dE0ifQ.fFuBynWjCcsmvye0kbI-ZAIqEXrLqvv9BFU13ZRoKcf54sQTUaguMubVQP4u1S1IijxyUMrFJpygzjbBQL_xzVRaUVXTPlrYM8HlugjsE-t94D085Y9ULJmDNbsGALwnA5ftv0O3cUH7qckmtIvUWI58vH6BvMYoS6T4ANiwXNxux7d81bGqy7r4a-IJH1umCLaz-cprhyb8J5SJkNhx4m5CJWGIyg5ycpF0PNUDX3HjxcACilXPQMGAKtQkV89EzzGFDc-j46aQ0920ocf9u_LfmavfYABasEtX9E0j8TKnAS1RZosKoCbj14OV8sYhNgKm9BIvk32aS2VfwpkMfQ
Step 4 - Test final connection
Finally, test your connection using this cURL command:
curl -s -X GET "https://api.test.txb.gs.com/v1/connectivity" -H "Authorization: Bearer <jwtOut>" --cacert ./certificate.pem --key private_key.key
Was this page useful?
Give feedback to help us improve developer.gs.com and serve you better.