SHA-3 第三代安全散列算法(Secure Hash Algorithm 3),之前名为 Keccak(念作/ˈkɛtʃæk/或/kɛtʃɑːk/))算法,设计者宣称在 Intel Core 2 的 CPU 上面,此算法的性能是 12.5cpb(每字节周期数,cycles per byte)。不过,在硬件实做上面,这个算法比起其他算法明显的快上很多。
JDK 自带的 MessageDigest 类为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。信息摘要是安全的单向哈希函数,它接收任意大小的数据,并输出固定长度的哈希值。
实例:使用 JDK 的 MessageDigest 实现 SHA3 消息摘要。
import org.apache.commons.codec.binary.Hex; import java.security.MessageDigest; public class CryptSha3Demo1 { public static void main(String[] args) { CryptSha3Demo1 demo = new CryptSha3Demo1(); byte[] bytes = "hello world".getBytes(); demo.sha3_224(bytes); demo.sha3_256(bytes); demo.sha3_384(bytes); demo.sha3_512(bytes); } private void sha(byte[] bytes, String name) { try { MessageDigest digest = MessageDigest.getInstance(name); System.out.println(name + ":" + Hex.encodeHexString(digest.digest(bytes))); } catch (Exception e) { System.err.println(name + ":" + e.getMessage()); } } private void sha3_224(byte[] bytes) { sha(bytes, "SHA3-224"); } private void sha3_256(byte[] bytes) { sha(bytes, "SHA3-256"); } private void sha3_384(byte[] bytes) { sha(bytes, "SHA3-384"); } private void sha3_512(byte[] bytes) { sha(bytes, "SHA3-512"); } }
输出结果:
SHA3-224:SHA3-224 MessageDigest not available SHA3-256:SHA3-256 MessageDigest not available SHA3-384:SHA3-384 MessageDigest not available SHA3-512:SHA3-512 MessageDigest not available
从上面结果可以看出,JDK 自身并不支持 SHA3 系列的算法。JDK 版本 jdk1.8.0_45,SHA3 至少需要 JDK9+ 版本,运行结果如下:
SHA3-224:dfb7f18c77e928bb56faeb2da27291bd790bc1045cde45f3210bb6c5 SHA3-256:644bcc7e564373040999aac89e7622f3ca71fba1d972fd94a31c3bfbf24e3938 SHA3-384:83bff28dde1b1bf5810071c6643c08e5b05bdb836effd70b403ea8ea0a634dc4997eb1053aa3593f590f9c63630dd90b SHA3-512:840006653e9ac9e95117a15c915caab81662918e925de9e004f774ff82d7079a40d4d27b1b372657c61d46d470304c88c788b3a4527ad074d1dccbee5dbaa99a
Apache Commons Codec 提供的 DigestUtils 类用于简化常见 MessageDigest(消息摘要)任务的操作。此类是不可变的并且是线程安全的。
实例1:使用 digest() 方法进行 SHA3 消息摘要算法计算。
import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.MessageDigestAlgorithms; public class CryptSha3Demo2 { public static void main(String[] args) { byte[] bytes = "hello world".getBytes(); // SHA3-224 digest(bytes, MessageDigestAlgorithms.SHA3_224); // SHA3-256 digest(bytes, MessageDigestAlgorithms.SHA3_256); // SHA3-384 digest(bytes, MessageDigestAlgorithms.SHA3_384); // SHA3-512 digest(bytes, MessageDigestAlgorithms.SHA3_512); } private static void digest(byte[] bytes, String algName) { try { DigestUtils digestUtils = new DigestUtils(algName); System.out.println(algName + ":" + Hex.encodeHexString(digestUtils.digest(bytes))); } catch (Exception e) { System.err.println(algName + ":" + e.getMessage()); } } }
输出结果:
SHA3-224:java.security.NoSuchAlgorithmException: SHA3-224 MessageDigest not available SHA3-256:java.security.NoSuchAlgorithmException: SHA3-256 MessageDigest not available SHA3-384:java.security.NoSuchAlgorithmException: SHA3-384 MessageDigest not available SHA3-512:java.security.NoSuchAlgorithmException: SHA3-512 MessageDigest not available
注意:DigestUtils 内部依然使用 MessageDigest 实现消息摘要,因此 JDK 不支持 SHA3,Apache Commons Codec 同样也不支持;你需要将 JDK 版本调整到 JDK9+,运行结果如下:
SHA3-224:dfb7f18c77e928bb56faeb2da27291bd790bc1045cde45f3210bb6c5 SHA3-256:644bcc7e564373040999aac89e7622f3ca71fba1d972fd94a31c3bfbf24e3938 SHA3-384:83bff28dde1b1bf5810071c6643c08e5b05bdb836effd70b403ea8ea0a634dc4997eb1053aa3593f590f9c63630dd90b SHA3-512:840006653e9ac9e95117a15c915caab81662918e925de9e004f774ff82d7079a40d4d27b1b372657c61d46d470304c88c788b3a4527ad074d1dccbee5dbaa99a
注意:更多关于 DigestUtils 的用法,请参考官网API:
http://commons.apache.org/proper/commons-codec/apidocs/index.html