使用UUID生成特定字符串的唯一标识符是否安全(就唯一性而言)?

4
String myText;
UUID.nameUUIDFromBytes((myText).getBytes()).toString();

我正在使用上述代码为特定文本生成代表符号。

例如,'Moien'应始终用“e9cad067-56f3-3ea9-98d2-26e25778c48f”表示,任何更改如项目重建都不应更改UUID。

我这样做的原因是,我不希望人类能够阅读(理解)这些特定的文本。

注意:我不需要在哈希后重新生成主文本(例如“Moien”)的能力。

我还有一种替代方法:

            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest((matcher.group(1)).getBytes("UTF-8"));
            String a = Base64.encode(hash);

你认为哪种方式更适合我的问题呢?

“我的意思是我不希望那些特定的文本对人类可读(可理解)。” - 为什么?这让我担心,因为这可能意味着您正在使用编码而不是加密。 - dkatzel
前者使用 MD5 而非 SHA-256,但结果是等效的:它为(实际上)无限的源集提供了一个有限集合中的值,试图使冲突不太可能发生,但并非不可能。换句话说,它并不像您问题标题所问的那样“安全(在独特性方面)”。如果您想要完全排除冲突,散列并不是正确的工具。 - Holger
他不是在寻找编码,而是哈希。 - Buhake Sindi
例如,我需要检查A是否等于B。但如果不是,我不希望B知道A的实际值,反之亦然。因此,我使用单向哈希将A和B转换为字符串,然后检查哈希字符串是否相等。 - MoienGK
1个回答

4

UUID.nameUUIDFromBytes 看起来基本上就是使用 MD5 哈希,结果表示为 UUID。

我觉得更清晰的方法是明确使用 base64 编码的哈希,部分原因是你可以控制使用哪个哈希——如果冲突会带来任何安全风险,则这可能是相关的。 (SHA-256 对于正是这个原因可能是比 MD5 更好的选择。) 当然,从 SHA-256 得到的字符串会更长,但希望这不是问题。

请注意,在任一情况下,我都会通过 StandardCharsets 使用固定编码将字符串转换为文本。不要使用平台默认值(如第一个片段所示),而应优先考虑 StandardCharsets 而非魔术字符串值(如第二个片段所示)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接