2012-12-09 34 views
1

我使用Apache DS与Spring LDAP进行身份验证和用户管理。 Apache DS将密码字段作为散列字节数组发送,所以我需要将其解密为字符串。我正在使用MD5哈希。无法解密MD5哈希字节数组

例如,下面是用于使用Apache DS工作室输入密码的窗口:

(出于演示的目的,我想告诉输入的密码是)

enter image description here

Apache DS将密码字段作为散列字节数组发送。当我尝试使用如下的Spring LDAP时,我得到了[B @ 66ca6254。我需要解密它,并得到它的十六进制值,它是c4ca4238a0b923820dcc509a6f75849b,如上所示。

回答

3

你来到这里两个问题:

  • 您使用的术语“解密”,如果你是真正能够恢复原来的密码。事实并非如此。希望您已经理解了这一点,并且您只是不恰当地使用术语“解密”
  • 您在字节数组上调用toString()。这就是“B @ 66ca6254”这个值,它表明你调用它的对象是一个字节数组,然后是一个散列。你真正感兴趣的是字节数组的十六进制表示。

基本上你只需要将字节数组转换为十六进制字符串。有多种方式可以做到这一点 - 无论是在您自己的代码中,还是使用第三方库(如Apache Commons Code及其Hex类)。如果您不想包含额外的库,则在堆栈溢出时会有加载的代码片段用于字节数组到十六进制字符串的转换,例如here。 (也有javax.xml.bind.DataTypeConverter,但我个人不希望将其用于常规转换 - 它对我来说太过于类似于XML的类型,我敢说它可以正常工作,它只是给代码中的错误印象。)

编辑:现在,你已经告诉我们你得到的字节,你不要只是想使用十六进制。您已获得"{MD5}xMpCOKC5I4INzFCab3WEmw=="的ASCII编码格式,它本身表明它是MD5,然后是base64编码版本。因此,你应该:

  • 字节数组转换为使用new String(data, "ASCII")
  • 检查字符串以"{MD5}"
  • 解码字符串为base64的其余开头的字符串(即,剥离前5个字符,然后通过base64解码运行其余部分)。同样,您可以使用Apache Commons Codec,或者使用this public domain base64 decoder(或许多其他解决方案)。
  • 在这一点上,你有实际散列的原始二进制数据。如前所述,如果需要,可以将其转换为十六进制。
+0

'字符串十六进制串=新的String(Hex.encodeHex(byteArrayPassword));'这给了我** ** 7b4d44357d784d70434f4b43354934494e7a464361623357456d773d3d而不是** ** c4ca4238a0b923820dcc509a6f75849b。 – talha06

+1

@ talha06:啊,对。现在我明白了。将编辑。 –

+0

现在它提供了这些输出,我仍然无法将原始密码的十六进制值转换回来'hexString = hexString.substring(5); // xMpCOKC5I4INzFCab3WEmw == byte [] bytes = Base64.decodeBase64(hexString.getBytes()); hexString = Hex.encodeHex(bytes).toString(); // [C @ 4c065f0a' – talha06

0

你不能解密MD5哈希,它是单向哈希函数。

+0

不,我的意思只是转换散列字节数组转换为十六进制 – talha06