연산
임의의 문자열을 생성하려면 문자열이 원하는 길이에 도달 할 때까지 허용되는 기호 세트에서 임의로 그려진 문자를 연결하십시오.
이행
다음은 임의 식별자를 생성하기위한 매우 간단하고 유연한 코드입니다. 중요한 응용 참고 사항에 대해서는 다음 정보를 읽으십시오 .
public class RandomString {
/**
* Generate a random string.
*/
public String nextString() {
for (int idx = 0; idx < buf.length; ++idx)
buf[idx] = symbols[random.nextInt(symbols.length)];
return new String(buf);
}
public static final String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static final String lower = upper.toLowerCase(Locale.ROOT);
public static final String digits = "0123456789";
public static final String alphanum = upper + lower + digits;
private final Random random;
private final char[] symbols;
private final char[] buf;
public RandomString(int length, Random random, String symbols) {
if (length < 1) throw new IllegalArgumentException();
if (symbols.length() < 2) throw new IllegalArgumentException();
this.random = Objects.requireNonNull(random);
this.symbols = symbols.toCharArray();
this.buf = new char[length];
}
/**
* Create an alphanumeric string generator.
*/
public RandomString(int length, Random random) {
this(length, random, alphanum);
}
/**
* Create an alphanumeric strings from a secure generator.
*/
public RandomString(int length) {
this(length, new SecureRandom());
}
/**
* Create session identifiers.
*/
public RandomString() {
this(21);
}
}
사용 예
8 자리 식별자에 대한 안전하지 않은 생성기를 만듭니다.
RandomString gen = new RandomString(8, ThreadLocalRandom.current());
세션 식별자를위한 보안 생성기를 만듭니다.
RandomString session = new RandomString();
읽기 쉬운 코드로 생성기를 생성하여 인쇄하십시오. 더 적은 수의 기호를 사용하기 위해 문자열이 전체 영숫자 문자열보다 깁니다.
String easy = RandomString.digits + "ACEFGHJKLMNPQRUVWXYabcdefhijkprstuvwx";
RandomString tickets = new RandomString(23, new SecureRandom(), easy);
세션 식별자로 사용
고유 할 수있는 세션 식별자를 생성하는 것만으로는 충분하지 않거나 간단한 카운터를 사용할 수 있습니다. 공격자는 예측 가능한 식별자가 사용될 때 세션을 가로 채습니다.
길이와 보안 사이에 긴장이 있습니다. 가능성이 적기 때문에 식별자가 짧을수록 추측하기 쉽습니다. 그러나 식별자가 길수록 더 많은 스토리지와 대역폭을 소비합니다. 더 큰 기호 집합이 도움이되지만 식별자가 URL에 포함되거나 직접 입력되면 인코딩 문제가 발생할 수 있습니다.
세션 식별자에 대한 기본 난수 또는 엔트로피 소스는 암호화를 위해 설계된 난수 생성기에서 가져와야합니다. 그러나 이러한 생성기의 초기화는 때때로 계산 비용이 많이 들거나 느릴 수 있으므로 가능하면 재사용하기 위해 노력해야합니다.
객체 식별자로 사용
모든 응용 프로그램에 보안이 필요한 것은 아닙니다. 무작위 할당은 여러 엔티티가 조정 또는 파티셔닝없이 공유 공간에서 식별자를 생성하는 효율적인 방법 일 수 있습니다. 특히 클러스터 또는 분산 환경에서 조정이 느려질 수 있으며 공간을 분할하면 엔터티가 너무 작거나 큰 공유로 끝날 때 문제가 발생합니다.
대부분의 웹 응용 프로그램에서와 같이 공격자가이를보고 조작 할 수있는 경우 예측할 수없는 조치를 취하지 않고 생성 된 식별자는 다른 방법으로 보호해야합니다. 액세스 권한없이 공격자가 식별자를 추측 할 수있는 개체를 보호하는 별도의 권한 부여 시스템이 있어야합니다.
예상되는 총 식별자 수를 고려할 때 충돌을 일으키지 않을 정도로 긴 식별자를 사용하도록주의를 기울여야합니다. 이것을 "생일 역설"이라고합니다. 충돌 확률 p 는 대략 n 2 / (2q x )이며, 여기서 n 은 실제로 생성 된 식별자의 수, q 는 알파벳의 고유 한 기호의 수, x 는 식별자의 길이입니다. 2-50 이하 의 매우 작은 숫자 여야합니다 .
이 작업을 수행하면 500k 15 자 식별자 간의 충돌 가능성이 약 2‑52 임을 알 수 있습니다. 이므로 우주 광선 등에서 감지되지 않은 오류보다 가능성이 적습니다.
UUID와 비교
사양에 따라 UUID 는 예측할 수 없도록 설계 되지 않았으므로 세션 식별자로 사용 해서는 안됩니다 .
표준 형식의 UUID는 많은 공간을 차지합니다. 122 비트 엔트로피의 경우 36 자입니다. "임의의"UUID의 모든 비트가 무작위로 선택되는 것은 아닙니다. 무작위로 선택한 영숫자 문자열은 21 자만으로 더 많은 엔트로피를 압축합니다.
UUID는 융통성이 없습니다. 그것들은 표준화 된 구조와 레이아웃을 가지고 있습니다. 이것이 그들의 주요 미덕이며 주요 약점입니다. 외부 당사자와 공동 작업 할 때 UUID에서 제공하는 표준화가 도움이 될 수 있습니다. 순전히 내부 사용의 경우 비효율적 일 수 있습니다.