001/*
002 * nimbus-jose-jwt
003 *
004 * Copyright 2012-2016, Connect2id Ltd.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.jose.jwk;
019
020
021import java.security.MessageDigest;
022import java.security.NoSuchAlgorithmException;
023import java.util.LinkedHashMap;
024
025import com.nimbusds.jose.JOSEException;
026import com.nimbusds.jose.util.Base64URL;
027import com.nimbusds.jose.util.JSONObjectUtils;
028import com.nimbusds.jose.util.StandardCharset;
029
030
031/**
032 * Thumbprint utilities.
033 *
034 * <p>See RFC 7638.
035 *
036 * @author Vladimir Dzhuvinov
037 * @version 2016-07-26
038 */
039public final class ThumbprintUtils {
040
041
042        /**
043         * Computes the SHA-256 thumbprint for the specified JWK.
044         *
045         * @param jwk The JWK. Must not be {@code null}.
046         *
047         * @return The JWK thumbprint.
048         *
049         * @throws JOSEException If the SHA-256 hash algorithm is not
050         *                       supported.
051         */
052        public static Base64URL compute(final JWK jwk)
053                throws JOSEException {
054
055                return compute("SHA-256", jwk);
056        }
057
058
059        /**
060         * Computes the thumbprint for the specified JWK.
061         *
062         * @param hashAlg The hash algorithm. Must not be {@code null}.
063         * @param jwk     The JWK. Must not be {@code null}.
064         *
065         * @return The JWK thumbprint.
066         *
067         * @throws JOSEException If the hash algorithm is not supported.
068         */
069        public static Base64URL compute(final String hashAlg, final JWK jwk)
070                throws JOSEException {
071
072                final LinkedHashMap<String, ?> orderedParams =  jwk.getRequiredParams();
073
074                return compute(hashAlg, orderedParams);
075        }
076
077
078        /**
079         * Computes the thumbprint for the specified required JWK parameters.
080         *
081         * @param hashAlg The hash algorithm. Must not be {@code null}.
082         * @param params  The required JWK parameters, alphanumerically sorted
083         *                by parameter name and ready for JSON object
084         *                serialisation. Must not be {@code null}.
085         *
086         * @return The JWK thumbprint.
087         *
088         * @throws JOSEException If the hash algorithm is not supported.
089         */
090        public static Base64URL compute(final String hashAlg, final LinkedHashMap<String,?> params)
091                throws JOSEException {
092
093                final String json = JSONObjectUtils.toJSONString(params);
094
095                final MessageDigest md;
096
097                try {
098                        md = MessageDigest.getInstance(hashAlg);
099
100                } catch (NoSuchAlgorithmException e) {
101
102                        throw new JOSEException("Couldn't compute JWK thumbprint: Unsupported hash algorithm: " + e.getMessage(), e);
103                }
104
105                md.update(json.getBytes(StandardCharset.UTF_8));
106
107                return Base64URL.encode(md.digest());
108        }
109}