1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.security.oauth.common.signature;
18
19 import org.apache.commons.codec.binary.Base64;
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22
23 import javax.crypto.Mac;
24 import javax.crypto.SecretKey;
25 import java.io.UnsupportedEncodingException;
26 import java.security.InvalidKeyException;
27 import java.security.NoSuchAlgorithmException;
28
29
30
31
32
33
34 public class HMAC_SHA1SignatureMethod implements OAuthSignatureMethod {
35
36 private static final Log LOG = LogFactory.getLog(HMAC_SHA1SignatureMethod.class);
37
38
39
40
41 public static final String SIGNATURE_NAME = "HMAC-SHA1";
42
43
44
45
46 public static final String MAC_NAME = "HmacSHA1";
47
48 private final SecretKey key;
49
50
51
52
53
54
55 public HMAC_SHA1SignatureMethod(SecretKey key) {
56 this.key = key;
57 }
58
59
60
61
62
63
64 public String getName() {
65 return SIGNATURE_NAME;
66 }
67
68
69
70
71
72
73
74
75 public String sign(String signatureBaseString) {
76 try {
77 Mac mac = Mac.getInstance(MAC_NAME);
78 mac.init(key);
79 byte[] text = signatureBaseString.getBytes("UTF-8");
80 byte[] signatureBytes = mac.doFinal(text);
81 signatureBytes = Base64.encodeBase64(signatureBytes);
82 String signature = new String(signatureBytes, "UTF-8");
83
84 if (LOG.isDebugEnabled()) {
85 LOG.debug("signature base: " + signatureBaseString);
86 LOG.debug("signature: " + signature);
87 }
88
89 return signature;
90 }
91 catch (NoSuchAlgorithmException e) {
92 throw new IllegalStateException(e);
93 }
94 catch (InvalidKeyException e) {
95 throw new IllegalStateException(e);
96 }
97 catch (UnsupportedEncodingException e) {
98 throw new RuntimeException(e);
99 }
100 }
101
102
103
104
105
106
107
108
109
110
111 public void verify(String signatureBaseString, String signature) throws InvalidSignatureException {
112 try {
113 if (LOG.isDebugEnabled()) {
114 LOG.debug("signature base: " + signatureBaseString);
115 LOG.debug("signature: " + signature);
116 }
117
118 byte[] signatureBytes = Base64.decodeBase64(signature.getBytes("UTF-8"));
119
120 Mac mac = Mac.getInstance(MAC_NAME);
121 mac.init(key);
122 byte[] text = signatureBaseString.getBytes("UTF-8");
123 byte[] calculatedBytes = mac.doFinal(text);
124 if (!safeArrayEquals(calculatedBytes, signatureBytes)) {
125 throw new InvalidSignatureException("Invalid signature for signature method " + getName());
126 }
127 }
128 catch (NoSuchAlgorithmException e) {
129 throw new IllegalStateException(e);
130 }
131 catch (InvalidKeyException e) {
132 throw new IllegalStateException(e);
133 }
134 catch (UnsupportedEncodingException e) {
135 throw new RuntimeException(e);
136 }
137 }
138
139 boolean safeArrayEquals(byte[] a1, byte[] a2) {
140 if (a1 == null || a2 == null) {
141 return (a1 == a2);
142 }
143
144 if (a1.length != a2.length) {
145 return false;
146 }
147
148 byte result = 0;
149 for (int i = 0; i < a1.length; i++) {
150 result |= a1[i] ^ a2[i];
151 }
152
153 return (result == 0);
154 }
155
156
157
158
159
160
161 public SecretKey getSecretKey() {
162 return key;
163 }
164 }