1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.codec.digest;
18
19 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertFalse;
22 import static org.junit.jupiter.api.Assertions.assertNotNull;
23 import static org.junit.jupiter.api.Assertions.assertThrows;
24 import static org.junit.jupiter.api.Assumptions.assumeTrue;
25
26 import java.io.ByteArrayInputStream;
27 import java.io.IOException;
28 import java.nio.file.Files;
29 import java.nio.file.Path;
30 import java.nio.file.StandardOpenOption;
31 import java.security.NoSuchAlgorithmException;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.List;
35 import java.util.stream.Stream;
36
37 import javax.crypto.Mac;
38
39 import org.apache.commons.lang3.JavaVersion;
40 import org.apache.commons.lang3.SystemUtils;
41 import org.junit.jupiter.api.AfterEach;
42 import org.junit.jupiter.api.BeforeAll;
43 import org.junit.jupiter.api.BeforeEach;
44 import org.junit.jupiter.api.io.TempDir;
45 import org.junit.jupiter.params.ParameterizedTest;
46 import org.junit.jupiter.params.provider.Arguments;
47 import org.junit.jupiter.params.provider.MethodSource;
48
49
50
51
52 class HmacAlgorithmsTest {
53
54 static final String STANDARD_KEY_STRING = "key";
55
56 static final byte[] STANDARD_KEY_BYTES = STANDARD_KEY_STRING.getBytes();
57
58 static final byte[] STANDARD_MD5_RESULT_BYTES = { -128, 7, 7, 19, 70, 62, 119, 73, -71, 12, 45, -62, 73, 17, -30, 117 };
59
60 static final String STANDARD_MD5_RESULT_STRING = "80070713463e7749b90c2dc24911e275";
61
62 static final String STANDARD_PHRASE_STRING = "The quick brown fox jumps over the lazy dog";
63
64 static final byte[] STANDARD_PHRASE_BYTES = STANDARD_PHRASE_STRING.getBytes();
65
66 static final byte[] STANDARD_SHA1_RESULT_BYTES = { -34, 124, -101, -123, -72, -73, -118, -90, -68, -118, 122, 54, -9, 10, -112, 112, 28, -99, -76, -39 };
67
68 static final String STANDARD_SHA1_RESULT_STRING = "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9";
69
70 static final byte[] STANDARD_SHA224_RESULT_BYTES = { -120, -1, -117, 84, 103, 93, 57, -72, -9, 35, 34, -26, 95, -7, 69, -59, 45, -106, 55, -103, -120, -83,
71 -94, 86, 57, 116, 126, 105 };
72
73 static final String STANDARD_SHA224_RESULT_STRING = "88ff8b54675d39b8f72322e65ff945c52d96379988ada25639747e69";
74
75 static final byte[] STANDARD_SHA256_RESULT_BYTES = { -9, -68, -125, -12, 48, 83, -124, 36, -79, 50, -104, -26, -86, 111, -79, 67, -17, 77, 89, -95, 73, 70,
76 23, 89, -105, 71, -99, -68, 45, 26, 60, -40 };
77
78 static final String STANDARD_SHA256_RESULT_STRING = "f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8";
79
80 static final byte[] STANDARD_SHA384_RESULT_BYTES = { -41, -12, 114, 126, 44, 11, 57, -82, 15, 30, 64, -52, -106, -10, 2, 66, -43, -73, -128, 24, 65, -50,
81 -90, -4, 89, 44, 93, 62, 26, -27, 7, 0, 88, 42, -106, -49, 53, -31, -27, 84, -103, 95, -28, -32, 51, -127, -62, 55 };
82
83 static final String STANDARD_SHA384_RESULT_STRING = "D7F4727E2C0B39AE0F1E40CC96F60242D5B7801841CEA6FC592C5D3E1AE50700582A96CF35E1E554995FE4E03381C237"
84 .toLowerCase();
85
86 static final byte[] STANDARD_SHA512_RESULT_BYTES = { -76, 42, -16, -112, 87, -70, -63, -30, -44, 23, 8, -28, -118, -112, 46, 9, -75, -1, 127, 18, -85, 66,
87 -118, 79, -24, 102, 83, -57, 61, -46, 72, -5, -126, -7, 72, -91, 73, -9, -73, -111, -91, -76, 25, 21, -18, 77, 30, -61, -109, 83, 87, -28, -30, 49,
88 114, 80, -48, 55, 42, -6, 46, -66, -21, 58 };
89
90 static final String STANDARD_SHA512_RESULT_STRING = "B42AF09057BAC1E2D41708E48A902E09B5FF7F12AB428A4FE86653C73DD248FB82F948A549F7B791A5B41915EE4D1EC3935357E4E2317250D0372AFA2EBEEB3A"
91 .toLowerCase();
92
93 private static final byte[] EMPTY_BYTE_ARRAY = {};
94
95 @TempDir
96 static Path TempDir;
97
98 static Path TempFile;
99
100
101 public static Stream<Arguments> data() {
102 List<Arguments> list = Arrays.asList(
103
104 Arguments.of(HmacAlgorithms.HMAC_MD5, STANDARD_MD5_RESULT_BYTES, STANDARD_MD5_RESULT_STRING),
105 Arguments.of(HmacAlgorithms.HMAC_SHA_1, STANDARD_SHA1_RESULT_BYTES, STANDARD_SHA1_RESULT_STRING),
106 Arguments.of(HmacAlgorithms.HMAC_SHA_256, STANDARD_SHA256_RESULT_BYTES, STANDARD_SHA256_RESULT_STRING),
107 Arguments.of(HmacAlgorithms.HMAC_SHA_384, STANDARD_SHA384_RESULT_BYTES, STANDARD_SHA384_RESULT_STRING),
108 Arguments.of(HmacAlgorithms.HMAC_SHA_512, STANDARD_SHA512_RESULT_BYTES, STANDARD_SHA512_RESULT_STRING));
109
110 if (SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_1_8)) {
111 list = new ArrayList<>(list);
112 list.add(Arguments.of(HmacAlgorithms.HMAC_SHA_224, STANDARD_SHA224_RESULT_BYTES, STANDARD_SHA224_RESULT_STRING));
113 }
114 return list.stream();
115 }
116
117 @BeforeAll
118 public static void init() throws IOException {
119 TempFile = Files.createFile(TempDir.resolve(HmacAlgorithmsTest.class.getSimpleName()));
120 Files.write(TempFile, STANDARD_PHRASE_BYTES, StandardOpenOption.CREATE);
121 }
122
123 private DigestUtilsTest digestUtilsTest;
124 @BeforeEach
125 public void setUp() throws Exception {
126 digestUtilsTest = new DigestUtilsTest();
127 digestUtilsTest.setUp();
128 }
129
130 @AfterEach
131 public void tearDown() throws Exception {
132 digestUtilsTest.tearDown();
133 digestUtilsTest = null;
134 }
135
136 @ParameterizedTest
137 @MethodSource("data")
138 void testAlgorithm(final HmacAlgorithms hmacAlgorithm, final byte[] standardResultBytes, final String standardResultString)
139 throws NoSuchAlgorithmException {
140 assumeTrue(HmacUtils.isAvailable(hmacAlgorithm));
141 final String algorithm = hmacAlgorithm.getName();
142 assertNotNull(algorithm);
143 assertFalse(algorithm.isEmpty());
144 assumeTrue(HmacUtils.isAvailable(hmacAlgorithm));
145 Mac.getInstance(algorithm);
146 }
147
148 @ParameterizedTest
149 @MethodSource("data")
150 void testGetHmacEmptyKey(final HmacAlgorithms hmacAlgorithm, final byte[] standardResultBytes, final String standardResultString) {
151 assumeTrue(HmacUtils.isAvailable(hmacAlgorithm));
152 assertThrows(IllegalArgumentException.class, () -> HmacUtils.getInitializedMac(hmacAlgorithm, EMPTY_BYTE_ARRAY));
153 }
154
155 @ParameterizedTest
156 @MethodSource("data")
157 void testGetHmacNullKey(final HmacAlgorithms hmacAlgorithm, final byte[] standardResultBytes, final String standardResultString) {
158 assumeTrue(HmacUtils.isAvailable(hmacAlgorithm));
159 assertThrows(IllegalArgumentException.class, () -> HmacUtils.getInitializedMac(hmacAlgorithm, null));
160 }
161
162 @ParameterizedTest
163 @MethodSource("data")
164 void testHmacFailByteArray(final HmacAlgorithms hmacAlgorithm, final byte[] standardResultBytes, final String standardResultString) {
165 assumeTrue(HmacUtils.isAvailable(hmacAlgorithm));
166 assertThrows(IllegalArgumentException.class, () -> new HmacUtils(hmacAlgorithm, (byte[]) null).hmac(STANDARD_PHRASE_BYTES));
167 }
168
169 @ParameterizedTest
170 @MethodSource("data")
171 void testHmacFailInputStream(final HmacAlgorithms hmacAlgorithm, final byte[] standardResultBytes, final String standardResultString) {
172 assumeTrue(HmacUtils.isAvailable(hmacAlgorithm));
173 assertThrows(IllegalArgumentException.class, () -> new HmacUtils(hmacAlgorithm, (byte[]) null).hmac(new ByteArrayInputStream(STANDARD_PHRASE_BYTES)));
174 }
175
176 @ParameterizedTest
177 @MethodSource("data")
178 void testHmacFailString(final HmacAlgorithms hmacAlgorithm, final byte[] standardResultBytes, final String standardResultString) {
179 assumeTrue(HmacUtils.isAvailable(hmacAlgorithm));
180 assertThrows(IllegalArgumentException.class, () -> new HmacUtils(hmacAlgorithm, (String) null).hmac(STANDARD_PHRASE_STRING));
181 }
182
183 @ParameterizedTest
184 @MethodSource("data")
185 void testHmacHexFailByteArray(final HmacAlgorithms hmacAlgorithm, final byte[] standardResultBytes, final String standardResultString) {
186 assumeTrue(HmacUtils.isAvailable(hmacAlgorithm));
187 assertThrows(IllegalArgumentException.class, () -> new HmacUtils(hmacAlgorithm, (byte[]) null).hmac(STANDARD_PHRASE_BYTES));
188 }
189
190 @ParameterizedTest
191 @MethodSource("data")
192 void testHmacHexFailInputStream(final HmacAlgorithms hmacAlgorithm, final byte[] standardResultBytes, final String standardResultString) {
193 assumeTrue(HmacUtils.isAvailable(hmacAlgorithm));
194 assertThrows(IllegalArgumentException.class, () -> new HmacUtils(hmacAlgorithm, (byte[]) null).hmac(new ByteArrayInputStream(STANDARD_PHRASE_BYTES)));
195 }
196
197 @ParameterizedTest
198 @MethodSource("data")
199 void testHmacHexFailString(final HmacAlgorithms hmacAlgorithm, final byte[] standardResultBytes, final String standardResultString) {
200 assumeTrue(HmacUtils.isAvailable(hmacAlgorithm));
201 assertThrows(IllegalArgumentException.class, () -> new HmacUtils(hmacAlgorithm, (String) null).hmac(STANDARD_PHRASE_STRING));
202 }
203
204 @ParameterizedTest
205 @MethodSource("data")
206 void testInitializedMac(final HmacAlgorithms hmacAlgorithm, final byte[] standardResultBytes, final String standardResultString) {
207 assumeTrue(HmacUtils.isAvailable(hmacAlgorithm));
208 final Mac mac = HmacUtils.getInitializedMac(hmacAlgorithm, STANDARD_KEY_BYTES);
209 final Mac mac2 = HmacUtils.getInitializedMac(hmacAlgorithm.getName(), STANDARD_KEY_BYTES);
210 assertArrayEquals(standardResultBytes, HmacUtils.updateHmac(mac, STANDARD_PHRASE_STRING).doFinal());
211 assertArrayEquals(standardResultBytes, HmacUtils.updateHmac(mac2, STANDARD_PHRASE_STRING).doFinal());
212 }
213
214 @ParameterizedTest
215 @MethodSource("data")
216 void testMacByteArray(final HmacAlgorithms hmacAlgorithm, final byte[] standardResultBytes, final String standardResultString) {
217 assumeTrue(HmacUtils.isAvailable(hmacAlgorithm));
218 assertArrayEquals(standardResultBytes, new HmacUtils(hmacAlgorithm, STANDARD_KEY_BYTES).hmac(STANDARD_PHRASE_BYTES));
219 }
220
221 @ParameterizedTest
222 @MethodSource("data")
223 void testMacHexByteArray(final HmacAlgorithms hmacAlgorithm, final byte[] standardResultBytes, final String standardResultString) {
224 assumeTrue(HmacUtils.isAvailable(hmacAlgorithm));
225 assertEquals(standardResultString, new HmacUtils(hmacAlgorithm, STANDARD_KEY_BYTES).hmacHex(STANDARD_PHRASE_BYTES));
226 }
227
228 @ParameterizedTest
229 @MethodSource("data")
230 void testMacHexFile(final HmacAlgorithms hmacAlgorithm, final byte[] standardResultBytes, final String standardResultString)
231 throws IOException {
232 assumeTrue(HmacUtils.isAvailable(hmacAlgorithm));
233 assertEquals(standardResultString, new HmacUtils(hmacAlgorithm, STANDARD_KEY_BYTES).hmacHex(TempFile.toFile()));
234 }
235
236 @ParameterizedTest
237 @MethodSource("data")
238 void testMacHexInputStream(final HmacAlgorithms hmacAlgorithm, final byte[] standardResultBytes, final String standardResultString)
239 throws IOException {
240 assumeTrue(HmacUtils.isAvailable(hmacAlgorithm));
241 assertEquals(standardResultString, new HmacUtils(hmacAlgorithm, STANDARD_KEY_BYTES).hmacHex(new ByteArrayInputStream(STANDARD_PHRASE_BYTES)));
242 }
243
244 @ParameterizedTest
245 @MethodSource("data")
246 void testMacHexPath(final HmacAlgorithms hmacAlgorithm, final byte[] standardResultBytes, final String standardResultString)
247 throws IOException {
248 assumeTrue(HmacUtils.isAvailable(hmacAlgorithm));
249 assertEquals(standardResultString, new HmacUtils(hmacAlgorithm, STANDARD_KEY_BYTES).hmacHex(TempFile));
250 }
251
252 @ParameterizedTest
253 @MethodSource("data")
254 void testMacHexString(final HmacAlgorithms hmacAlgorithm, final byte[] standardResultBytes, final String standardResultString) {
255 assumeTrue(HmacUtils.isAvailable(hmacAlgorithm));
256 assertEquals(standardResultString, new HmacUtils(hmacAlgorithm, STANDARD_KEY_BYTES).hmacHex(STANDARD_PHRASE_STRING));
257 }
258
259 @ParameterizedTest
260 @MethodSource("data")
261 void testMacInputStream(final HmacAlgorithms hmacAlgorithm, final byte[] standardResultBytes, final String standardResultString) throws IOException {
262 assumeTrue(HmacUtils.isAvailable(hmacAlgorithm));
263 assertArrayEquals(standardResultBytes, new HmacUtils(hmacAlgorithm, STANDARD_KEY_BYTES).hmac(new ByteArrayInputStream(STANDARD_PHRASE_BYTES)));
264 }
265
266 @ParameterizedTest
267 @MethodSource("data")
268 void testMacString(final HmacAlgorithms hmacAlgorithm, final byte[] standardResultBytes, final String standardResultString) {
269 assumeTrue(HmacUtils.isAvailable(hmacAlgorithm));
270 assertArrayEquals(standardResultBytes, new HmacUtils(hmacAlgorithm, STANDARD_KEY_BYTES).hmac(STANDARD_PHRASE_STRING));
271 }
272
273 }