001    package com.nimbusds.jose.crypto;
002    
003    
004    import java.security.InvalidKeyException;
005    
006    import javax.crypto.Mac;
007    
008    import javax.crypto.spec.SecretKeySpec;
009    
010    import net.jcip.annotations.ThreadSafe;
011    
012    import com.nimbusds.jose.JOSEException;
013    import com.nimbusds.jose.JWSSigner;
014    import com.nimbusds.jose.ReadOnlyJWSHeader;
015    
016    import com.nimbusds.jose.util.Base64URL;
017    
018    
019    
020    /**
021     * Message Authentication Code (MAC) signer of 
022     * {@link com.nimbusds.jose.JWSObject JWS objects}. This class is thread-safe.
023     *
024     * <p>Supports the following JSON Web Algorithms (JWAs):
025     *
026     * <ul>
027     *     <li>{@link com.nimbusds.jose.JWSAlgorithm#HS256}
028     *     <li>{@link com.nimbusds.jose.JWSAlgorithm#HS384}
029     *     <li>{@link com.nimbusds.jose.JWSAlgorithm#HS512}
030     * </ul>
031     * 
032     * @author Vladimir Dzhuvinov
033     * @version $version$ (2012-10-23)
034     */
035    @ThreadSafe
036    public class MACSigner extends MACProvider implements JWSSigner {
037    
038    
039            /**
040             * Creates a new Message Authentication (MAC) signer.
041             *
042             * @param sharedSecret The shared secret. Must not be {@code null}.
043             */
044            public MACSigner(final byte[] sharedSecret) {
045    
046                    super(sharedSecret);
047            }
048    
049    
050            @Override
051            public Base64URL sign(final ReadOnlyJWSHeader header, final byte[] signableContent)
052                    throws JOSEException {
053                    
054                    Mac mac = getMAC(header.getAlgorithm());
055                    
056                    try {
057                            mac.init(new SecretKeySpec(getSharedSecret(), mac.getAlgorithm()));
058                            
059                    } catch (InvalidKeyException e) {
060                    
061                            throw new JOSEException("Invalid HMAC key: " + e.getMessage(), e);
062                    }
063                    
064                    mac.update(signableContent);
065                    
066                    return Base64URL.encode(mac.doFinal());
067            }
068    }