Random vs SecureRandom

Teerayut Hiruntaraporn
2 min readJan 7, 2023

--

ในการเขียนโปรแกรม เมื่อเราต้องการที่จะสร้างความไม่แน่นอนของข้อมูล ฟังก์ชั่น Random ก็จะหนึ่งในตัวที่เราเลือกใช้

ซึ่งโดยปกติ ในแต่ละภาษาก็จะ มีฟังก์ชั่น Random อยู่ 2 แบบ คือ Random กับ Secure Random

จริงๆ ส่วนตัว หลังๆ แทบจะใช้ SecureRandom มาใช้งานตลอด ทำให้หลายครั้งก็หลงลืมไปว่า แล้วทำไมเขาต้องทำ function มาให้ 2 อันหว่า

เลยต้องไปหาข้อมูลกันหน่อย ว่า มันอะไรยังไง

Image by Freepik

คุณลักษณะ ของ Random vs SecureRandom

  1. Size — Random ใช้ข้อมูลขนาด 48 bit ขณะที่ SecureRandom ใช้ข้อมูลขนาด 128 bit
  2. Seed Generation — Random จะสร้าง Seed โดยใช้ System Clock ขณะที่ SecureRandom ข้อมูล random จาก OS (Entropy) ที่ /dev/random หรือ /dev/urandom
  3. Algorithm — ทั้งสอง ใช้สิ่งที่เรียกว่า Pseudo Random Number Generator (PRNG) แต่ SecureRandom จะเป็น PRNG ที่ ได้รับการการันตีว่าแข็งแรง พอสำหรับงานที่ต้องใช้การเข้ารหัส หรือ Cryptographically Strong PRNG ซึ่งในการที่จะเป็น CSPRNG ได้ ก็จะต้องมีการ comply ผ่าน มาตรฐาน เช่น การทดสอบ ของ FIP-140-2 ของ NIST
    ขณะที่ Random จะใช้ Algorithm ที่เรียกว่า subtractive random number generator ซึ่งให้ผลการมั่วที่ดี แต่เนื่องจากเป็น Algorithm ที่มีกฎเกณฑ์ที่ชัดเจน อาจจะทำให้สามารถ เดาค่าถัดไปได้

จากคุณลักษณะดังกล่าว ทำให้ผลของทั้ง คู่มีลักษณะดังนี้

  • Random — เบา เร็ว แต่ไม่ปลอดภัยในเชิง Crytographic
  • SecureRandom — ใหญ่ ช้า ปลอดภัยตาม มาตรฐาน Compliance ที่กำหนด

การทดสอบความเร็ว

เมื่อเราไปขอให้ ChatGPT Gen Code แล้ว ทดสอบให้ กับ เทสที่เครื่องตัวเอง จะได้ผล Benchmark ประมาณนี้

อันนี้เป็นโค้ดที่ใช้ทดสอบ จาก ChatGPT

import java.security.SecureRandom;
import java.util.Random;

public class RandomBenchmark {

private static final int NUM_ITERATIONS = 100000000;

public static void main(String[] args) {
long startTime = System.nanoTime();
Random random = new Random();
for (int i = 0; i < NUM_ITERATIONS; i++) {
random.nextInt();
}
long endTime = System.nanoTime();
long elapsedTime = endTime - startTime;
System.out.println("Random: Elapsed time: " + elapsedTime + " ns");

startTime = System.nanoTime();
SecureRandom secureRandom = new SecureRandom();
for (int i = 0; i < NUM_ITERATIONS; i++) {
secureRandom.nextInt();
}
endTime = System.nanoTime();
elapsedTime = endTime - startTime;
System.out.println("SecureRandom: Elapsed time: " + elapsedTime + " ns");
}
}

ข้อควรระวังสำหรับ การใช้ SecureRandom (Entropy)

เนื่องจาก การใช้ SecureRandom มีการใช้ Entropy จาก /dev/random หรือ มีสิ่งที่ต้องพึ่งระลึกไว้ โดยเฉพาะ กรณีที่ใช้ linux คือ

entropy เกิดจาก activity ที่ได้ขึ้นใน OS ซึ่งต้องมีปริมาณที่เพียงพอ ถึงจะสร้าง Random ขึ้นมาได้

นั่นแปลว่า ถ้าปริมาณ entropy ที่เกิดขึ้นไม่พอ ระบบจะ Block จนกว่า entropy จะครบ

ขณะที่ urandom แม้ว่าจะ ไม่ block แต่มันก็จะส่งในขณะที่ปริมาณ entropy ไม่ครบ นั่นหมายถึง ข้อมูลอาจจะน้อยเกินกว่าจะ random ได้ปลอดภัย

และมีข้อมูลว่า urandom มันจะ predict ได้ ถ้าไม่มีการ initialize pool ที่ดี

คำแนะนำในการใช้งาน

Random

เหมาะสำหรับ App ที่ไม่ซีเรียสกับเรื่อง Security มากนัก หรือ ใช้ function random ที่ไม่เกี่ยวข้องกับเรื่องเกี่ยวกับความปลอดภัย เช่น

  • Game / Simulation
  • Test Data สำหรับ Benchmark , Data Set, Machine Learning

SecureRandom

เหมาะสำหรับ App ที่ซีเรียสเรื่อง Security ซึ่งถ้า ซีเรียสจริงจัง ควรใช้ ผ่าน /dev/random ที่รับประกันปริมาณของ Entropy ที่เพียงพอในการ Random

อ้างอิง

  1. https://www.geeksforgeeks.org/random-vs-secure-random-numbers-java/
  2. https://stackoverflow.com/questions/11051205/difference-between-java-util-random-and-java-security-securerandom
  3. https://mattnworb.com/post/the-dangers-of-java-security-securerandom/
  4. https://en.wikipedia.org/wiki//dev/random#Linux
  5. https://gopherproxy.meulie.net/gopher.floodgap.com/0/archive/walnut-creek-cd-simtel/SIMTEL/SIGM/VOLS100/VOL148/RNDKNUTH.LIB
  6. ChatGPT, OpenAI
  7. https://www.kicksecure.com/wiki/Dev/Entropy

--

--

Teerayut Hiruntaraporn
Teerayut Hiruntaraporn

No responses yet