Java中如何创建满足系统长度和字符集要求的随机密码?
我必须创建一个随机密码,长度为 10-14 个字符,并且至少有一个大写字母、一个小写字母和一个特殊字符。不幸的是,有些特殊字符 太 特殊了,不能使用,所以我不能只使用打印的 ASCII。
本网站上的许多示例生成的随机密码或会话密钥在字符中没有足够的熵,或者在业务环境中没有像上面给出的那样的现实要求,所以我问更尖锐的问题以获得更好的答案。
我的字符集,标准美式键盘上除空格外的每个特殊字符:
A-Z
a-z
0-9
~`!@#$%^&*()-_=+[{]}\|;:'",<.>/?
原文由 summer 发布,翻译遵循 CC BY-SA 4.0 许可协议
我最近了解了 Passay 。它提供了其 PasswordGenerator 类 中所需的功能。它随机生成满足要求的密码,类似于下面使用 CharacterRules 而不是 PasswordCharacterSets 所写的要求,就像我在下面所做的那样。它不是为随机字符插入保存未使用索引的列表,而是在插入满足要求的字符后简单地洗牌字符缓冲区。
下面是之前遗留下来的,如果您的许可允许,我建议使用 Passay,否则这段代码应该可以工作,并提供了为什么生成的密码在密码学上很强大的详细信息
我最终将这段代码写了两次。曾经得到一个随机字符结果,但事实证明字符的分布取决于字符集的大小(糟糕!)。我重写了它,现在您只需复制/粘贴代码并将 Main.java 更改为您想要的字符集。尽管可以采取不同的方式,但我认为这是获得正确结果的相对直接的方法,我鼓励重复使用、评论、批评和深思熟虑的编辑。
PasswordGenerator代码的控件如下:
实际密码生成的主要部分:
密码复杂度说明:密码复杂度通常用位熵来表示。以下是您的键空间的可能性数量:
至少有一个大写字母字符(共 26 个)、一个小写字母字符(共 26 个)、一位数字(共 10 个)和一个特殊字符(共 32 个),计算可能性的方式是每个字符的可能性数乘以字符数,因为它们是随机放置在字符串中的。所以我们知道四个字符的可能性是:
所有剩余的字符每个都有 94 (26+26+10+32) 种可能性
我们的计算是:
考虑到这一点,如果您想要最安全的密码,您应该始终选择尽可能多的字符,在本例中为 14 个。
主.java
密码生成器.java