Skip to content

Commit 01b6911

Browse files
committed
[CODEC-274] Add SHA-512/224 and SHA-512/256 to DigestUtils for Java 9
and up.
1 parent b436b6d commit 01b6911

4 files changed

Lines changed: 251 additions & 5 deletions

File tree

src/changes/changes.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ The <action> type attribute can be add,update,fix,remove.
5353
<action issue="CODEC-269" dev="aherbert" type="fix">Allow repeat calls to MurmurHash3.IncrementalHash32.end() to generate the same value.</action>
5454
<action issue="CODEC-272" dev="ggregory" type="add" due-to="Behrang, Alex Herbert, Gary Gregory">Add RandomAccessFile digest methods #31.</action>
5555
<action issue="CODEC-273" dev="ggregory" type="add" due-to="Gary Gregory">Add Path APIs to org.apache.commons.codec.digest.DigestUtils similar to File APIs.</action>
56+
<action issue="CODEC-274" dev="ggregory" type="add" due-to="Gary Gregory">Add SHA-512/224 and SHA-512/256 to DigestUtils for Java 9 and up.</action>
5657
</release>
5758

5859
<release version="1.13" date="2019-07-20" description="Feature and fix release.">

src/main/java/org/apache/commons/codec/digest/DigestUtils.java

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,30 @@ public static MessageDigest getSha512Digest() {
333333
return getDigest(MessageDigestAlgorithms.SHA_512);
334334
}
335335

