Sha256不提供16字节数组

时间:2014-04-17 10:09:21

标签: java encryption hash cryptography hex

我使用以下方法为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

的java输出
efbfbd7eefbfbdefbfbd4aefbfbdefbfbd79efbfbd4a257953307f1cefbfbd4a2e3d221e363eefbfbd52efbfbd6b556eefbfbd

表示相同的字符串。他们为什么不同?

2 个答案:

答案 0 :(得分:4)

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 commons编解码器,Bouncy Castle或Guava的十六进制编码器之一。

答案 1 :(得分:0)

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