Search in sources :

Example 1 with JwkEC

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);
}
Also used : PrivateKey(java.security.PrivateKey) JwkRSA(io.helidon.security.jwt.jwk.JwkRSA) Errors(io.helidon.common.Errors) JwkEC(io.helidon.security.jwt.jwk.JwkEC) Jwk(io.helidon.security.jwt.jwk.Jwk)

Aggregations

Errors (io.helidon.common.Errors)1 Jwk (io.helidon.security.jwt.jwk.Jwk)1 JwkEC (io.helidon.security.jwt.jwk.JwkEC)1 JwkRSA (io.helidon.security.jwt.jwk.JwkRSA)1 PrivateKey (java.security.PrivateKey)1