JdkTokenBuilder.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package uk.co.spudsoft.jwtvalidatorvertx.jdk;
import com.google.common.cache.Cache;
import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.ECGenParameterSpec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.co.spudsoft.jwtvalidatorvertx.AlgorithmAndKeyPair;
import uk.co.spudsoft.jwtvalidatorvertx.JsonWebAlgorithm;
import uk.co.spudsoft.jwtvalidatorvertx.impl.AbstractTokenBuilder;
/**
* Implementation of TokenBuilder that uses the JDK {@link java.security.KeyPairGenerator} to generate key pairs.
* @author jtalbut
*/
public class JdkTokenBuilder extends AbstractTokenBuilder {
@SuppressWarnings("constantname")
private static final Logger logger = LoggerFactory.getLogger(JdkTokenBuilder.class);
/**
* Constructor.
* @param keyCache The key cache to be filled with keys created by the token builder.
*/
public JdkTokenBuilder(Cache<String, AlgorithmAndKeyPair> keyCache) {
super(keyCache);
}
private KeyPair generateKey(String kid, JsonWebAlgorithm algorithm) throws Exception {
if ("RSA".equals(algorithm.getFamilyName())) {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(algorithm.getMinKeyLength());
return keyGen.genKeyPair();
}
if ("ECDSA".equals(algorithm.getFamilyName())) {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
ECGenParameterSpec spec = new ECGenParameterSpec(algorithm.getSubName());
keyGen.initialize(spec);
return keyGen.genKeyPair();
}
if ("EdDSA".equals(algorithm.getFamilyName())) {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algorithm.getJdkAlgName());
return keyGen.genKeyPair();
}
if (algorithm == JsonWebAlgorithm.none) {
return null;
}
throw new IllegalArgumentException("Test harness does not support keys for " + algorithm.toString());
}
@Override
protected byte[] generateSignature(String kid, JsonWebAlgorithm algorithm, String headerBase64, String claimsBase64) throws Exception {
AlgorithmAndKeyPair akp;
synchronized (keyCache) {
akp = keyCache.get(kid, () -> {
KeyPair kp = generateKey(kid, algorithm);
return new AlgorithmAndKeyPair(algorithm, kp);
});
}
return generateSignature(akp.getKeyPair().getPrivate(), algorithm, headerBase64 + "." + claimsBase64);
}
/**
* Generate a signature using the JDK security classes.
* @param privateKey The private key to sign the input with.
* @param algorithm The algorithm to use for the signing.
* @param signingInput The content to be signed.
* @return A byte array containing the signature.
* @throws Exception If thrown by the JDK security subsystem.
*/
public static byte[] generateSignature(PrivateKey privateKey, JsonWebAlgorithm algorithm, String signingInput) throws Exception {
Signature signer = Signature.getInstance(algorithm.getJdkAlgName());
signer.initSign(privateKey);
signer.update(signingInput.getBytes(StandardCharsets.UTF_8));
return signer.sign();
}
}