336+
/**
337+
* Returns an SHA-512/224 digest.
338+
*
339+
* @return An SHA-512/224 digest instance.
340+
* @throws IllegalArgumentException
341+
* when a {@link NoSuchAlgorithmException} is caught.
342+
* @see MessageDigestAlgorithms#SHA_512_224
343+
*/
344+
public static MessageDigest getSha512_224Digest() {
345+
return getDigest(MessageDigestAlgorithms.SHA_512_224);
346+
}
347+
348+
/**
349+
* Returns an SHA-512/256 digest.
350+
*
351+
* @return An SHA-512/256 digest instance.
352+
* @throws IllegalArgumentException
353+
* when a {@link NoSuchAlgorithmException} is caught.
354+
* @see MessageDigestAlgorithms#SHA_512_224
355+
*/
356+
public static MessageDigest getSha512_256Digest() {
357+
return getDigest(MessageDigestAlgorithms.SHA_512_256);
358+
}
359+
336360
/**
337361
* Returns an SHA-1 digest.
338362
*
@@ -1089,6 +1113,30 @@ public static byte[] sha512(final byte[] data) {
10891113
return getSha512Digest().digest(data);
10901114
}
10911115

1116+
/**
1117+
* Calculates the SHA-512/224 digest and returns the value as a {@code byte[]}.
1118+
*
1119+
* @param data
1120+
* Data to digest
1121+
* @return SHA-512/224 digest
1122+
* @since 1.14
1123+
*/
1124+
public static byte[] sha512_224(final byte[] data) {
1125+
return getSha512_224Digest().digest(data);
1126+
}
1127+
1128+
/**
1129+
* Calculates the SHA-512/256 digest and returns the value as a {@code byte[]}.
1130+
*
1131+
* @param data
1132+
* Data to digest
1133+
* @return SHA-512/256 digest
1134+
* @since 1.14
1135+
*/
1136+
public static byte[] sha512_256(final byte[] data) {
1137+
return getSha512_256Digest().digest(data);
1138+
}
1139+
10921140
/**
10931141
* Calculates the SHA-512 digest and returns the value as a {@code byte[]}.
10941142
*
@@ -1103,6 +1151,34 @@ public static byte[] sha512(final InputStream data) throws IOException {
11031151
return digest(getSha512Digest(), data);
11041152
}
11051153

1154+
/**
1155+
* Calculates the SHA-512/224 digest and returns the value as a {@code byte[]}.
1156+
*
1157+
* @param data
1158+
* Data to digest
1159+
* @return SHA-512/224 digest
1160+
* @throws IOException
1161+
* On error reading from the stream
1162+
* @since 1.14
1163+
*/
1164+
public static byte[] sha512_224(final InputStream data) throws IOException {
1165+
return digest(getSha512_224Digest(), data);
1166+
}
1167+
1168+
/**
1169+
* Calculates the SHA-512/256 digest and returns the value as a {@code byte[]}.
1170+
*
1171+
* @param data
1172+
* Data to digest
1173+
* @return SHA-512/256 digest
1174+
* @throws IOException
1175+
* On error reading from the stream
1176+
* @since 1.14
1177+
*/
1178+
public static byte[] sha512_256(final InputStream data) throws IOException {
1179+
return digest(getSha512_256Digest(), data);
1180+
}
1181+
11061182
/**
11071183
* Calculates the SHA-512 digest and returns the value as a {@code byte[]}.
11081184
*
@@ -1115,6 +1191,30 @@ public static byte[] sha512(final String data) {
11151191
return sha512(StringUtils.getBytesUtf8(data));
11161192
}
11171193

1194+
/**
1195+
* Calculates the SHA-512/224 digest and returns the value as a {@code byte[]}.
1196+
*
1197+
* @param data
1198+
* Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
1199+
* @return SHA-512/224 digest
1200+
* @since 1.14
1201+
*/
1202+
public static byte[] sha512_224(final String data) {
1203+
return sha512_224(StringUtils.getBytesUtf8(data));
1204+
}
1205+
1206+
/**
1207+
* Calculates the SHA-512/256 digest and returns the value as a {@code byte[]}.
1208+
*
1209+
* @param data
1210+
* Data to digest; converted to bytes using {@link StringUtils#getBytesUtf8(String)}
1211+
* @return SHA-512/224 digest
1212+
* @since 1.14
1213+
*/
1214+
public static byte[] sha512_256(final String data) {
1215+
return sha512_256(StringUtils.getBytesUtf8(data));
1216+
}
1217+
11181218
/**
11191219
* Calculates the SHA-512 digest and returns the value as a hex string.
11201220
*
@@ -1127,6 +1227,58 @@ public static String sha512Hex(final byte[] data) {
11271227
return Hex.encodeHexString(sha512(data));
11281228
}
11291229

1230+
/**
1231+
* Calculates the SHA-512/224 digest and returns the value as a hex string.
1232+
*
1233+
* @param data
1234+
* Data to digest
1235+
* @return SHA-512/224 digest as a hex string
1236+
* @since 1.14
1237+
*/
1238+
public static String sha512_224Hex(final byte[] data) {
1239+
return Hex.encodeHexString(sha512_224(data));
1240+
}
1241+
1242+
/**
1243+
* Calculates the SHA-512/256 digest and returns the value as a hex string.
1244+
*
1245+
* @param data
1246+
* Data to digest
1247+
* @return SHA-512/256 digest as a hex string
1248+
* @since 1.14
1249+
*/
1250+
public static String sha512_256Hex(final byte[] data) {
1251+
return Hex.encodeHexString(sha512_256(data));
1252+
}
1253+
1254+
/**
1255+
* Calculates the SHA-512/224 digest and returns the value as a hex string.
1256+
*
1257+
* @param data
1258+
* Data to digest
1259+
* @return SHA-512/224 digest as a hex string
1260+
* @throws IOException
1261+
* On error reading from the stream
1262+
* @since 1.14
1263+
*/
1264+
public static String sha512_224Hex(final InputStream data) throws IOException {
1265+
return Hex.encodeHexString(sha512_224(data));
1266+
}
1267+
1268+
/**
1269+
* Calculates the SHA-512/256 digest and returns the value as a hex string.
1270+
*
1271+
* @param data
1272+
* Data to digest
1273+
* @return SHA-512/256 digest as a hex string
1274+
* @throws IOException
1275+
* On error reading from the stream
1276+
* @since 1.14
1277+
*/
1278+
public static String sha512_256Hex(final InputStream data) throws IOException {
1279+
return Hex.encodeHexString(sha512_256(data));
1280+
}
1281+
11301282
/**
11311283
* Calculates the SHA-512 digest and returns the value as a hex string.
11321284
*
@@ -1153,6 +1305,30 @@ public static String sha512Hex(final String data) {
11531305
return Hex.encodeHexString(sha512(data));
11541306
}
11551307

1308+
/**
1309+
* Calculates the SHA-512/224 digest and returns the value as a hex string.
1310+
*
1311+
* @param data
1312+
* Data to digest
1313+
* @return SHA-512/224 digest as a hex string
1314+
* @since 1.14
1315+
*/
1316+
public static String sha512_224Hex(final String data) {
1317+
return Hex.encodeHexString(sha512_224(data));
1318+
}
1319+
1320+
/**
1321+
* Calculates the SHA-512/256 digest and returns the value as a hex string.
1322+
*
1323+
* @param data
1324+
* Data to digest
1325+
* @return SHA-512/256 digest as a hex string
1326+
* @since 1.14
1327+
*/
1328+
public static String sha512_256Hex(final String data) {
1329+
return Hex.encodeHexString(sha512_256(data));
1330+
}
1331+
11561332
/**
11571333
* Calculates the SHA-1 digest and returns the value as a hex string.
11581334
*

src/main/java/org/apache/commons/codec/digest/MessageDigestAlgorithms.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,30 @@ public class MessageDigestAlgorithms {
9393
*/
9494
public static final String SHA_512 = "SHA-512";
9595

