001package com.nimbusds.jose.crypto; 002 003 004import net.jcip.annotations.ThreadSafe; 005 006import com.nimbusds.jose.DefaultJWSHeaderFilter; 007import com.nimbusds.jose.JOSEException; 008import com.nimbusds.jose.JWSHeaderFilter; 009import com.nimbusds.jose.JWSVerifier; 010import com.nimbusds.jose.ReadOnlyJWSHeader; 011import com.nimbusds.jose.util.Base64URL; 012 013 014/** 015 * Message Authentication Code (MAC) verifier of 016 * {@link com.nimbusds.jose.JWSObject JWS objects}. This class is thread-safe. 017 * 018 * <p>Supports the following JSON Web Algorithms (JWAs): 019 * 020 * <ul> 021 * <li>{@link com.nimbusds.jose.JWSAlgorithm#HS256} 022 * <li>{@link com.nimbusds.jose.JWSAlgorithm#HS384} 023 * <li>{@link com.nimbusds.jose.JWSAlgorithm#HS512} 024 * </ul> 025 * 026 * <p>Accepts all {@link com.nimbusds.jose.JWSHeader#getReservedParameterNames 027 * reserved JWS header parameters}. Modify the {@link #getJWSHeaderFilter 028 * header filter} properties to restrict the acceptable JWS algorithms and 029 * header parameters, or to allow custom JWS header parameters. 030 * 031 * @author Vladimir Dzhuvinov 032 * @version $version$ (2013-03-22) 033 */ 034@ThreadSafe 035public class MACVerifier extends MACProvider implements JWSVerifier { 036 037 038 /** 039 * The JWS header filter. 040 */ 041 private final DefaultJWSHeaderFilter headerFilter; 042 043 044 /** 045 * Creates a new Message Authentication (MAC) verifier. 046 * 047 * @param sharedSecret The shared secret. Must not be {@code null}. 048 */ 049 public MACVerifier(final byte[] sharedSecret) { 050 051 super(sharedSecret); 052 053 headerFilter = new DefaultJWSHeaderFilter(supportedAlgorithms()); 054 } 055 056 057 @Override 058 public JWSHeaderFilter getJWSHeaderFilter() { 059 060 return headerFilter; 061 } 062 063 064 @Override 065 public boolean verify(final ReadOnlyJWSHeader header, 066 final byte[] signedContent, 067 final Base64URL signature) 068 throws JOSEException { 069 070 String jcaAlg = getJCAAlgorithmName(header.getAlgorithm()); 071 072 byte[] hmac = HMAC.compute(jcaAlg, getSharedSecret(), signedContent); 073 074 Base64URL expectedSignature = Base64URL.encode(hmac); 075 076 if (expectedSignature.equals(signature)) { 077 078 return true; 079 080 } else { 081 082 return false; 083 } 084 } 085}