如何使用Java创建符合系统长度和字符集要求的随机密码?
我必须创建一个随机密码,密码长度为10-14个字符,并且至少具有一个大写字母,一个小写字母和一个特殊字符。不幸的是,某些特殊字符 太
特殊而无法使用,因此我不能仅使用打印的ASCII。
该站点上的许多示例都会生成一个随机的密码或会话密钥,而在字符中没有足够的熵,或者在像上面给出的那样的商业环境中没有现实的要求,因此,我想提出更明确的问题以获得更好的答案。
我的字符集,标准美国键盘上的每个特殊字符(空格除外):
A-Z
a-z
0-9
~`!@#$%^&*()-_=+[{]}\|;:'",<.>/?
我最近了解了Passay。它在PasswordGenerator类中提供所需的必需功能。它会随机生成满足以下要求的密码,这些密码类似于使用CharacterRules而不是我下面所做的PasswordCharacterSets所写的内容。它不保留用于随机字符插入的未使用索引的列表,而只是在插入符合要求的字符后才重新洗改字符缓冲区。
以下是以前遗留下来的内容,如果您的许可允许,我建议您使用Passay,否则此代码应该可以正常工作,并详细说明了为什么生成的密码具有极高的密码强度
我最终两次编写了这段代码。曾经获得随机字符结果,但事实证明,字符的分布取决于字符集的大小(哇!)。我重写了它,现在您应该只复制/粘贴代码并将Main.java更改为所需的字符集。尽管可以采取不同的方法,但我认为这是获得正确结果的相对简单的方法,我鼓励重用,评论,批评和周密的编辑。
PasswordGenerator代码的控件如下:
实际密码生成的主要位:
密码复杂度的描述:密码复杂度通常用熵来谈论。以下是您的键空间的可能数量:
计算可能性数的方式至少有一个大写字母字符(26个中的一个),一个小写字母字符(26个中的一个),一个数字(10个中的一个)和一个特殊字符(32个中的一个),这是您计算可能性的方式是每个字符的可能性数乘以字符数,因为它们被随机放置在字符串中。因此,我们知道其中四个字符的可能性是:
Required Characters = 26*26*10*32=216,320
其余所有角色每个都有94(26 + 26 + 10 + 32)个可能性
我们的计算是:
Characters Possibilities Bits of Entropy
10 chars 216,320*94^6 = 149,232,631,038,033,920 ~2^57
11 chars 216,320*94^7 = 14,027,867,317,575,188,480 ~2^63
12 chars 216,320*94^8 = 1,318,619,527,852,067,717,120 ~2^70
13 chars 216,320*94^9 = 123,950,235,618,094,365,409,280 ~2^76
14 chars 216,320*94^10 = 11,651,322,148,100,870,348,472,320 ~2^83
考虑到这一点,如果您想要最安全的密码,则应始终选择尽可能多的字符,在这种情况下为14。
Main.java
package org.redtown.pw;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Set;
import org.redtown.pw.PasswordGenerator.PasswordCharacterSet;
public class Main {
public static void main(String[] args) {
Set<PasswordCharacterSet> values = new HashSet<PasswordCharacterSet>(EnumSet.allOf(SummerCharacterSets.class));
PasswordGenerator pwGenerator = new PasswordGenerator(values, 10, 14);
for(int i=0; i < 10; ++i) {
System.out.println(pwGenerator.generatePassword());
}
}
private static final char[] ALPHA_UPPER_CHARACTERS = { 'A', 'B', 'C', 'D',
'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
private static final char[] ALPHA_LOWER_CHARACTERS = { 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
private static final char[] NUMERIC_CHARACTERS = { '0', '1', '2', '3', '4',
'5', '6', '7', '8', '9' };
private static final char[] SPECIAL_CHARACTERS = { '~', '`', '!', '@', '#',
'$', '%', '^', '&', '*', '(', ')', '-', '_', '=', '+', '[', '{',
']', '}', '\\', '|', ';', ':', '\'', '"', ',', '<', '.', '>', '/',
'?' };
private enum SummerCharacterSets implements PasswordCharacterSet {
ALPHA_UPPER(ALPHA_UPPER_CHARACTERS, 1),
ALPHA_LOWER(ALPHA_LOWER_CHARACTERS, 1),
NUMERIC(NUMERIC_CHARACTERS, 1),
SPECIAL(SPECIAL_CHARACTERS, 1);
private final char[] chars;
private final int minUsage;
private SummerCharacterSets(char[] chars, int minUsage) {
this.chars = chars;
this.minUsage = minUsage;
}
@Override
public char[] getCharacters() {
return chars;
}
@Override
public int getMinCharacters() {
return minUsage;
}
}
}
PasswordGenerator.java
package org.redtown.pw;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class PasswordGenerator {
private final List<PasswordCharacterSet> pwSets;
private final char[] allCharacters;
private final int minLength;
private final int maxLength;
private final int presetCharacterCount;
public PasswordGenerator(Collection<PasswordCharacterSet> origPwSets, int minLength, int maxLength) {
this.minLength = minLength;
this.maxLength = maxLength;
// Make a copy of the character arrays and min-values so they cannot be changed after initialization
int pwCharacters = 0;
int preallocatedCharacters = 0;
List<PasswordCharacterSet> pwSets = new ArrayList<PasswordCharacterSet>(origPwSets.size());
for(PasswordCharacterSet origpwSet : origPwSets) {
PasswordCharacterSet newPwSet = new PwSet(origpwSet);
pwSets.add(newPwSet);
pwCharacters += newPwSet.getCharacters().length;
preallocatedCharacters += newPwSet.getMinCharacters();
}
this.presetCharacterCount = preallocatedCharacters;
this.pwSets = Collections.unmodifiableList(pwSets);
if (minLength < presetCharacterCount) {
throw new IllegalArgumentException("Combined minimum lengths "
+ presetCharacterCount
+ " are greater than the minLength of " + minLength);
}
// Copy all characters into single array so we can evenly access all members when accessing this array
char[] allChars = new char[pwCharacters];
int currentIndex = 0;
for(PasswordCharacterSet pwSet : pwSets) {
char[] chars = pwSet.getCharacters();
System.arraycopy(chars, 0, allChars, currentIndex, chars.length);
currentIndex += chars.length;
}
this.allCharacters = allChars;
}
public char[] generatePassword() {
SecureRandom rand = new SecureRandom();
// Set pw length to minLength <= pwLength <= maxLength
int pwLength = minLength + rand.nextInt(maxLength - minLength + 1);
int randomCharacterCount = pwLength - presetCharacterCount;
// Place each index in an array then remove them randomly to assign positions in the pw array
List<Integer> remainingIndexes = new ArrayList<Integer>(pwLength);
for(int i=0; i < pwLength; ++i) {
remainingIndexes.add(i);
}
// Fill pw array
char[] pw = new char[pwLength];
for(PasswordCharacterSet pwSet : pwSets) {
addRandomCharacters(pw, pwSet.getCharacters(), pwSet.getMinCharacters(), remainingIndexes, rand);
}
addRandomCharacters(pw, allCharacters, randomCharacterCount, remainingIndexes, rand);
return pw;
}
private static void addRandomCharacters(char[] pw, char[] characterSet,
int numCharacters, List<Integer> remainingIndexes, Random rand) {
for(int i=0; i < numCharacters; ++i) {
// Get and remove random index from the remaining indexes
int pwIndex = remainingIndexes.remove(rand.nextInt(remainingIndexes.size()));
// Set random character from character index to pwIndex
int randCharIndex = rand.nextInt(characterSet.length);
pw[pwIndex] = characterSet[randCharIndex];
}
}
public static interface PasswordCharacterSet {
char[] getCharacters();
int getMinCharacters();
}
/**
* Defensive copy of a passed-in PasswordCharacterSet
*/
private static final class PwSet implements PasswordCharacterSet {
private final char[] chars;
private final int minChars;
public PwSet(PasswordCharacterSet pwSet) {
this.minChars = pwSet.getMinCharacters();
char[] pwSetChars = pwSet.getCharacters();
// Defensive copy
this.chars = Arrays.copyOf(pwSetChars, pwSetChars.length);
}
@Override
public char[] getCharacters() {
return chars;
}
@Override
public int getMinCharacters() {
return minChars;
}
}
}
问题内容: 我正在尝试为具有以下密码要求的Active Directory生成随机密码:至少8个字符,至少一个特殊字符,至少一位数字,至少一个小写字母和至少一个大写字母。 使用以下代码,我可以生成一个随机密码,并检查它是否包含特殊字符。生成新密码,直到找到特殊字符为止。 以下问题是,它仅检查特殊字符并生成新密码可能会摆脱其他要求(假设它们已经存在)。如何才能有效地实施AD密码要求?谢谢你的帮助。
这就是我获取XML响应的方式: 希望有人能帮我。我认为URLConnection或其中一个流需要设置为UTF-8,考虑到谷歌的响应也是用UTF-8编码的?!
如何使这个随机密码生成器生成至少一个组件?目前,生成的密码中没有包含数字,或者遗漏了任何其他类型的数字。如何使它至少生成其中的类型?
问题内容: PHP的函数不能提供良好的随机数。因此,我开始使用据说效果更好的产品。但是这些结果有多好?有什么方法可以再次改善它们? 我的点子: 这应该给您“完美的”随机数,不是吗? 问题答案: 伪随机数生成器(PRNG)是非常复杂的野兽。 没有真正的“完美”随机数生成器-实际上,可以通过数学函数完成的最好的操作是伪随机数-对于大多数意图和目的,它们似乎足够随机。 实际上,从PRNG返回的数字中执行
问题内容: 我正在尝试从Timus在线法官那里解决这个问题。要解决此问题,您需要生成1 000 000个小写拉丁字母的序列,并在1秒内将其写入stdin。 使用C ++或Java很容易解决此问题。我在这里有python解决方案: 需要1.7秒: 结果是“超出时间限制”。因此,问题是“如何更快地做到这一点?” UPD1 :使用减少了16ms的时间。现在是1.740秒 UPD2: @Martijn P
本文向大家介绍用Java生成随机字符串,包括了用Java生成随机字符串的使用技巧和注意事项,需要的朋友参考一下 让我们首先声明一个字符串数组并初始化- 现在,创建一个Random对象- 生成随机字符串- 示例 输出结果 让我们再次运行它以获得不同的随机字符串-