001package com.nimbusds.openid.connect.sdk.claims; 002 003 004import java.nio.charset.Charset; 005import java.security.MessageDigest; 006import java.security.NoSuchAlgorithmException; 007import java.util.Arrays; 008 009import org.apache.commons.codec.binary.Base64; 010 011import com.nimbusds.jose.JWSAlgorithm; 012 013import com.nimbusds.oauth2.sdk.id.Identifier; 014 015 016/** 017 * The base class for SHA-2 based claims. 018 * 019 * @author Vladimir Dzhuvinov 020 */ 021public abstract class HashClaim extends Identifier { 022 023 024 /** 025 * Creates a new SHA-2 based claim with the specified value. 026 * 027 * @param value The claim value. Must not be {@code null}. 028 */ 029 protected HashClaim(final String value) { 030 031 super(value); 032 } 033 034 035 /** 036 * Gets the matching SHA-2 message digest for the specified JSON Web 037 * Signature (JWS) algorithm. 038 * 039 * @param alg The JWS algorithm. Must not be {@code null}. 040 * 041 * @return The SHA-2 message digest, {@code null} if the JWS algorithm 042 * or its corresponding SHA-2 message digest are not supported. 043 */ 044 public static MessageDigest getMessageDigestInstance(final JWSAlgorithm alg) { 045 046 String mdAlg; 047 048 if (alg.equals(JWSAlgorithm.HS256) || 049 alg.equals(JWSAlgorithm.RS256) || 050 alg.equals(JWSAlgorithm.ES256) || 051 alg.equals(JWSAlgorithm.PS256) ) { 052 053 mdAlg = "SHA-256"; 054 055 } else if (alg.equals(JWSAlgorithm.HS384) || 056 alg.equals(JWSAlgorithm.RS384) || 057 alg.equals(JWSAlgorithm.ES384) || 058 alg.equals(JWSAlgorithm.PS384) ) { 059 060 mdAlg = "SHA-384"; 061 062 } else if (alg.equals(JWSAlgorithm.HS512) || 063 alg.equals(JWSAlgorithm.RS512) || 064 alg.equals(JWSAlgorithm.ES512) || 065 alg.equals(JWSAlgorithm.PS512) ) { 066 067 mdAlg = "SHA-512"; 068 069 } else { 070 // unsupported JWS alg 071 return null; 072 } 073 074 try { 075 return MessageDigest.getInstance(mdAlg); 076 077 } catch (NoSuchAlgorithmException e) { 078 079 // unsupported SHA-2 alg 080 return null; 081 } 082 } 083 084 085 /** 086 * Computes the SHA-2 claim value for the specified identifier. 087 * 088 * @param identifier The identifier, typically an authorisation code or 089 * an access token. Must not be {@code null}. 090 * @param alg The reference JSON Web Signature (JWS) algorithm. 091 * Must not be {@code null}. 092 * 093 * @return The matching (truncated to first half) SHA-2 claim value, 094 * or {@code null} if the JWS algorithm or its corresponding 095 * SHA-2 message digest are not supported. 096 */ 097 public static String computeValue(final Identifier identifier, final JWSAlgorithm alg) { 098 099 MessageDigest md = getMessageDigestInstance(alg); 100 101 if (md == null) 102 return null; 103 104 md.update(identifier.getValue().getBytes(Charset.forName("US-ASCII"))); 105 106 byte[] hash = md.digest(); 107 108 byte[] firstHalf = Arrays.copyOf(hash, hash.length / 2); 109 110 return Base64.encodeBase64URLSafeString(firstHalf); 111 } 112}