我正在使用Java的XMPP(Jabber)客户端,我想通过SASL连接到服务器。经过一些研究,我发现这个site解释了整个身份验证机制。
问题是我应该将md5散列的结果保留为原始数据:
这是诀窍 - 通常当您散列内容时,您会得到十六进制值的结果。但是我们不希望这个结果是一串十六进制值!我们需要将结果保存为原始数据!如果你要对这些数据进行十六进制转储,你会发现它是“3a4f5725a748ca945e506e30acd906f0”。但请记住,我们需要对其原始数据进行操作,因此请勿将其转换为字符串。
如何在Java中实现这一目标?如果我不应该将结果转换为String,那么当我需要在另一个md5散列中使用它时,我该如何使用它呢?
只是仅供参考这是我学校项目的一部分(这不是强制性的,不是,我不是在寻求帮助而作弊)。而且我这样说是因为我被禁止使用JDK的非标准库(例如com.sun.org.apache)。
答案 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”)的诱惑,它不会返回相应的字节数组期望的。