微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SHA-3 可变长度散列与使用 BouncyCastle

如何解决SHA-3 可变长度散列与使用 BouncyCastle

我需要基于 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,messageBytes.length);
        digest.doOutput(hashBytes,hashBytes.length);

        return Hex.toHexString(hashBytes);
    }
}

如果我执行它,我会得到以下输出

aacfe6ebd3737d9f195c837c5281d3f87646ecd7e43864e1a40456e40f264046
aacfe6ebd3737d9f195c837c5281d3
aacfe6ebd3737d9f195c

我预计哈希值会根据请求的长度完全不同。现在看来,我还可以使用 JDK MessageDigest 生成一个简单的 SHA-256 哈希值,然后将其截断为所需的长度。

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

带有单元测试的完整代码位于:https://github.com/steinsag/java-dynamic-hash

解决方法

Nit:SHAKEn 实际上是可扩展输出函数 (XOF),构建 Keccak 海绵,其方式与(固定长度)SHA3 哈希相同;见https://en.wikipedia.org/wiki/SHA-3#Instances

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

是的,您可以将任何 SHA3 哈希(或 SHA2 哈希)截断为小于其正常大小的大小,并获得更小但其他方面同样出色的加密哈希(对于真实数据,伪随机、不可逆和不冲突),事实上,人们几十年来一直在这样做。但是你不能安全地增加它,你可以使用像 SHAKE 这样的 XOF。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。