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