Java: How to keep raw UTF-8 data of string?
I'm working on XMPP (Jabber) client in Java and I want to connect to server via SASL. After some research I found this site that explains whole authentication mechanism.
Problem is when I'm supposed to keep result of md5 hashing as raw data:
Here's the trick - normally when you hash stuff you get a result in hex values. But we don't want this result as a string of hex values! We need to keep the result as raw data! If you were to do a hex dump of this data you'd find it to be "3a4f5725a748ca945e506e30acd906f0". But remeber, we need to operate on it's raw data, so don't convert it to a string.
How can this be achieved in Java? And if I'm not supposed to convert result to String, how should I work with it afterwards when I need to use it in another md5 hashing?
And just FYI this is part of my school project (it's not mandatory and no, I'm not che开发者_开发百科ating by asking for help). And I'm saying that because I'm forbidden to use nonstandard libraries of JDK (for example com.sun.org.apache).
The MessageDigest
class in Java can be used to give you a MD5 hasher. The MD5 hasher you get from it takes a byte[]
and returns a byte[]
. Just keep around the returned byte[]
. Looking at the web page you gave a link to, it looks like you'll have be making other byte[]
and will be copying intermediate results into pieces of other byte[]
and then hashing those.
If someone wanted the code that computes response String for XMPP SASL challenge query, here it is:
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));
}
I hope it helps.
Sorry but i don't really catch what you mean by "raw data".
Actually if you have a byte stream or something raw like that, instead of converting it to a hex String, just keep using that byte stream/array...
I guess it's not advised to use string because if you convert the bytes to an hexadecimal representation string, you could have the temptation to use myHexString.getBytes("UTF-8") that would not return the appropriate byte array you would expect.
精彩评论