001package com.nimbusds.jose.jwk;
002
003
004import java.security.MessageDigest;
005import java.security.NoSuchAlgorithmException;
006import java.util.LinkedHashMap;
007
008import com.nimbusds.jose.JOSEException;
009import com.nimbusds.jose.util.Base64URL;
010import com.nimbusds.jose.util.StandardCharset;
011import net.minidev.json.JSONObject;
012
013
014/**
015 * Thumbprint utilities.
016 *
017 * <p>See RFC 7638.
018 *
019 * @author Vladimir Dzhuvinov
020 * @version 2016-07-26
021 */
022public final class ThumbprintUtils {
023
024
025        /**
026         * Computes the SHA-256 thumbprint for the specified JWK.
027         *
028         * @param jwk The JWK. Must not be {@code null}.
029         *
030         * @return The JWK thumbprint.
031         *
032         * @throws JOSEException If the SHA-256 hash algorithm is not
033         *                       supported.
034         */
035        public static Base64URL compute(final JWK jwk)
036                throws JOSEException {
037
038                return compute("SHA-256", jwk);
039        }
040
041
042        /**
043         * Computes the thumbprint for the specified JWK.
044         *
045         * @param hashAlg The hash algorithm. Must not be {@code null}.
046         * @param jwk     The JWK. Must not be {@code null}.
047         *
048         * @return The JWK thumbprint.
049         *
050         * @throws JOSEException If the hash algorithm is not supported.
051         */
052        public static Base64URL compute(final String hashAlg, final JWK jwk)
053                throws JOSEException {
054
055                final LinkedHashMap<String,?> orderedParams = jwk.getRequiredParams();
056
057                return compute(hashAlg, orderedParams);
058        }
059
060
061        /**
062         * Computes the thumbprint for the specified required JWK parameters.
063         *
064         * @param hashAlg The hash algorithm. Must not be {@code null}.
065         * @param params  The required JWK parameters, alphanumerically sorted
066         *                by parameter name and ready for JSON object
067         *                serialisation. Must not be {@code null}.
068         *
069         * @return The JWK thumbprint.
070         *
071         * @throws JOSEException If the hash algorithm is not supported.
072         */
073        public static Base64URL compute(final String hashAlg, final LinkedHashMap<String,?> params)
074                throws JOSEException {
075
076                final String json = JSONObject.toJSONString(params);
077
078                final MessageDigest md;
079
080                try {
081                        md = MessageDigest.getInstance(hashAlg);
082
083                } catch (NoSuchAlgorithmException e) {
084
085                        throw new JOSEException("Couldn't compute JWK thumbprint: Unsupported hash algorithm: " + e.getMessage(), e);
086                }
087
088                md.update(json.getBytes(StandardCharset.UTF_8));
089
090                return Base64URL.encode(md.digest());
091        }
092}