2011-04-03 96 views

回答

204

SHA-256不是「編碼」 - 它是單向散列。

你基本上將字符串轉換爲字節(例如使用text.getBytes("UTF-8")),然後散列字節。請注意,散列的結果也是是任意的二進制數據,並且如果要在字符串中表示該值,則應該使用base64或hex ... 不要嘗試使用String(byte[], String)構造函數。

例如

MessageDigest digest = MessageDigest.getInstance("SHA-256"); 
byte[] hash = digest.digest(text.getBytes(StandardCharsets.UTF_8)); 
+9

*「SHA-256不是編碼」*絕對正確,但我必須說我更喜歡當前問題的標題「如何用sha加密「(許多人似乎認爲它是加密)。也許我們應該把它看作編碼,而不是用密碼術來處理,因爲在實踐中它更接近它的使用方式。 – Luc 2014-06-10 12:32:12

+1

@Luc:這是一個密碼哈希,所以我認爲說它不會與密碼學有關......加密和加密不可互換...... – 2014-06-10 12:34:20

+3

注意:這是一個好主意要使用[StandardCharsets.UTF_8](http://docs.oracle.com/javase/7/docs/api/java/nio/charset/StandardCharsets.html#UTF_8)而不是「UTF-8」字面Java 7+:一個檢查異常不用擔心。 – kryger 2015-12-01 21:59:37

56

完整的示例散列到字符串作爲另一個字符串。

public static String sha256(String base) { 
    try{ 
     MessageDigest digest = MessageDigest.getInstance("SHA-256"); 
     byte[] hash = digest.digest(base.getBytes("UTF-8")); 
     StringBuffer hexString = new StringBuffer(); 

     for (int i = 0; i < hash.length; i++) { 
      String hex = Integer.toHexString(0xff & hash[i]); 
      if(hex.length() == 1) hexString.append('0'); 
      hexString.append(hex); 
     } 

     return hexString.toString(); 
    } catch(Exception ex){ 
     throw new RuntimeException(ex); 
    } 
} 
+5

要將Jon的結果編碼爲十六進制,請考慮使用現有的庫,如[apache commons](http://commons.apache.org/codec/apidocs/org/apache/commons/codec/binary/Hex.html#encodeHexString%28byte []%29)而不是滾動你自己的。 – Leigh 2012-06-13 20:18:28

+0

@Leigh謝謝,我之前不知道這個庫。 – user1452273 2012-06-13 21:32:48

+1

是的,Apache項目有各種好東西。 – Leigh 2012-06-13 22:11:47

111

我認爲,最簡單的解決方法是使用Apache Common Codec

String sha256hex = org.apache.commons.codec.digest.DigestUtils.sha256Hex(stringText); 
+0

最簡單的方法做 – HelmiB 2017-12-25 02:15:31

75

另一種方法是Guava它具有易於使用的套件Hashing工具。例如,要使用SHA256作爲一個十六進制字符串哈希字符串,你會簡單地做:

final String hashed = Hashing.sha256() 
     .hashString("your input", StandardCharsets.UTF_8) 
     .toString(); 
+5

雖然這個工作,這使用您的字符串的UTF16_LE編碼。我建議顯式地傳入Charset作爲hashString()的第二個參數,特別是如果你想讓你的答案與上面的其他答案一致。 – 2013-09-26 22:03:27

+0

@SimonNickerson好點,我已經編輯了我的答案。 – Jonathan 2013-09-27 08:56:21

+0

直接點 – 2016-03-31 12:41:34

5

Convert Java String to Sha-256 Hash

import java.security.MessageDigest; 

public class CodeSnippets { 

public static String getSha256(String value) { 
    try{ 
     MessageDigest md = MessageDigest.getInstance("SHA-256"); 
     md.update(value.getBytes()); 
     return bytesToHex(md.digest()); 
    } catch(Exception ex){ 
     throw new RuntimeException(ex); 
    } 
} 
private static String bytesToHex(byte[] bytes) { 
    StringBuffer result = new StringBuffer(); 
    for (byte b : bytes) result.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1)); 
    return result.toString(); 
} 
} 
+0

用'0xff'按位與字節值的點是什麼?它什麼都不產生,是嗎? – yktoo 2017-01-27 14:20:42

+1

@yktoo:它將它轉換爲正整數(不幸的是,字節是用Java簽名的)http://stackoverflow.com/questions/11380062/what-does-value-0xff-do-in-java – leonbloy 2017-03-15 18:18:31

3

我通過DigestUtilssha256追溯到Apache的代碼似乎默認回到java.security.MessageDigest爲計算。 Apache不實施獨立的sha256解決方案。我正在尋找一個獨立的實現來與java.security庫進行比較。僅供參考。

16

如果您使用的是Java 8可以byte[]通過執行編碼

MessageDigest digest = MessageDigest.getInstance("SHA-256"); 
byte[] hash = digest.digest(text.getBytes(StandardCharsets.UTF_8)); 
String encoded = Base64.getEncoder().encodeToString(hash); 
+1

這種方式很方便爲了我。但是,您應該使用以下內容 Base64.encodeToString(hash,Base64.DEFAULT); – 2017-06-27 10:53:47

+0

@MotassemJalal Base64.DEFAULT在Java8的最新版本中不可用,我目前使用jdk1.8.0_144,請問您是如何創建它的? – rajadilipkolli 2017-12-01 07:30:01

0
String hashWith256(String textToHash) { 
    MessageDigest digest = MessageDigest.getInstance("SHA-256"); 
    byte[] byteOfTextToHash = textToHash.getBytes("UTF-8"); 
    byte[] hashedByetArray = digest.digest(byteOfTextToHash); 
    String encoded = Base64.encode(hashedByetArray); 
    return encoded; 
} 
1

您可以通過以下方式使用消息摘要:

public static String getSHA256(String data){ 
    StringBuffer sb = new StringBuffer(); 
    try{ 
     MessageDigest md = MessageDigest.getInstance("SHA-256"); 
     md.update(data.getBytes()); 
     byte byteData[] = md.digest(); 

     for (int i = 0; i < byteData.length; i++) { 
     sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1)); 
     } 
    } catch(Exception e){ 
     e.printStackTrace(); 
    } 
    return sb.toString(); 
} 
通過SHA [散列字符串的