【问题标题】:Sha256 is not providing 16 byte arraySha256 不提供 16 字节数组
【发布时间】:2014-06-01 13:18:28
【问题描述】:

我使用下面的方法来生成 aes 加密的密码。

我的 aes 需要 16 个字节作为密钥。

这是我获取密钥的方式

    public  byte[] sha256digest16(String[] list) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        digest.reset();
        for(String s: list){
            digest.update(s.getBytes("UTF-8"));
        }
        byte[]  b = digest.digest();

        return String.format("%0" + (b.length) + 'x', new BigInteger(1, b)).getBytes("UTF-8");

    }

但是,它是 64 字节。我怎样才能让这个方法返回一个 16 字节的字符串

编辑 我这样做的主要原因是因为我的python代码是

from Crypto.Hash import SHA256


myHash = SHA256.new()
myHash.update("265jMeges")
print myHash.hexdigest()

哪个输出

917ef7e7be4a84e279b74a257953307f1cff4a2e3d221e363ead528c6b556edb

is的java输出在哪里

efbfbd7eefbfbdefbfbd4aefbfbdefbfbd79efbfbd4a257953307f1cefbfbd4a2e3d221e363eefbfbd52efbfbd6b556eefbfbd

对于相同的字符串。为什么它们不同?

【问题讨论】:

  • 如果你得到 64 个字节,你确定你没有使用 SHA512 吗?无论哪种方式,当前的哈希都不会给出短至 128 位的结果,因此您只需要截断输出即可。
  • 您能告诉我如何截断该输出吗?

标签: java encryption hash cryptography hex


【解决方案1】:

您将结果字节格式化为十六进制,这会将位占用率乘以 2。这样您永远不会得到 16 个字节。去掉 String.format() 行,只返回 digest() 方法的结果。我希望你在其他地方重复这个过程,这会再次加倍,

【讨论】:

    【解决方案2】:

    SHA-256 默认返回 32 个字节 (256 / 8 = 32),而不是 16 个。使用部分散列的正常方法是使用生成的散列的第一个(最左边)16 个字节。您可以通过对 SHA-256 的结果应用 Java copyOf 方法来做到这一点。

    请使用真正的十六进制编码器显示结果(不要返回值,您根本不需要任何String 实例)。使用BigInteger 容易出错,并且可能会添加或删除字节。

    试一试:

    public static byte[] sha256digest16(String[] list) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        digest.reset();
        for(String s: list){
            digest.update(s.getBytes("UTF-8"));
        }
    
        // so you have 32 bytes here
        byte[]  b = digest.digest();
    
        // you can return it directly or you can cut it to 16 bytes
        return Arrays.copyOf(b, 16);
    }
    

    要显示为十六进制,请使用:

    public static String tohex(byte[] data) {
        StringBuilder sb = new StringBuilder(data.length * 2);
        for (int i = 0; i < data.length; i++) {
            sb.append(String.format("%02X", data[i] & 0xFF));
        }
        return sb.toString();
    }
    

    或者使用 Apache 公共编解码器的十六进制编码器之一,Bouncy Castle 或 Guava。

    【讨论】:

    • 因此您显示 64 个十六进制字符,因为每个字节有 2 个字符,您只需显示 32 个字节,即哈希的完整输出。有什么可看的?在我的答案中更改了您的代码,看看这是否适合您。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多