96+
/**
97+
* The SHA-512 hash algorithm defined in the FIPS PUB 180-4.
98+
* <p>
99+
* Included starting in Oracle Java 9.
100+
* </p>
101+
*
102+
* @since 1.14
103+
*/
104+
public static final String SHA_512_224 = "SHA-512/224";
105+
106+
/**
107+
* The SHA-512 hash algorithm defined in the FIPS PUB 180-4.
108+
* <p>
109+
* Included starting in Oracle Java 9.
110+
* </p>
111+
*
112+
* @since 1.14
113+
*/
114+
public static final String SHA_512_256 = "SHA-512/256";
115+
96116
/**
97117
* The SHA3-224 hash algorithm defined in the FIPS PUB 202.
98118
* <p>
99-
* Included starting in Oracle Java 9 GA.
119+
* Included starting in Oracle Java 9.
100120
* </p>
101121
*
102122
* @since 1.11
@@ -106,7 +126,7 @@ public class MessageDigestAlgorithms {
106126
/**
107127
* The SHA3-256 hash algorithm defined in the FIPS PUB 202.
108128
* <p>
109-
* Included starting in Oracle Java 9 GA.
129+
* Included starting in Oracle Java 9.
110130
* </p>
111131
*
112132
* @since 1.11
@@ -116,7 +136,7 @@ public class MessageDigestAlgorithms {
116136
/**
117137
* The SHA3-384 hash algorithm defined in the FIPS PUB 202.
118138
* <p>
119-
* Included starting in Oracle Java 9 GA.
139+
* Included starting in Oracle Java 9.
120140
* </p>
121141
*
122142
* @since 1.11
@@ -126,7 +146,7 @@ public class MessageDigestAlgorithms {
126146
/**
127147
* The SHA3-512 hash algorithm defined in the FIPS PUB 202.
128148
* <p>
129-
* Included starting in Oracle Java 9 GA.
149+
* Included starting in Oracle Java 9.
130150
* </p>
131151
*
132152
* @since 1.11
@@ -142,7 +162,7 @@ public class MessageDigestAlgorithms {
142162
public static String[] values() {
143163
// N.B. do not use a constant array here as that can be changed externally by accident or design
144164
return new String[] {
145-
MD2, MD5, SHA_1, SHA_224, SHA_256, SHA_384, SHA_512, SHA3_224, SHA3_256, SHA3_384, SHA3_512
165+
MD2, MD5, SHA_1, SHA_224, SHA_256, SHA_384, SHA_512, SHA_512_224, SHA_512_256, SHA3_224, SHA3_256, SHA3_384, SHA3_512
146166
};
147167
}
148168

src/test/java/org/apache/commons/codec/digest/DigestUtilsTest.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import static org.apache.commons.codec.binary.StringUtils.getBytesUtf8;
2121
import static org.junit.Assert.assertEquals;
22+
import static org.junit.Assert.assertArrayEquals;
2223

2324
import java.io.ByteArrayInputStream;
2425
import java.io.File;
@@ -29,6 +30,7 @@
2930
import java.nio.file.Path;
3031
import java.nio.file.Paths;
3132
import java.security.MessageDigest;
33+
import java.util.Locale;
3234
import java.util.Random;
3335

3436
import org.apache.commons.codec.binary.Hex;
@@ -356,6 +358,53 @@ public void testSha512() {
356358
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"));
357359
}
358360

361+
@Test
362+
public void testSha512_224() throws Exception {
363+
assumeJava9();
364+
// Examples from
365+
// https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA512_224.pdf
366+
final String stringInput = "abc";
367+
final byte[] bytesInput = getBytesUtf8(stringInput);
368+
final String resultString = "4634270F707B6A54DAAE7530460842E20E37ED265CEEE9A43E8924AA".toLowerCase(Locale.ROOT);
369+
final byte[] resultBytes = Hex.decodeHex(resultString);
370+
//
371+
assertArrayEquals(resultBytes, DigestUtils.sha512_224(bytesInput));
372+
assertArrayEquals(resultBytes, DigestUtils.sha512_224(new ByteArrayInputStream(bytesInput)));
373+
assertArrayEquals(resultBytes, DigestUtils.sha512_224(stringInput));
374+
//
375+
assertEquals(resultString, DigestUtils.sha512_224Hex(bytesInput));
376+
assertEquals(resultString, DigestUtils.sha512_224Hex(new ByteArrayInputStream(bytesInput)));
377+
assertEquals(resultString, DigestUtils.sha512_224Hex(stringInput));
378+
// Example 2
379+
assertEquals("23FEC5BB94D60B23308192640B0C453335D664734FE40E7268674AF9".toLowerCase(Locale.ROOT),
380+
DigestUtils.sha512_224Hex(
381+
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"));
382+
}
383+
384+
@Test
385+
public void testSha512_256() throws Exception {
386+
assumeJava9();
387+
// Examples from
388+
// https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA512_256.pdf
389+
final String stringInput = "abc";
390+
final byte[] bytesInput = getBytesUtf8(stringInput);
391+
final String resultString = "53048E2681941EF99B2E29B76B4C7DABE4C2D0C634FC6D46E0E2F13107E7AF23"
392+
.toLowerCase(Locale.ROOT);
393+
final byte[] resultBytes = Hex.decodeHex(resultString);
394+
//
395+
assertArrayEquals(resultBytes, DigestUtils.sha512_256(bytesInput));
396+
assertArrayEquals(resultBytes, DigestUtils.sha512_256(new ByteArrayInputStream(bytesInput)));
397+
assertArrayEquals(resultBytes, DigestUtils.sha512_256(stringInput));
398+
//
399+
assertEquals(resultString, DigestUtils.sha512_256Hex(bytesInput));
400+
assertEquals(resultString, DigestUtils.sha512_256Hex(new ByteArrayInputStream(bytesInput)));
401+
assertEquals(resultString, DigestUtils.sha512_256Hex(stringInput));
402+
// Example 2
403+
assertEquals("3928E184FB8690F840DA3988121D31BE65CB9D3EF83EE6146FEAC861E19B563A".toLowerCase(Locale.ROOT),
404+
DigestUtils.sha512_256Hex(
405+
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"));
406+
}
407+
359408
@Test
360409
public void testSha3_224() {
361410
assumeJava9();

0 commit comments

Comments
 (0)