Python Secrets Module to Generate secure random data

#Code4Sec Week #Day5 #NEIS0736 #NECS0736

ตั้งแต่ Python เวอร์ชั่น 3.6 ได้มีการเปิดตัว Secrets Module สำหรับสร้างข้อมูลแบบสุ่มที่มีความแข็งแรงและปลอดภัย เราจะมาเรียนรู้วิธีใช้ secret.SystemRandom() และ secrets.token() เพื่อทำการสร้าง random data ที่มีความมั่งคงปลอดภัย โดยก่อนหน้า Python เวอร์ชั่น 3.6 เรามีการใช้งาน os.urandom() และ random.SystemRandom() เพื่อสร้างข้อมูลแบบสุ่มที่มีความปลอดภัย

Secrets module ทำงานแบบ Cryptographically Secure Pseudorandom Number Generator (CSPRNG) เป็นการสร้างตัวเลข Pseudo-Random ที่มีการเข้ารหัสที่แข็งแรงใช้เพื่อสร้างข้อมูลสุ่มซึ่งปลอดภัยและมีประโยชน์ในแอปพลิเคชันที่ต้องการความปลอดภัย โดยอ้างอิงจาก PEP - 0506 ที่ออกแบบมาเพื่อเพิ่ม Secrets Module เป็น library มาตรฐานใน Python และมีการสร้างข้อมูลแบบสุ่มโดยใช้ synchronization methods เพื่อให้แน่ใจว่าไม่มี process ใดที่สามารถรับข้อมูลเดียวกันในเวลาเดียวกันได้

ตัวอย่างการใช้งานทั่วไปของ secrets module ที่เกี่ยวข้อง

Secrets module ทำงานอยู่บน os.urandom() และ random.SystemRandom() ซึ่งอาศัยการทำงานจาก Operating system เป็นหลัก เช่น

Random numbers

Class secrets.SystemRandom

เป็น class สำหรับสร้างตัวเลขสุ่มโดยใช้ highest-quality sources ที่ระบบปฏิบัติการได้จัดเตรียมไว้ โดยเมื่อเรียกใช้งาน secrets.SystemRandom class เราก็จะสามารถใช้งานฟังก์ชั่นทั้งหมดของ random module ได้เลย

ตัวอย่าง class secrets.SystemRandom

secrets.choice(sequence)

Return ค่า randomly ที่ถูกเลือกจาก non-empty sequence

import secrets

code4secGenerator = secrets.SystemRandom()
# Secure Random choice using secrets
number_list = [6, 12, 18, 24, 30, 36, 42, 48, 54, 60]
secure_choice = code4secGenerator.choice(number_list)
print("code4secGenerator choice -> ", secure_choice)

Result:

code4secGenerator choice ->  54

secrets.randrange(n)

Return ค่า random แบบ integer ระหว่าง 0 ถึง n

import secrets

code4secGenerator = secrets.SystemRandom()

secure_choice = code4secGenerator.randrange(100)
print("code4secGenerator randbelow -> ", secure_choice)

Result:

code4secGenerator randbelow ->  7

Generating tokens

Secrets module มีฟังก์ชั่นสำหรับการสร้าง Token ที่ปลอดภัยสำหรับ application ที่ต้องการใช้งาน เช่น password resets, hard-to-guess URLs เป็นต้น

ตัวอย่างการ generate tokens

secrets.token_bytes([nbytes=None])

Return ค่า random รูปแบบ byte string ที่มีข้อมูลขนาด n bytes

import secrets

token = secrets.token_bytes(32)
print(token)

Result:

b'\xe3\x87v\x9a\x08\xd1\xd5*\xe28\x9c\x8fwm4\xd8\xb3\xee\x01\t\x05T\xd4I\xda\x93\xf8\t\x10\x98\xc1{'

secrets.token_hex([nbytes=None])

Return ค่า random ของ text string ในรูปแบบฐาน 16 (hexadecimal) ที่มีข้อมูลขนาด nbytes random bytes โดยในแต่ละ byte ถูกเปลี่ยนเป็น 2 Hex digits

Result:

1a36840ddb095370c37e477161f2fa1eb400e48be4ca97f0a314d1099840b165

secrets.token_urlsafe([nbytes=None])

Return ค่า random ของ URL-safe ในรูปแบบ text string ที่มีข้อมูลขนาด n bytes โดยถูก encoded แบบ Base64

import secrets

url = 'https://code4sec.com/reset=' + secrets.token_urlsafe()
print(url)

Result:

https://code4sec.com/reset=VgZIgKN97sDsfhSQ14M5mG84hkIyLGHcfy_cXFp_7WQ

Token ควรใช้ขนาดกี่ byte ?

เพื่อความปลอดภัยจากการโจมตีด้วย brute-force attacks ต้องมีขนาดการสุ่มอย่างเพียงพอเนื่องจากปัจจุบัน computer มีประสิทธิภาพในการเดาและถอดรหัสมากขึ้น ตั้งแต่ปี ค.ศ.2015 ยังเชื่อกันว่าการสุ่มขนาด 32 bytes (256 bits) นั้นเพียงพอสำหรับกรณีการใช้งานทั่วไปที่ถูกคาดการณ์ไว้สำหรับ secrets module

Reference:

Author:

Ekawut Chairat