1 /*
2  * Copyright (C) 2014 jsonwebtoken.io
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package io.jsonwebtoken.impl.crypto;
17
18 import io.jsonwebtoken.SignatureAlgorithm;
19 import io.jsonwebtoken.SignatureException;
20 import io.jsonwebtoken.lang.Assert;
21
22 import javax.crypto.Mac;
23 import javax.crypto.SecretKey;
24 import javax.crypto.spec.SecretKeySpec;
25 import java.security.InvalidKeyException;
26 import java.security.Key;
27 import java.security.NoSuchAlgorithmException;
28
29 public class MacSigner extends MacProvider implements Signer {
30
31     public MacSigner(SignatureAlgorithm alg, byte[] key) {
32         this(alg, new SecretKeySpec(key, alg.getJcaName()));
33     }
34
35     public MacSigner(SignatureAlgorithm alg, Key key) {
36         super(alg, key);
37         Assert.isTrue(alg.isHmac(), "The MacSigner only supports HMAC signature algorithms.");
38         if (!(key instanceof SecretKey)) {
39             String msg = "MAC signatures must be computed and verified using a SecretKey.  The specified key of " +
40                          "type " + key.getClass().getName() + " is not a SecretKey.";
41             throw new IllegalArgumentException(msg);
42         }
43     }
44
45     @Override
46     public byte[] sign(byte[] data) {
47         Mac mac = getMacInstance();
48         return mac.doFinal(data);
49     }
50
51     protected Mac getMacInstance() throws SignatureException {
52         try {
53             return doGetMacInstance();
54         } catch (NoSuchAlgorithmException e) {
55             String msg = "Unable to obtain JCA MAC algorithm '" + alg.getJcaName() + "': " + e.getMessage();
56             throw new SignatureException(msg, e);
57         } catch (InvalidKeyException e) {
58             String msg = "The specified signing key is not a valid " + alg.name() + " key: " + e.getMessage();
59             throw new SignatureException(msg, e);
60         }
61     }
62
63     protected Mac doGetMacInstance() throws NoSuchAlgorithmException, InvalidKeyException {
64         Mac mac = Mac.getInstance(alg.getJcaName());
65         mac.init(key);
66         return mac;
67     }
68 }
69