我使用以下方法为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
表示相同的字符串。他们为什么不同?
答案 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()方法的结果。我希望你能在其他地方重复这个过程,再次加倍,