2011-08-17 151 views
1

我想將一些在Java中的代碼轉換爲C#。C#SHA-256與Java SHA-256。不同的結果?

Java代碼:

private static final byte[] SALT = "NJui8*&N823bVvy03^4N".getBytes(); 

    public static final String getSHA256Hash(String secret) 
    { 
    try { 
     MessageDigest digest = MessageDigest.getInstance("SHA-256"); 
     digest.update(secret.getBytes()); 
     byte[] hash = digest.digest(SALT); 
     StringBuffer hexString = new StringBuffer(); 
     for (int i = 0; i < hash.length; i++) { 
     hexString.append(Integer.toHexString(0xFF & hash[i])); 
     } 
     return hexString.toString(); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } 
    throw new RuntimeException("SHA-256 realization algorithm not found in JDK!"); 
    } 

當我試圖使用the SimpleHash class我得到不同hashs

UPDATE:

例如:

爪哇:字節[]散列= digest.digest(SALT); 生成(前6個字節):

[0] = 9 
[1] = -95 
[2] = -68 
[3] = 64 
[4] = -11 
[5] = 53 
.... 

C#代碼(類SimpleHash): 串散列值= Convert.ToBase64String(hashWithSaltBytes); hashWithSaltBytes具有(前6個字節):

[0] 175 byte 
[1] 209 byte 
[2] 120 byte 
[3] 74 byte 
[4] 74 byte 
[5] 227 byte 
+3

爲什麼法名爲'getMd5Hash'如果你使用'「SHA-256」'? – dtb

+0

我不知道。可能是這種方法在過去生成MD5。我們只是將項目從java轉換爲C# –

回答

6

String.getBytes method編碼串使用平臺的默認字符集字節,而你鏈接的示例代碼使用UTF-8。

試試這個:

digest.update(secret.getBytes("UTF-8")); 

其次,Integer.toHexString method返回十六進制的結果,沒有前導零。

+0

謝謝。解決了這個問題。 –

2

您鏈接到的C#代碼也使用salt - 但Java代碼沒有。如果一次使用鹽,但不使用其他鹽,那麼結果將會不同(和應該是!)。

+0

該代碼包含'byte [] hash = digest.digest(SALT);'。那不是使用鹽嗎? – dtb

+0

啊,我以前沒有發現... – Cocowalla

2
hexString.append(Integer.toHexString(0xFF & hash[i])); 

您錯誤地建立散列字符串。 Integer.toHexString不包含前導零,所以雖然Integer.toHexString(0xFF) == "FF",問題是Integer.toHexString(0x05) == "5"

建議修正:String.format("%02x", hash[i] & 0xFF)

0

你真的不寫你怎麼叫SimpleHash類 - 有哪些參數和這樣的。

但請注意,其ComputeHash方法都有其文檔中:格式化爲base64編碼字符串

哈希值。

你的類改爲以十六進制格式化輸出,這顯然是不同的。當你的方法將它解釋爲ASCII(或者任何你的系統編碼 - 很可能是與ASCII兼容的東西,並且字符串只包含ASCII字符)時,SimpleHash將salt解釋爲base64。

此外,SimpleHash中的輸出包括salt(允許在使用隨機鹽時對其進行「驗證」部分的重現),而不是在您的方法中。

(詳細點已經由其他的答案中提到。)