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