Thuật toán
Để tạo một chuỗi ngẫu nhiên, nối các ký tự được vẽ ngẫu nhiên từ tập hợp các ký hiệu được chấp nhận cho đến khi chuỗi đạt đến độ dài mong muốn.
Thực hiện
Đây là một số mã khá đơn giản và rất linh hoạt để tạo các định danh ngẫu nhiên. Đọc thông tin sau đây cho các ghi chú ứng dụng quan trọng.
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);
}
}
Ví dụ sử dụng
Tạo trình tạo không an toàn cho số nhận dạng 8 ký tự:
RandomString gen = new RandomString(8, ThreadLocalRandom.current());
Tạo một trình tạo an toàn cho các định danh phiên:
RandomString session = new RandomString();
Tạo một trình tạo với các mã dễ đọc để in. Các chuỗi dài hơn các chuỗi chữ và số đầy đủ để bù cho việc sử dụng ít ký hiệu hơn:
String easy = RandomString.digits + "ACEFGHJKLMNPQRUVWXYabcdefhijkprstuvwx";
RandomString tickets = new RandomString(23, new SecureRandom(), easy);
Sử dụng làm định danh phiên
Tạo các mã định danh phiên có khả năng là duy nhất là không đủ hoặc bạn chỉ có thể sử dụng một bộ đếm đơn giản. Kẻ tấn công chiếm quyền điều khiển phiên khi định danh dự đoán được sử dụng.
Có sự căng thẳng giữa chiều dài và an ninh. Các định danh ngắn hơn sẽ dễ đoán hơn, vì có ít khả năng hơn. Nhưng định danh dài hơn tiêu thụ nhiều lưu trữ và băng thông hơn. Một bộ ký hiệu lớn hơn sẽ giúp, nhưng có thể gây ra sự cố mã hóa nếu số nhận dạng được bao gồm trong URL hoặc nhập lại bằng tay.
Nguồn ngẫu nhiên cơ bản, hoặc entropy, cho các định danh phiên nên đến từ một trình tạo số ngẫu nhiên được thiết kế cho mật mã. Tuy nhiên, việc khởi tạo các máy phát này đôi khi có thể tốn kém về mặt tính toán hoặc chậm, vì vậy cần nỗ lực để sử dụng lại chúng khi có thể.
Sử dụng làm định danh đối tượng
Không phải mọi ứng dụng đều yêu cầu bảo mật. Việc gán ngẫu nhiên có thể là một cách hiệu quả để nhiều thực thể tạo ra các định danh trong một không gian chung mà không có bất kỳ sự phối hợp hay phân vùng nào. Phối hợp có thể chậm, đặc biệt là trong một môi trường phân cụm hoặc phân tán và việc phân tách một không gian gây ra vấn đề khi các thực thể kết thúc với các cổ phần quá nhỏ hoặc quá lớn.
Các định danh được tạo mà không thực hiện các biện pháp khiến chúng không thể đoán trước được nên được bảo vệ bằng các phương tiện khác nếu kẻ tấn công có thể xem và thao tác chúng, như xảy ra trong hầu hết các ứng dụng web. Cần có một hệ thống ủy quyền riêng biệt để bảo vệ các đối tượng mà kẻ nhận dạng có thể đoán được kẻ tấn công mà không có quyền truy cập.
Cũng cần phải chú ý sử dụng các số nhận dạng đủ dài để khiến các va chạm không thể xảy ra với tổng số lượng định danh dự đoán. Điều này được gọi là "nghịch lý sinh nhật." Xác suất va chạm, p , xấp xỉ n 2 / (2q x ), trong đó n là số lượng định danh thực sự được tạo ra, q là số ký hiệu riêng biệt trong bảng chữ cái và x là chiều dài của mã định danh. Đây phải là một số rất nhỏ, như 2 ‑50 hoặc ít hơn.
Làm việc này cho thấy khả năng va chạm giữa các số nhận dạng 500k 15 ký tự là khoảng 2 ‑52 , có lẽ ít xảy ra hơn các lỗi không được phát hiện từ các tia vũ trụ, v.v.
So sánh với UUID
Theo đặc điểm kỹ thuật của họ, UUID không được thiết kế để không thể đoán trước và không nên được sử dụng làm định danh phiên.
Các UUID ở định dạng chuẩn của chúng chiếm rất nhiều dung lượng: 36 ký tự chỉ cho 122 bit entropy. (Không phải tất cả các bit của UUID "ngẫu nhiên" đều được chọn ngẫu nhiên.) Một chuỗi ký tự chữ và số được chọn ngẫu nhiên có nhiều entropy hơn chỉ trong 21 ký tự.
UUID không linh hoạt; họ có một cấu trúc và bố cục tiêu chuẩn. Đây là đức tính chính của họ cũng như điểm yếu chính của họ. Khi hợp tác với một bên ngoài, tiêu chuẩn hóa được cung cấp bởi UUID có thể hữu ích. Để sử dụng hoàn toàn nội bộ, chúng có thể không hiệu quả.