使用Utility.convertByteArrayToCharArray和MessageDigest的MalformatedInputException

时间:2014-06-11 17:45:57

标签: java java-7

我正在尝试创建一个Glassfish自定义JDBCRealm,并且在对它进行一些测试时,当我使用com.sun.enterprise.util.Utility.convertByteArrayToCharArray函数时,我得到了一个MalformatedInputException。

所以我决定外化我的函数部分,它抛出这个错误来测试它并理解它的来源。

恢复功能:

public void justATestFunction()
        throws Exception
{
    final char[] password = "myP4ssW0rd42".toCharArray();
    MessageDigest md = MessageDigest.getInstance("SHA-256");

    // according to the Utility doc, if the Charset parameter is null or empty,
    // it will call the Charset.defaultCharset() function to define the charset to use
    byte[] hashedPassword= Utility.convertCharArrayToByteArray(password, null);
    hashedPassword = md.digest(hashedPassword);
    Utility.convertByteArrayToCharArray(hashedPassword, null); // throw a MalformatedInputException
}

提前感谢您的回答。

1 个答案:

答案 0 :(得分:1)

让我们看看每一步:

byte[] hashedPassword= Utility.convertCharArrayToByteArray(password, null);

上面使用默认的endcoding将Unicode-16字符转换为字节数组,可能是WIN-1252或UTF-8。由于密码不包含标准7位ASCII之外的任何内容,因此对于任一编码,结果都是相同的。

hashedPassword = md.digest(hashedPassword);

hashedPassword现在引用一个完全不同的字节数组,其中包含原始密码的BINARY摘要。这是一个BINARY字符串,不再代表任何字符编码中的任何内容。它是纯二进制数据。

Utility.convertByteArrayToCharArray(hashedPassword, null);

现在你尝试"解码"二进制字符串,好像它是用默认字符集编码的,这无疑会引发异常。

我怀疑你真的想要显示摘要的十六进制表示,或者可能是base-64版本。在任何一种情况下,你所做的都将永远不会奏效。

由于您还没有解释您想要完成的任务,因此这是任何人都可以做到的。