Java:如何保留字符串的原始UTF-8数据?

时间:2011-04-26 11:01:58

标签: java utf-8 xmpp

我正在使用Java的XMPP(Jabber)客户端,我想通过SASL连接到服务器。经过一些研究,我发现这个site解释了整个身份验证机制。

问题是我应该将md5散列的结果保留为原始数据:

  

这是诀窍 - 通常当您散列内容时,您会得到十六进制值的结果。但是我们不希望这个结果是一串十六进制值!我们需要将结果保存为原始数据!如果你要对这些数据进行十六进制转储,你会发现它是“3a4f5725a748ca945e506e30acd906f0”。但请记住,我们需要对其原始数据进行操作,因此请勿将其转换为字符串。

如何在Java中实现这一目标?如果我不应该将结果转换为String,那么当我需要在另一个md5散列中使用它时,我该如何使用它呢?


只是仅供参考这是我学校项目的一部分(这不是强制性的,不是,我不是在寻求帮助而作弊)。而且我这样说是因为我被禁止使用JDK的非标准库(例如com.sun.org.apache)。

3 个答案:

答案 0 :(得分:1)

Java中的MessageDigest类可用于为您提供MD5哈希。 MD5 hasher得到它需要byte[]并返回byte[]。只需保留返回的byte[]即可。查看您提供链接的网页,看起来您将创建其他byte[],并将中间结果复制到其他byte[]的片段中,然后对其进行哈希处理。

答案 1 :(得分: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));  
}

我希望它有所帮助。

答案 2 :(得分:0)

很抱歉,但我并没有真正理解“原始数据”的含义。

实际上如果你有一个字节流或类似的东西,而不是将其转换为十六进制字符串,只需继续使用该字节流/数组......

我想不建议使用字符串,因为如果将字节转换为十六进制表示字符串,您可能会有使用myHexString.getBytes(“UTF-8”)的诱惑,它不会返回相应的字节数组期望的。