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