Javastring到SHA1

我正在尝试在Java中做一个简单的stringSHA1转换器,这是我得到的…

public static String toSHA1(byte[] convertme) { MessageDigest md = null; try { md = MessageDigest.getInstance("SHA-1"); } catch(NoSuchAlgorithmException e) { e.printStackTrace(); } return new String(md.digest(convertme)); } 

当我把它传递给toSHA1("password".getBytes()) ,我得到“[ a ɹ?? %l 3〜 。 我知道这可能是一个像UTF-8简单的编码修复,但有人可以告诉我该怎么做才能得到我想要的“5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8”? 还是我这样做完全错了?

非常感谢!

UPDATE
您可以使用Apache Commons Codec (版本1.7+)为您完成这项工作。

  DigestUtils.sha1Hex(stringToConvertToSHexRepresentation) 

感谢@ Jon Onstott对此build议。


老答案
将您的字节数组转换为hexstring。 真正的如何告诉你如何 。

 return byteArrayToHexString(md.digest(convertme)) 

和(从真实的如何)

 public static String byteArrayToHexString(byte[] b) { String result = ""; for (int i=0; i < b.length; i++) { result += Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 ); } return result; } 

顺便说一句,你可能会得到更紧凑的代表使用Base64。 Apache Commons Codec API 1.4 ,有这个很好的工具来消除所有的痛苦。 请参阅这里

这是我把string转换为sha1的解决scheme。 它适用于我的Android应用程序:

 private static String encryptPassword(String password) { String sha1 = ""; try { MessageDigest crypt = MessageDigest.getInstance("SHA-1"); crypt.reset(); crypt.update(password.getBytes("UTF-8")); sha1 = byteToHex(crypt.digest()); } catch(NoSuchAlgorithmException e) { e.printStackTrace(); } catch(UnsupportedEncodingException e) { e.printStackTrace(); } return sha1; } private static String byteToHex(final byte[] hash) { Formatter formatter = new Formatter(); for (byte b : hash) { formatter.format("%02x", b); } String result = formatter.toString(); formatter.close(); return result; } 

使用番石榴散列类 :

 Hashing.sha1().hashString( "password", Charsets.UTF_8 ).toString() 

只需使用apache commons编解码器库。 他们有一个名为DigestUtils的工具类

没有必要进入细节。

SHA-1(以及所有其他哈希algorithm)返回二进制数据。 这意味着(在Java中)它们产生一个byte[] 。 该byte数组不代表任何特定的字符,这意味着你不能像你一样简单地把它变成一个String

如果你需要一个String ,那么你必须以一种可以被表示为一个String的方式来格式化这个byte[] (否则,只需保持byte[] )。

将任意byte[]表示为可打印字符的两种常见方式是BASE64或简单的hexstring(即用两个hex数字表示每个byte )。 它看起来像你试图产生一个hexstring。

还有一个错误:如果你想得到一个Java String的SHA-1,那么你首先需要将该String转换为一个byte[] (因为SHA-1的input也是一个byte[] )。 如果您只是简单地使用myString.getBytes() ,那么它将使用平台默认编码,因此将取决于您在其中运行的环境(例如,它可能会根据语言/区域设置返回不同的数据你的操作系统)。

更好的解决scheme是指定用于Stringbyte[]转换的编码,如下所示: myString.getBytes("UTF-8") 。 selectUTF-8(或其他可以代表每个Unicode字符的编码)是最安全的select。

如果将string转换为hex格式,这是非常简单的解决scheme:

 private static String encryptPassword(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException { MessageDigest crypt = MessageDigest.getInstance("SHA-1"); crypt.reset(); crypt.update(password.getBytes("UTF-8")); return new BigInteger(1, crypt.digest()).toString(16); } 

如前所述使用apache commons编解码器。 这也是春季大家推荐的(参见Spring doc中的DigestUtils)。 例如:

 DigestUtils.sha1Hex(b); 

绝对不会在这里使用最高评分的答案。

它不能正确打印,因为您需要使用Base64编码。 使用Java 8,您可以使用Base64编码器类进行编码。

 public static String toSHA1(byte[] convertme) { md = MessageDigest.getInstance("SHA-1"); return Base64.getEncoder().encodeToString((md.digest(convertme)); } 

结果

这会给你预期的输出5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8

这不起作用的原因是当你调用String(md.digest(convertme)) ,你告诉Java将一串encryption字节解释为一个String。 你想要的是将字节转换成hex字符。

转换字节数组为hexstring

 public static String toSHA1(byte[] convertme) { final char[] HEX_CHARS = "0123456789ABCDEF".toCharArray(); MessageDigest md = null; try { md = MessageDigest.getInstance("SHA-1"); } catch(NoSuchAlgorithmException e) { e.printStackTrace(); } byte[] buf = md.digest(convertme); char[] chars = new char[2 * buf.length]; for (int i = 0; i < buf.length; ++i) { chars[2 * i] = HEX_CHARS[(buf[i] & 0xF0) >>> 4]; chars[2 * i + 1] = HEX_CHARS[buf[i] & 0x0F]; } return new String(chars); }