use of io.helidon.security.jwt.jwk.JwkEC in project helidon by oracle.
the class EncryptedJwt method decrypt.
/**
* Decrypt {@link SignedJwt} from the content of the encrypted jwt.
* If the kid header is specified among encrypted JWT headers, it will be used to match corresponding key
* from the jwkKeys. If no kid is specified, provided default Jwk is used.
*
* Used {@link Jwk} needs to have private key set.
*
* @param jwkKeys jwk keys
* @param defaultJwk default jwk
* @return empty optional if any error has occurred or SignedJwt instance if the decryption and validation was successful
*/
public SignedJwt decrypt(JwkKeys jwkKeys, Jwk defaultJwk) {
Errors.Collector errors = Errors.collector();
String headerBase64 = encode(header.headerJson().toString().getBytes(StandardCharsets.UTF_8));
String alg = header.algorithm().orElse(null);
String kid = header.keyId().orElse(null);
String enc = header.encryption().orElse(null);
Jwk jwk = null;
String algorithm = null;
if (kid != null) {
if (jwkKeys != null) {
jwk = jwkKeys.forKeyId(kid).orElse(null);
} else if (kid.equals(defaultJwk.keyId())) {
jwk = defaultJwk;
} else {
errors.fatal("Could not find JWK for kid: " + kid);
}
} else {
jwk = defaultJwk;
if (jwk == null) {
errors.fatal("Could not find any suitable JWK.");
}
}
if (enc == null) {
errors.fatal("Content encryption algorithm not set.");
}
if (alg != null) {
try {
SupportedAlgorithm supportedAlgorithm = SupportedAlgorithm.getValue(alg);
algorithm = RSA_ALGORITHMS.get(supportedAlgorithm);
} catch (IllegalArgumentException e) {
errors.fatal("Value of the claim alg not supported. alg: " + alg);
}
} else {
errors.fatal("No alg header was present among JWE headers");
}
PrivateKey privateKey = null;
Jwk finalJwk = jwk;
if (jwk instanceof JwkRSA) {
privateKey = ((JwkRSA) jwk).privateKey().orElseGet(() -> {
errors.fatal("No private key present in RSA JWK kid: " + finalJwk.keyId());
return null;
});
} else if (jwk instanceof JwkEC) {
privateKey = ((JwkEC) jwk).privateKey().orElseGet(() -> {
errors.fatal("No private key present in EC JWK kid: " + finalJwk.keyId());
return null;
});
} else if (jwk != null) {
errors.fatal("Not supported JWK type: " + jwk.keyType() + ", JWK class: " + jwk.getClass().getName());
} else {
errors.fatal("No JWK found for key id: " + kid);
}
errors.collect().checkValid();
byte[] decryptedKey = decryptRsa(algorithm, privateKey, encryptedKey);
// Base64 headers are used as an aad. This aad has to be in US_ASCII encoding.
EncryptionParts encryptionParts = new EncryptionParts(decryptedKey, iv, headerBase64.getBytes(StandardCharsets.US_ASCII), encryptedPayload, authTag);
AesAlgorithm aesAlgorithm;
try {
SupportedEncryption supportedEncryption = SupportedEncryption.getValue(enc);
aesAlgorithm = CONTENT_ENCRYPTION.get(supportedEncryption);
} catch (IllegalArgumentException e) {
throw new JwtException("Unsupported content encryption: " + enc);
}
String decryptedPayload = new String(aesAlgorithm.decrypt(encryptionParts), StandardCharsets.UTF_8);
return SignedJwt.parseToken(decryptedPayload);
}
Aggregations