1

我已经编写了一种使用 MD5 算法将纯文本转换为哈希码的方法。请在下面找到我使用的代码。

public static String convertToMD5Hash(final String plainText){
            MessageDigest messageDigest = null;

            try {
                messageDigest = MessageDigest.getInstance("MD5");
            } catch (NoSuchAlgorithmException e) {
                LOGGER.warn("For some wierd reason the MD5 algorithm was not found.", e);
            }

            messageDigest.reset();
            messageDigest.update(plainText.getBytes());
            final byte[] digest = messageDigest.digest();
            final BigInteger bigInt = new BigInteger(1, digest);
            String hashtext = bigInt.toString(8);

            return hashtext;
}

此方法完美运行,但它返回一个冗长的哈希。我需要将此哈希文本限制为 8 个字符。有没有可能在 Java 中设置哈希码的长度?

4

4 回答 4

7

是和否。如果您总是以相似的方式剪切原始哈希字符串(即 8 个最后/第一个字符),则可以使用原始哈希的子字符串。你打算用那个“半哈希”做什么是另一回事。

无论您要做什么,请确保它与安全无关。

原因如下:MD5 是 128 位哈希,所以有 2^128 = ~340,000,000,000,000,000,000,000,000,000,000,000,000 种可能的排列。相当数量的排列使得暴力破解这种字符串几乎是不可能的。通过减少到 8 个字符,您将得到 32 位散列。这是因为单个十六进制值需要 4 位来表示(因此,128 位 / 4 位 = 32 个十六进制值)。使用 32 位哈希,只有 2^32 = 4,294,967,296 种组合。这比原始 128 位散列的安全性低大约 79,228,162,514,264,337,593,543,950,336 倍,并且可以在几秒钟内被任何具有 80 年代计算器处理能力的旧计算机破解。

于 2013-11-11T13:02:33.467 回答
1

没有。MD5 被定义为返回 128 位值。您可以使用 Base64 将它们编码为 ASCII 并使用String#substring(0, 8).

在 Java 8(尚未正式发布)中,您可以将 a 编码byte[]为 Base64,如下所示:

String base64 = Base64.getEncoder().encodeToString(digest);

对于早期的 Java 版本,请参阅在 Java 中解码 Base64 数据

于 2013-11-11T11:59:17.200 回答
0

首先,正如大家所提到的,64 位哈希不够安全。最终,这取决于您计划对哈希做什么。

如果您仍需要将其转换为 8 个字符,我建议使用将 BigInteger 向下转换为 Long 值BigIteger.longValue()

它将确保它产生的长值与产生的散列一致。

我不确定从 128 位哈希中获取最重要的 64 位是否是个好主意。我宁愿采用最低有效的 64 位。这确保的是

什么时候hash(128, a) = hash(128, b)永远hash(64, a) = hash(64, b)是真的。

但是在 64 位的情况下,我们必须忍受冲突,即当hash(64, a) = hash(64, b)thenhash(128, a) = hash(128, b)并不总是正确的时候。

简而言之,我们确保不会出现 2 个文本的 128 位哈希值不同但它们的 64 位哈希值相同的情况。这取决于您真正使用哈希的目的,但我个人认为这种方法更正确。

于 2013-11-14T07:10:58.167 回答
0

每当数据的任何部分发生更改时,所有哈希算法都应随机更改整个哈希中的位。所以你可以从你的哈希中选择 8 个字符。只是不要随意挑选它们 - 它必须是可重现的

于 2013-11-11T12:00:14.663 回答