2011-04-26 68 views
2

我正在使用Java中的XMPP(Jabber)客戶端,我想通過SASL連接到服務器。經過一番研究,我發現這個解釋整個認證機制的這個siteJava:如何保持字符串的原始UTF-8數據?

問題是,當我應該保持的MD5哈希結果作爲原始數據:

這裏的絕招 - 通常,當你湊的東西,你得到的十六進制值的結果。但是我們不希望這個結果是一串十六進制值!我們需要將結果保留爲原始數據!如果你要做這個數據的十六進制轉儲,你會發現它是「3a4f5725a748ca945e506e30acd906f0」。但是請記住,我們需要對它的原始數據進行操作,所以不要將其轉換爲字符串。

這怎麼能在Java中實現?如果我不應該將結果轉換爲String,那麼當我需要在另一個md5散列中使用它時,我應該如何處理它?


而只是FYI這是我的學校項目的一部分(這不是強制性的,不,我不尋求幫助作弊)。我在說因爲我禁止使用JDK的非標準庫(例如com.sun.org.apache)

+0

你可以添加一些代碼嗎? 「我需要函數X的結果,但格式爲Y」。目前尚不清楚你究竟需要什麼「原始數據」(Byte [])。 – 2011-04-26 11:11:35

回答

1

如果有人想一個計算響應字符串XMPP SASL挑戰查詢代碼,那就是:

private static byte[] combineByteArrays(byte[] a, byte[] b) { // combines two byte[] arrays 
    byte[] result = new byte[a.length + b.length]; 
    System.arraycopy(a, 0, result, 0, a.length); 
    for (int i = a.length; i < result.length; i++) { 
     result[i] = b[i-a.length];    
    } 
    return result; 
} 

private static String byteArrayToHex(byte[] array) { // returns hex representation of byte[] array 
    String resultStr = ""; 
    for (int i=0; i < array.length; i++) { 
     resultStr += Integer.toString((array[i] & 0xff) + 0x100, 16).substring(1); 
    } 
    return resultStr; 
} 

private static String computeResponse(String username, String password, String realm, String nonce, String qop, String cnonce, String digest_uri, String nc) throws NoSuchAlgorithmException { // computes response for challenge query of XMPP server 
    MessageDigest md5 = MessageDigest.getInstance("MD5"); 
    final byte[] part1 = md5.digest(combineByteArrays(md5.digest((username + ":" + realm + ":" + password).getBytes()), (":" + nonce + ":" + cnonce).getBytes())); 
    final byte[] part2 = md5.digest(combineByteArrays("AUTHENTICATE:".getBytes(), digest_uri.getBytes())); 
    final byte[] temp = combineByteArrays(byteArrayToHex(part1).getBytes(), (":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":").getBytes()); 
    final byte[] part3 = md5.digest(combineByteArrays(temp, byteArrayToHex(part2).getBytes())); 
    return byteArrayToHex(part3); 
} 

public static void main(String[] args) throws NoSuchAlgorithmException { 

    /* example data from http://deusty.blogspot.com/2007/09/example-please.html */ 
    String username = "test"; 
    String password = "secret"; 
    String realm = "osXstream.local"; 
    String nonce = "392616736"; 
    String qop = "auth"; 
    String cnonce = "05E0A6E7-0B7B-4430-9549-0FE1C244ABAB"; 
    String digest_uri = "xmpp/osXstream.local"; 
    String nc = "00000001";   

    /* prints out "37991b870e0f6cc757ec74c47877472b" */ 
    System.out.println(computeResponse(username, password, realm, nonce, qop, cnonce, digest_uri, nc)); 
} 

我希望它能幫助。

1

Java中的MessageDigest類可用於爲您提供MD5散列器。從中獲得的MD5 hasher需要byte[]並返回byte[]。只是保持在返回byte[]。看着你給出鏈接的網頁,它看起來像你會做其他byte[],並將複製中間結果成其他byte[]片段,然後哈希那些。

+0

現在我完全失去了。我嘗試過:'String input =「testing」;''MessageDigest md5 = MessageDigest.getInstance(「MD5」);''byte [] result = md5.digest(input.getBytes());'如果我打印出來其結果是完整的垃圾。如果我嘗試打印出來逐字節它看起來像一些字節是負面的,這似乎是奇怪的... – MyFlower 2011-04-26 12:00:49

+0

@MyFlower:是的,它是完整的垃圾。這是散列工作方式。如果你想看看它,將其轉換爲十六進制或base64或其他東西,但要使用它,你將使用'byte []'。 – 2011-04-26 12:04:17

+0

我愛你!:-D我非常接近正確的解決方案,但你指出了我的正確方向。謝謝! – MyFlower 2011-04-26 12:10:04

0

對不起,但我不明白你的意思是「原始數據」。

其實如果你有一個字節流或原始的東西,而不是將其轉換爲十六進制字符串那樣,只是一味地使用字節流/陣列...

我想這是不建議使用的字符串,因爲如果將字節轉換爲十六進制表示字符串,則可能有使用myHexString.getBytes(「UTF-8」)的誘惑,它不會返回您所期望的相應字節數組。

相關問題