A lightweight Java library for generating JWT tokens signed with RSA private keys, specifically designed for use in SmartBear ReadyAPI Groovy scripts.
- ✅ JWT Token Generation - Create JWT tokens signed with RS256 (RSA with SHA-256) algorithm
- ✅ P8/PKCS#8 Key Support - Works with both encrypted and unencrypted private keys in P8 format
- ✅ Public Key Fingerprinting - Generate SHA-256 fingerprints of public keys for verification
Download the latest jwt-helper-uber-jar from the GitHub Releases page or from the Actions artifacts.
Copy the JAR file to your ReadyAPI ext directory:
- Windows:
C:\Program Files\SmartBear\ReadyAPI-X.X.X\bin\ext\ - macOS:
/Applications/ReadyAPI-X.X.X.app/Contents/java/app/bin/ext/ - Linux:
/opt/ReadyAPI-X.X.X/bin/ext/
Restart ReadyAPI after adding the JAR.
// Define your JWT claims
def claims = [
sub: "user@example.com",
name: "John Doe",
role: "admin",
iat: System.currentTimeMillis() / 1000,
exp: System.currentTimeMillis() / 1000 + 3600 // 1 hour expiry
]
// Generate JWT token
def privateKeyPath = "/path/to/your/private_key.p8"
def passphrase = "yourSecretPassphrase"
def jwt = com.smartbear.JWTHelper.make(claims, privateKeyPath, passphrase)
log.info "Generated JWT: ${jwt}"
// Use the JWT in your test
testRunner.testCase.setPropertyValue("authToken", jwt)Generates a JWT token signed with the provided private key.
Signature:
public static String make(
Map<String, Object> jwtFormat,
String privateKeyPath,
String privateKeyPassphrase
)Parameters:
jwtFormat- A map of key-value pairs representing JWT claimsprivateKeyPath- Full path to the private key file (.p8 format)privateKeyPassphrase- Passphrase for encrypted keys (use empty string""for unencrypted keys)
Returns: JWT token as a String
Example:
def claims = [
iss: "my-app",
sub: "user123",
aud: "api.example.com",
exp: System.currentTimeMillis() / 1000 + 3600
]
def jwt = com.smartbear.JWTHelper.make(
claims,
"/home/user/keys/private_key.p8",
"myPassphrase123"
)Generates a SHA-256 fingerprint of a public key for verification purposes.
Signature:
public static String generateFingerprint(String publicKeyPath)Parameters:
publicKeyPath- Full path to the public key file (.p8 format)
Returns: Fingerprint in the format SHA256:hexstring
Example:
def fingerprint = com.smartbear.JWTHelper.generateFingerprint(
"/home/user/keys/public_key.p8"
)
log.info "Public Key Fingerprint: ${fingerprint}"
// Output: SHA256:8cc989e66cdf9becf168d3e2a9dd66d5d8222cfbe24fdce29959b30c340125a6// Generate JWT for Bearer token authentication
def claims = [
sub: context.expand('${#Project#username}'),
iss: "readyapi-test",
exp: System.currentTimeMillis() / 1000 + 1800 // 30 minutes
]
def jwt = com.smartbear.JWTHelper.make(
claims,
context.expand('${#Project#privateKeyPath}'),
context.expand('${#Project#privateKeyPassphrase}')
)
// Set as Authorization header for subsequent requests
testRunner.testCase.setPropertyValue("BearerToken", "Bearer ${jwt}")// Generate fingerprint for API key registration
def publicKeyPath = "/path/to/public_key.p8"
def fingerprint = com.smartbear.JWTHelper.generateFingerprint(publicKeyPath)
def claims = [
sub: context.expand('${#Project#username}'),
iss: "readyapi-test",
exp: System.currentTimeMillis() / 1000 + 1800, // 30 minutes
public_key_fingerprint: fingerprint
]
def jwt = com.smartbear.JWTHelper.make(
claims,
context.expand('${#Project#privateKeyPath}'),
context.expand('${#Project#privateKeyPassphrase}')
)
// Set as Authorization header for subsequent requests
testRunner.testCase.setPropertyValue("BearerToken", "Bearer ${jwt}")Generate encrypted private key:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 \
-aes256 -out private_key.p8 -pass pass:YourPassphrase123Extract public key:
openssl pkey -in private_key.p8 -pubout -out public_key.p8 \
-passin pass:YourPassphrase123Generate unencrypted private key:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 \
-out private_key_unencrypted.p8Extract public key from unencrypted private key:
openssl pkey -in private_key_unencrypted.p8 -pubout -out public_key.p8- Java 17 or higher
- Maven 3.6+
- Git
# Clone the repository
git clone https://github.com/nitin-karthy/RAPI-JWT-Helper.git
cd JWT-Maker
# Build the uber JAR
mvn clean package
# Run tests
mvn test
# The uber JAR will be created at:
# target/jwt.helper-1.0-SNAPSHOT.jarRun tests with:
mvn testIssue: ClassNotFoundException: com.smartbear.JWTHelper
- Solution: Ensure the JAR is placed in the ReadyAPI
extdirectory and ReadyAPI has been restarted.
Issue: Private key file not found
- Solution: Use absolute paths for key files, not relative paths. Verify the file exists and is readable.
Issue: Error generating JWT token: Unsupported key format
- Solution: Ensure your key is in PKCS#8 format (.p8). Convert if necessary using OpenSSL.
Issue: Wrong passphrase error
- Solution: Verify the passphrase is correct. For unencrypted keys, use an empty string
""ornull.
Enable debug logging in your Groovy script:
try {
def jwt = com.smartbear.JWTHelper.make(claims, keyPath, passphrase)
log.info "JWT generated successfully"
} catch (Exception e) {
log.error "Failed to generate JWT: ${e.message}"
log.error "Stack trace: ${e.getStackTrace()}"
throw e
}- Never commit private keys to version control
- Use encrypted keys with strong passphrases in production
- Store keys securely with appropriate file permissions (chmod 600)
- Rotate keys regularly according to your security policy
- Set appropriate expiration times (
expclaim) on tokens - Use HTTPS/TLS when transmitting JWTs over networks
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
Made with ❤️ for the SmartBear ReadyAPI community