SHA-3可变长度散列与使用BouncyCastle截断Java中的普通散列相同

SHA-3可变长度散列与使用BouncyCastle截断Java中的普通散列相同,java,hash,bouncycastle,sha-3,Java,Hash,Bouncycastle,Sha 3,我需要根据Java中的一些输入数据(如客户电子邮件地址)生成一个30个字符的固定长度散列。经过一些搜索,我发现了SHA-3海绵函数,在这里我可以指定所需的长度。我使用Bouncy CastleSHAKEDigest类实现了以下内容 public class App { public static void main(String[] args) { final String message = "Hello World!"; Syste

我需要根据Java中的一些输入数据(如客户电子邮件地址)生成一个30个字符的固定长度散列。经过一些搜索,我发现了SHA-3海绵函数,在这里我可以指定所需的长度。我使用Bouncy Castle
SHAKEDigest
类实现了以下内容

public class App {
    public static void main(String[] args) {
        final String message = "Hello World!";
        System.out.println(getHash(message, 64));
        System.out.println(getHash(message, 30));
        System.out.println(getHash(message, 20));
    }

    static String getHash(final String message, final int lengthInCharacters) {
        final byte[] messageBytes = message.getBytes(StandardCharsets.UTF_8);

        final SHAKEDigest digest = new SHAKEDigest(128);

        final byte[] hashBytes = new byte[lengthInCharacters / 2];
        digest.update(messageBytes, 0, messageBytes.length);
        digest.doOutput(hashBytes, 0, hashBytes.length);

        return Hex.toHexString(hashBytes);
    }
}
如果我执行它,我会得到以下输出:

aacfe6ebd3737d9f195c837c5281d3f87646ecd7e43864e1a40456e40f264046
aacfe6ebd3737d9f195c837c5281d3
aacfe6ebd3737d9f195c
我认为散列是完全不同的,取决于请求的长度。现在看来,我还可以使用JDK
MessageDigest
生成一个简单的SHA-256散列,并将其截断到所需的长度

我是做错了什么,还是误解了海绵功能的意义


单元测试的完整代码可在以下站点获得:

Nit:SHAKEn实际上是构建在Keccak海绵上的可扩展输出函数(xof),其方式与(固定长度)SHA3散列相同;看

但您似乎误解了一点,那就是底层的海绵使每一个/所有这些都具有确定性——给定的实例(参数化)每次为相同的输入生成相同的输出,并且不受输出大小的影响。因此,SHA3-256(m)不是SHA3-512(m)的前256位,因为它具有不同的参数,而SHAKE128(m,256)是SHAKE128(m,512)的前256位,但不是SHAKE256(m,256)

是的,您可以将任何SHA3散列(或SHA2散列)截断为比其正常大小更小的大小,并得到更小但同样好的加密散列(真实数据的伪随机、不可逆和非聚集),事实上,几十年来人们一直在这样做。但是你不能安全地增加它,你可以用一个类似XOF的震动