All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.jsonwebtoken.security.Jwks Maven / Gradle / Ivy

/*
 * Copyright (C) 2021 jsonwebtoken.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.jsonwebtoken.security;

import io.jsonwebtoken.Identifiable;
import io.jsonwebtoken.io.Parser;
import io.jsonwebtoken.lang.Classes;
import io.jsonwebtoken.lang.Registry;

/**
 * Utility methods for creating
 * JWKs (JSON Web Keys) with a type-safe builder.
 *
 * 

Standard JWK Thumbprint Algorithm References

*

Standard IANA Hash * Algorithms commonly used to compute {@link JwkThumbprint JWK Thumbprint}s and ensure valid * JWK Thumbprint URIs * are available via the {@link Jwks.HASH} registry constants to allow for easy code-completion in IDEs. For example, when * typing:

*
 * Jwks.{@link Jwks.HASH HASH}.// press hotkeys to suggest individual hash algorithms or utility methods
* * @see #builder() * @since 0.12.0 */ public final class Jwks { private Jwks() { } //prevent instantiation private static final String JWKS_BRIDGE_FQCN = "io.jsonwebtoken.impl.security.JwksBridge"; private static final String BUILDER_FQCN = "io.jsonwebtoken.impl.security.DefaultDynamicJwkBuilder"; private static final String PARSER_BUILDER_FQCN = "io.jsonwebtoken.impl.security.DefaultJwkParserBuilder"; private static final String SET_BUILDER_FQCN = "io.jsonwebtoken.impl.security.DefaultJwkSetBuilder"; private static final String SET_PARSER_BUILDER_FQCN = "io.jsonwebtoken.impl.security.DefaultJwkSetParserBuilder"; /** * Return a new JWK builder instance, allowing for type-safe JWK builder coercion based on a specified key or key pair. * * @return a new JWK builder instance, allowing for type-safe JWK builder coercion based on a specified key or key pair. */ public static DynamicJwkBuilder builder() { return Classes.newInstance(BUILDER_FQCN); } /** * Returns a new builder used to create {@link Parser}s that parse JSON into {@link Jwk} instances. For example: *
     * Jwk<?> jwk = Jwks.parser()
     *         //.provider(aJcaProvider)     // optional
     *         //.deserializer(deserializer) // optional
     *         //.operationPolicy(policy)    // optional
     *         .build()
     *         .parse(jwkString);
* * @return a new builder used to create {@link Parser}s that parse JSON into {@link Jwk} instances. */ public static JwkParserBuilder parser() { return Classes.newInstance(PARSER_BUILDER_FQCN); } /** * Return a new builder used to create {@link JwkSet}s. For example: *
     * JwkSet jwkSet = Jwks.set()
     *     //.provider(aJcaProvider)     // optional
     *     //.operationPolicy(policy)    // optional
     *     .add(aJwk)                    // appends a key
     *     .add(aCollection)             // appends multiple keys
     *     //.keys(allJwks)              // sets/replaces all keys
     *     .build()
     * 
* * @return a new builder used to create {@link JwkSet}s */ public static JwkSetBuilder set() { return Classes.newInstance(SET_BUILDER_FQCN); } /** * Returns a new builder used to create {@link Parser}s that parse JSON into {@link JwkSet} instances. For example: *
     * JwkSet jwkSet = Jwks.setParser()
     *         //.provider(aJcaProvider)     // optional
     *         //.deserializer(deserializer) // optional
     *         //.operationPolicy(policy)    // optional
     *         .build()
     *         .parse(jwkSetString);
* * @return a new builder used to create {@link Parser}s that parse JSON into {@link JwkSet} instances. */ public static JwkSetParserBuilder setParser() { return Classes.newInstance(SET_PARSER_BUILDER_FQCN); } /** * Converts the specified {@link PublicJwk} into JSON. Because {@link PublicJwk}s do not contain secret or private * key material, they are safe to be printed to application logs or {@code System.out}. * * @param publicJwk the {@code PublicJwk} to convert to JSON * @return the JWK's canonical JSON value */ public static String json(PublicJwk publicJwk) { return UNSAFE_JSON(publicJwk); // safe by nature of it being a Public JWK } /** * WARNING - UNSAFE OPERATION - RETURN VALUES CONTAIN RAW KEY MATERIAL, DO NOT LOG OR PRINT TO SYSTEM.OUT. * Converts the specified JWK into JSON, including raw key material. If the specified JWK * is a {@link SecretJwk} or a {@link PrivateJwk}, be very careful with the return value, ensuring it is not * printed to application logs or system.out. * * @param jwk the JWK to convert to JSON * @return the JWK's canonical JSON value */ public static String UNSAFE_JSON(Jwk jwk) { return Classes.invokeStatic(JWKS_BRIDGE_FQCN, "UNSAFE_JSON", new Class[]{Jwk.class}, jwk); } /** * Constants for all standard JWK * crv (Curve) parameter values * defined in the JSON Web Key Elliptic * Curve Registry (including its * Edwards Elliptic Curve additions). * Each standard algorithm is available as a ({@code public static final}) constant for direct type-safe * reference in application code. For example: *
     * Jwks.CRV.P256.keyPair().build();
*

They are also available together as a {@link Registry} instance via the {@link #get()} method.

* * @see #get() * @since 0.12.0 */ public static final class CRV { private static final String IMPL_CLASSNAME = "io.jsonwebtoken.impl.security.StandardCurves"; private static final Registry REGISTRY = Classes.newInstance(IMPL_CLASSNAME); /** * Returns a registry of all standard Elliptic Curves in the {@code JSON Web Key Elliptic Curve Registry} * defined by RFC 7518, Section 7.6 * (for Weierstrass Elliptic Curves) and * RFC 8037, Section 5 (for Edwards Elliptic Curves). * * @return a registry of all standard Elliptic Curves in the {@code JSON Web Key Elliptic Curve Registry}. */ public static Registry get() { return REGISTRY; } /** * {@code P-256} Elliptic Curve defined by * RFC 7518, Section 6.2.1.1 * using the native Java JCA {@code secp256r1} algorithm. * * @see Java Security Standard Algorithm Names */ public static final Curve P256 = get().forKey("P-256"); /** * {@code P-384} Elliptic Curve defined by * RFC 7518, Section 6.2.1.1 * using the native Java JCA {@code secp384r1} algorithm. * * @see Java Security Standard Algorithm Names */ public static final Curve P384 = get().forKey("P-384"); /** * {@code P-521} Elliptic Curve defined by * RFC 7518, Section 6.2.1.1 * using the native Java JCA {@code secp521r1} algorithm. * * @see Java Security Standard Algorithm Names */ public static final Curve P521 = get().forKey("P-521"); /** * {@code Ed25519} Elliptic Curve defined by * RFC 8037, Section 3.1 * using the native Java JCA {@code Ed25519}1 algorithm. * *

1 Requires Java 15 or a compatible JCA Provider (like BouncyCastle) in the runtime * classpath. If on Java 14 or earlier, BouncyCastle will be used automatically if found in the runtime * classpath.

* * @see Java Security Standard Algorithm Names */ public static final Curve Ed25519 = get().forKey("Ed25519"); /** * {@code Ed448} Elliptic Curve defined by * RFC 8037, Section 3.1 * using the native Java JCA {@code Ed448}1 algorithm. * *

1 Requires Java 15 or a compatible JCA Provider (like BouncyCastle) in the runtime * classpath. If on Java 14 or earlier, BouncyCastle will be used automatically if found in the runtime * classpath.

* * @see Java Security Standard Algorithm Names */ public static final Curve Ed448 = get().forKey("Ed448"); /** * {@code X25519} Elliptic Curve defined by * RFC 8037, Section 3.2 * using the native Java JCA {@code X25519}1 algorithm. * *

1 Requires Java 11 or a compatible JCA Provider (like BouncyCastle) in the runtime * classpath. If on Java 10 or earlier, BouncyCastle will be used automatically if found in the runtime * classpath.

* * @see Java Security Standard Algorithm Names */ public static final Curve X25519 = get().forKey("X25519"); /** * {@code X448} Elliptic Curve defined by * RFC 8037, Section 3.2 * using the native Java JCA {@code X448}1 algorithm. * *

1 Requires Java 11 or a compatible JCA Provider (like BouncyCastle) in the runtime * classpath. If on Java 10 or earlier, BouncyCastle will be used automatically if found in the runtime * classpath.

* * @see Java Security Standard Algorithm Names */ public static final Curve X448 = get().forKey("X448"); //prevent instantiation private CRV() { } } /** * Various (but not all) * IANA Hash * Algorithms commonly used to compute {@link JwkThumbprint JWK Thumbprint}s and ensure valid * JWK Thumbprint URIs. * Each algorithm is made available as a ({@code public static final}) constant for direct type-safe * reference in application code. For example: *
     * Jwks.{@link Jwks#builder}()
     *     // ... etc ...
     *     .{@link JwkBuilder#idFromThumbprint(HashAlgorithm) idFromThumbprint}(Jwts.HASH.{@link Jwks.HASH#SHA256 SHA256}) // <---
     *     .build()
*

or

*
     * HashAlgorithm hashAlg = Jwks.HASH.{@link Jwks.HASH#SHA256 SHA256};
     * {@link JwkThumbprint} thumbprint = aJwk.{@link Jwk#thumbprint(HashAlgorithm) thumbprint}(hashAlg);
     * String rfcMandatoryPrefix = "urn:ietf:params:oauth:jwk-thumbprint:" + hashAlg.getId();
     * assert thumbprint.toURI().toString().startsWith(rfcMandatoryPrefix);
     * 
*

They are also available together as a {@link Registry} instance via the {@link #get()} method.

* * @see #get() * @since 0.12.0 */ public static final class HASH { private static final String IMPL_CLASSNAME = "io.jsonwebtoken.impl.security.StandardHashAlgorithms"; private static final Registry REGISTRY = Classes.newInstance(IMPL_CLASSNAME); /** * Returns a registry of various (but not all) * IANA Hash * Algorithms commonly used to compute {@link JwkThumbprint JWK Thumbprint}s and ensure valid * JWK Thumbprint URIs. * * @return a registry of various (but not all) * IANA Hash * Algorithms commonly used to compute {@link JwkThumbprint JWK Thumbprint}s and ensure valid * JWK Thumbprint URIs. */ public static Registry get() { return REGISTRY; } /** * IANA * hash algorithm with an {@link Identifiable#getId() id} (aka IANA "{@code Hash Name String}") * value of {@code sha-256}. It is a {@code HashAlgorithm} alias for the native * Java JCA {@code SHA-256} {@code MessageDigest} algorithm. */ public static final HashAlgorithm SHA256 = get().forKey("sha-256"); /** * IANA * hash algorithm with an {@link Identifiable#getId() id} (aka IANA "{@code Hash Name String}") * value of {@code sha-384}. It is a {@code HashAlgorithm} alias for the native * Java JCA {@code SHA-384} {@code MessageDigest} algorithm. */ public static final HashAlgorithm SHA384 = get().forKey("sha-384"); /** * IANA * hash algorithm with an {@link Identifiable#getId() id} (aka IANA "{@code Hash Name String}") * value of {@code sha-512}. It is a {@code HashAlgorithm} alias for the native * Java JCA {@code SHA-512} {@code MessageDigest} algorithm. */ public static final HashAlgorithm SHA512 = get().forKey("sha-512"); /** * IANA * hash algorithm with an {@link Identifiable#getId() id} (aka IANA "{@code Hash Name String}") * value of {@code sha3-256}. It is a {@code HashAlgorithm} alias for the native * Java JCA {@code SHA3-256} {@code MessageDigest} algorithm. *

This algorithm requires at least JDK 9 or a compatible JCA Provider (like BouncyCastle) in the runtime * classpath.

*/ public static final HashAlgorithm SHA3_256 = get().forKey("sha3-256"); /** * IANA * hash algorithm with an {@link Identifiable#getId() id} (aka IANA "{@code Hash Name String}") * value of {@code sha3-384}. It is a {@code HashAlgorithm} alias for the native * Java JCA {@code SHA3-384} {@code MessageDigest} algorithm. *

This algorithm requires at least JDK 9 or a compatible JCA Provider (like BouncyCastle) in the runtime * classpath.

*/ public static final HashAlgorithm SHA3_384 = get().forKey("sha3-384"); /** * IANA * hash algorithm with an {@link Identifiable#getId() id} (aka IANA "{@code Hash Name String}") * value of {@code sha3-512}. It is a {@code HashAlgorithm} alias for the native * Java JCA {@code SHA3-512} {@code MessageDigest} algorithm. *

This algorithm requires at least JDK 9 or a compatible JCA Provider (like BouncyCastle) in the runtime * classpath.

*/ public static final HashAlgorithm SHA3_512 = get().forKey("sha3-512"); //prevent instantiation private HASH() { } } /** * Constants for all standard JWK * key_ops (Key Operations) parameter values * defined in the JSON Web Key Operations * Registry. Each standard key operation is available as a ({@code public static final}) constant for * direct type-safe reference in application code. For example: *
     * Jwks.builder()
     *     .operations(Jwks.OP.SIGN)
     *     // ... etc ...
     *     .build();
*

They are also available together as a {@link Registry} instance via the {@link #get()} method.

* * @see #get() * @since 0.12.0 */ public static final class OP { private static final String IMPL_CLASSNAME = "io.jsonwebtoken.impl.security.StandardKeyOperations"; private static final Registry REGISTRY = Classes.newInstance(IMPL_CLASSNAME); private static final String BUILDER_CLASSNAME = "io.jsonwebtoken.impl.security.DefaultKeyOperationBuilder"; private static final String POLICY_BUILDER_CLASSNAME = "io.jsonwebtoken.impl.security.DefaultKeyOperationPolicyBuilder"; /** * Creates a new {@link KeyOperationBuilder} for creating custom {@link KeyOperation} instances. * * @return a new {@link KeyOperationBuilder} for creating custom {@link KeyOperation} instances. */ public static KeyOperationBuilder builder() { return Classes.newInstance(BUILDER_CLASSNAME); } /** * Creates a new {@link KeyOperationPolicyBuilder} for creating custom {@link KeyOperationPolicy} instances. * * @return a new {@link KeyOperationPolicyBuilder} for creating custom {@link KeyOperationPolicy} instances. */ public static KeyOperationPolicyBuilder policy() { return Classes.newInstance(POLICY_BUILDER_CLASSNAME); } /** * Returns a registry of all standard Key Operations in the {@code JSON Web Key Operations Registry} * defined by RFC 7517, Section 8.3. * * @return a registry of all standard Key Operations in the {@code JSON Web Key Operations Registry}. */ public static Registry get() { return REGISTRY; } /** * {@code sign} operation indicating a key is intended to be used to compute digital signatures or * MACs. It's related operation is {@link #VERIFY}. * * @see #VERIFY * @see Key Operation Registry Contents */ public static final KeyOperation SIGN = get().forKey("sign"); /** * {@code verify} operation indicating a key is intended to be used to verify digital signatures or * MACs. It's related operation is {@link #SIGN}. * * @see #SIGN * @see Key Operation Registry Contents */ public static final KeyOperation VERIFY = get().forKey("verify"); /** * {@code encrypt} operation indicating a key is intended to be used to encrypt content. It's * related operation is {@link #DECRYPT}. * * @see #DECRYPT * @see Key Operation Registry Contents */ public static final KeyOperation ENCRYPT = get().forKey("encrypt"); /** * {@code decrypt} operation indicating a key is intended to be used to decrypt content. It's * related operation is {@link #ENCRYPT}. * * @see #ENCRYPT * @see Key Operation Registry Contents */ public static final KeyOperation DECRYPT = get().forKey("decrypt"); /** * {@code wrapKey} operation indicating a key is intended to be used to encrypt another key. It's * related operation is {@link #UNWRAP_KEY}. * * @see #UNWRAP_KEY * @see Key Operation Registry Contents */ public static final KeyOperation WRAP_KEY = get().forKey("wrapKey"); /** * {@code unwrapKey} operation indicating a key is intended to be used to decrypt another key and validate * decryption, if applicable. It's related operation is * {@link #WRAP_KEY}. * * @see #WRAP_KEY * @see Key Operation Registry Contents */ public static final KeyOperation UNWRAP_KEY = get().forKey("unwrapKey"); /** * {@code deriveKey} operation indicating a key is intended to be used to derive another key. It does not have * a related operation. * * @see Key Operation Registry Contents */ public static final KeyOperation DERIVE_KEY = get().forKey("deriveKey"); /** * {@code deriveBits} operation indicating a key is intended to be used to derive bits that are not to be * used as key. It does not have a related operation. * * @see Key Operation Registry Contents */ public static final KeyOperation DERIVE_BITS = get().forKey("deriveBits"); //prevent instantiation private OP() { } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy