如何有效地在Java中生成安全的随机字母数字字符串?

dev*_*von 18 java security algorithm performance

如何有效地在Java中生成安全的随机(或伪随机)字母数字字符串?

JB *_*zet 22

初始化包含所有接受的字符(CHARS_ARRAY)的数组,然后实例化SecureRandom实例,并nextInt(CHARS_ARRAY.length)重复调用以获取char数组中的随机索引.将每个字符附加到a,StringBuilder直到获得预期的字符数.

  • +1 是将生成的字符串限制为定义的字符列表的好方法。 (3认同)

Nal*_*iba 10

如果您使用Apache Commons Lang,最简单的方法是

RandomStringUtils.random(20, 0, 0, true, true, null, new SecureRandom());
Run Code Online (Sandbox Code Playgroud)

  • @ninjaxelite 为什么?他使用 SecureRandom 作为种子,随机性来自新的 SecureRandom(),请看这里:https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/RandomStringUtils.html (6认同)
  • 引用的注释指的是 RandomStringUtils 使用的默认随机源,即“Random”。答案是通过明确设计并旨在覆盖默认实例的方法提供“SecureRandom”实例 (4认同)

eri*_*son 5

这是重复问题中我的代码的略微修改版本

public final class RandomString
{

  /* Assign a string that contains the set of characters you allow. */
  private static final String symbols = "ABCDEFGJKLMNPRSTUVWXYZ0123456789"; 

  private final Random random = new SecureRandom();

  private final char[] buf;

  public RandomString(int length)
  {
    if (length < 1)
      throw new IllegalArgumentException("length < 1: " + length);
    buf = new char[length];
  }

  public String nextString()
  {
    for (int idx = 0; idx < buf.length; ++idx) 
      buf[idx] = symbols.charAt(random.nextInt(symbols.length()));
    return new String(buf);
  }

}
Run Code Online (Sandbox Code Playgroud)


Chl*_*loe 5

    String chrs = "0123456789abcdefghijklmnopqrstuvwxyz-_ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    SecureRandom secureRandom = SecureRandom.getInstanceStrong();
    // 9 is the length of the string you want
    String customTag = secureRandom.ints(9, 0, chrs.length()).mapToObj(i -> chrs.charAt(i))
      .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append).toString();
    System.out.println(customTag);
Run Code Online (Sandbox Code Playgroud)

例子:

// q3HX6EctP
// WjRrMjQT4
// sX-Piq4DB
Run Code Online (Sandbox Code Playgroud)


Mau*_*res 1

使用UUID

UUID random = UUID.randomUUID();
System.out.println( random );
Run Code Online (Sandbox Code Playgroud)

  • UUID 具有足够的随机性,足以避免意外冲突。然而,它们不能用于安全性,它们无法抵御主动尝试猜测值的攻击者。 (17认同)
  • 长度不是 UUID/GUID 的问题。使用“加密强度高的 RNG”生成的 128 位就可以了(例如 SecureRandom)。问题是“随机”必须是密码随机的。GUIDS 可以使用多种算法生成,并且不保证加密安全。例如:http://stackoverflow.com/questions/3652944/how-securely-unguessable-are-guids (4认同)
  • 这是一个很好的答案。Java的UUID使用java.security.SecureRandom和java.security.provider.SecureRandom...这里的可预测性被大大夸大了。某些 JVM 的 impl 可能不如 Sun/Oracle OOTB 的那么好... (4认同)
  • 甚至定义 UUID 的 RFC 也说“不要假设 UUID 很难猜测;它们不应该被用作安全功能”http://tools.ietf.org/html/rfc4122 (3认同)
  • [UUID.randomUUID()](https://docs.oracle.com/javase/8/docs/api/java/util/UUID.html#randomUUID()) 的文档指定它使用加密的强伪随机数字生成器。 (2认同)