io.jsonwebtoken.security.Jwk 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.lang.Supplier;
import java.security.Key;
import java.util.Map;
import java.util.Set;
/**
* A JWK is an immutable set of name/value pairs that represent a cryptographic key as defined by
* RFC 7517: JSON Web Key (JWK). The {@code Jwk}
* interface represents properties common to all JWKs. Subtypes will have additional properties specific to
* different types of cryptographic keys (e.g. Secret, Asymmetric, RSA, Elliptic Curve, etc).
*
* Immutability
*
* JWKs are immutable and cannot be changed after they are created. {@code Jwk} extends the
* {@link Map} interface purely out of convenience: to allow easy marshalling to JSON as well as name/value
* pair access and key/value iteration, and other conveniences provided by the Map interface. Attempting to call any of
* the {@link Map} interface's mutation methods however (such as {@link Map#put(Object, Object) put},
* {@link Map#remove(Object) remove}, {@link Map#clear() clear}, etc) will throw an
* {@link UnsupportedOperationException}.
*
* Identification
*
* {@code Jwk} extends {@link Identifiable} to support the
* JWK {@code kid} parameter. Calling
* {@link #getId() aJwk.getId()} is the type-safe idiomatic approach to the alternative equivalent of
* {@code aJwk.get("kid")}. Either approach will return an id if one was originally set on the JWK, or {@code null} if
* an id does not exist.
*
* Private and Secret Value Safety
*
* JWKs often represent secret or private key data which should never be exposed publicly, nor mistakenly printed
* to application logs or {@code System.out.println} calls. As a result, all JJWT JWK
* private or secret values are 'wrapped' in a {@link io.jsonwebtoken.lang.Supplier Supplier} instance to ensure
* any attempt to call {@link String#toString() toString()} on the value will print a redacted value instead of an
* actual private or secret value.
*
* For example, a {@link SecretJwk} will have an internal "{@code k}" member whose value reflects raw
* key material that should always be kept secret. If the following is called:
*
* System.out.println(aSecretJwk.get("k"));
* You would see the following:
*
* <redacted>
* instead of the actual/raw {@code k} value.
*
* Similarly, if attempting to print the entire JWK:
*
* System.out.println(aSecretJwk);
* You would see the following substring in the output:
*
* k=<redacted>
* instead of the actual/raw {@code k} value.
*
* Finally, because all private or secret values are wrapped as {@link io.jsonwebtoken.lang.Supplier}
* instances, if you really wanted the real internal value, you could just call the supplier's
* {@link Supplier#get() get()} method:
*
* String k = ((Supplier<String>)aSecretJwk.get("k")).get();
* but BE CAREFUL: obtaining the raw value in your application code exposes greater security
* risk - you must ensure to keep that value safe and out of console or log output. It is almost always better to
* interact with the JWK's {@link #toKey() toKey()} instance directly instead of accessing
* JWK internal serialization parameters.
*
* @param The type of Java {@link Key} represented by this JWK
* @since 0.12.0
*/
public interface Jwk extends Identifiable, Map {
/**
* Returns the JWK
* {@code alg} (Algorithm) value
* or {@code null} if not present.
*
* @return the JWK {@code alg} value or {@code null} if not present.
*/
String getAlgorithm();
/**
* Returns the JWK {@code key_ops}
* (Key Operations) parameter values or {@code null} if not present. All JWK standard Key Operations are
* available via the {@link Jwks.OP} registry, but other (custom) values MAY be present in the returned
* set.
*
* @return the JWK {@code key_ops} value or {@code null} if not present.
* @see key_ops
(Key Operations) Parameter
*/
Set getOperations();
/**
* Returns the required JWK
* {@code kty} (Key Type)
* parameter value. A value is required and may not be {@code null}.
*
* The JWA specification defines the
* following {@code kty} values:
*
*
* JWK Key Types
*
*
* Value
* Key Type
*
*
*
*
* {@code EC}
* Elliptic Curve [DSS]
*
*
* {@code RSA}
* RSA [RFC 3447]
*
*
* {@code oct}
* Octet sequence (used to represent symmetric keys)
*
*
* {@code OKP}
* Octet Key Pair (used to represent Edwards
* Elliptic Curve keys)
*
*
*
*
* @return the JWK {@code kty} (Key Type) value.
*/
String getType();
/**
* Computes and returns the canonical JWK Thumbprint of this
* JWK using the {@code SHA-256} hash algorithm. This is a convenience method that delegates to
* {@link #thumbprint(HashAlgorithm)} with a {@code SHA-256} {@link HashAlgorithm} instance.
*
* @return the canonical JWK Thumbprint of this
* JWK using the {@code SHA-256} hash algorithm.
* @see #thumbprint(HashAlgorithm)
*/
JwkThumbprint thumbprint();
/**
* Computes and returns the canonical JWK Thumbprint of this
* JWK using the specified hash algorithm.
*
* @param alg the hash algorithm to use to compute the digest of the canonical JWK Thumbprint JSON form of this JWK.
* @return the canonical JWK Thumbprint of this
* JWK using the specified hash algorithm.
*/
JwkThumbprint thumbprint(HashAlgorithm alg);
/**
* Represents the JWK as its corresponding Java {@link Key} instance for use with Java cryptographic
* APIs.
*
* @return the JWK's corresponding Java {@link Key} instance for use with Java cryptographic APIs.
*/
K toKey();
}