ขั้นตอนวิธี
ในการสร้างสตริงแบบสุ่มให้เชื่อมอักขระที่สุ่มจากชุดของสัญลักษณ์ที่ยอมรับได้จนกว่าสตริงจะมีความยาวตามที่ต้องการ
การดำเนินงาน
นี่คือรหัสที่ค่อนข้างง่ายและยืดหยุ่นมากสำหรับการสร้างตัวระบุแบบสุ่ม อ่านข้อมูลที่ตามมาสำหรับบันทึกย่อของแอปพลิเคชันที่สำคัญ
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 ในรูปแบบมาตรฐานใช้พื้นที่มาก: 36 ตัวอักษรสำหรับ entropy เพียง 122 บิต (ไม่ใช่ทุกบิตของ UUID ที่ "สุ่ม" จะถูกเลือกแบบสุ่ม) สตริงตัวอักษรและตัวเลขที่สุ่มเลือกนั้นจะบรรจุเอนโทรปีมากขึ้นด้วยอักขระเพียง 21 ตัว
UUID ไม่ยืดหยุ่น พวกเขามีโครงสร้างมาตรฐานและเค้าโครง นี่คือคุณธรรมหลักของพวกเขาเช่นเดียวกับจุดอ่อนหลักของพวกเขา เมื่อร่วมมือกับบุคคลภายนอกมาตรฐานที่เสนอโดย UUID อาจมีประโยชน์ สำหรับการใช้ภายในอย่างหมดจดพวกเขาสามารถไม่มีประสิทธิภาพ