2011-04-26 69 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”)的诱惑,它不会返回您所期望的相应字节数组。

相关问题