java SHA3算法实现

2018/04/19 note 共 2247 字,约 7 分钟

SHA3算法即为Keccak算法

贴一张维基百科的图
sha

BouncyCastle中的实现

BouncyCastle中实现了SHA3算法家族的所有实现,对应实现在org.bouncycastle.crypto.digests.SHA3Digestorg.bouncycastle.crypto.digests.SHAKEDigest中,(但是现在还没有搞清楚SHAKE算法的调用方法,维基百科上写的SHAKE算法输出长度不固定,所以调用的示例都是SHAKE128("", 256) 7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26这种,貌似传了一个最大长度?),示例代码:

// SHA3家族:SHA3-224,SHA3-256,SHA3-384,SHA3-512,SHAKE128,SHAKE256  
private static final Digest _SHA3_224Digest = new SHA3Digest(224);  
private static final Digest _SHA3_256Digest = new SHA3Digest(256);  
private static final Digest _SHA3_384Digest = new SHA3Digest(384);  
private static final Digest _SHA3_512Digest = new SHA3Digest(512);  
// private static final Digest _SHA3_SHAKE128Digest = new SHAKEDigest(128);  
// private static final Digest _SHA3_SHAKE256Digest = new SHAKEDigest(256);  
  
private static byte[] doDigest(Digest digest, byte[] src) {  
    digest.reset();  
    byte[] result = new byte[digest.getDigestSize()];  
    digest.update(src, 0, src.length);  
    digest.doFinal(result, 0);  
    return result;  
}  
  
public static byte[] sha3_224(byte[] src) {  
    return doDigest(_SHA3_224Digest, src);  
}  
  
public static byte[] sha3_256(byte[] src) {  
    return doDigest(_SHA3_256Digest, src);  
}  
  
public static byte[] sha3_384(byte[] src) {  
    return doDigest(_SHA3_384Digest, src);  
}  
  
public static byte[] sha3_512(byte[] src) {  
    return doDigest(_SHA3_512Digest, src);  
}  

以太坊中的实现(Keccak256,和sha3哈希结果不同)

在以太坊的java实现代码中,有sha3算法的实现:https://github.com/ethereum/ethereumj/blob/develop/ethereumj-core/src/main/java/org/ethereum/crypto/cryptohash/Keccak256.java

注意:Keccak256算法和sha3算法略有区别,结果是不一样的。以太坊使用Keccak256算法来进行HASH运算,而不是sha3算法。

在代码中,作者将算法实现加入到SpongyCastle的算法集中:

// 代码位于:org.ethereum.crypto.jce.SpongyCastleProvider  
private static final Provider INSTANCE;  
static{  
    Provider p = Security.getProvider("SC");  
      
    INSTANCE = (p != null) ? p : new BouncyCastleProvider();  
          
    INSTANCE.put("MessageDigest.ETH-KECCAK-256", "org.ethereum.crypto.cryptohash.Keccak256");  
    INSTANCE.put("MessageDigest.ETH-KECCAK-512", "org.ethereum.crypto.cryptohash.Keccak512");  
}  

而后调用sha3算法时,只需要在Digest算法中填写”ETH-KECCAK-256”串即可调用sha3算法:

// 代码位于:org.ethereum.crypto.HashUtil,为了方便查看,将方法中的变量直接替换为字符串  
public static byte[] sha3(byte[] input) {  
    MessageDigest digest;  
    try {  
        digest = MessageDigest.getInstance("ETH-KECCAK-256", SC);  
        digest.update(input);  
        return digest.digest();  
    } catch (NoSuchAlgorithmException e) {  
        LOG.error("Can't find such algorithm", e);  
        throw new RuntimeException(e);  
    }  
  
}  

文档信息

Search

    Table of Contents