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-05-16) 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 /** 058 * Creates a new Message Authentication (MAC) verifier. 059 * 060 * @param sharedSecretString The shared secret as a UTF-8 encoded 061 * string. Must not be {@code null}. 062 */ 063 public MACVerifier(final String sharedSecretString) { 064 065 super(sharedSecretString); 066 067 headerFilter = new DefaultJWSHeaderFilter(supportedAlgorithms()); 068 } 069 070 071 @Override 072 public JWSHeaderFilter getJWSHeaderFilter() { 073 074 return headerFilter; 075 } 076 077 078 @Override 079 public boolean verify(final ReadOnlyJWSHeader header, 080 final byte[] signedContent, 081 final Base64URL signature) 082 throws JOSEException { 083 084 String jcaAlg = getJCAAlgorithmName(header.getAlgorithm()); 085 086 byte[] hmac = HMAC.compute(jcaAlg, getSharedSecret(), signedContent); 087 088 Base64URL expectedSignature = Base64URL.encode(hmac); 089 090 if (expectedSignature.equals(signature)) { 091 092 return true; 093 094 } else { 095 096 return false; 097 } 098 } 099}