IT General
น้องๆ เคยเจอปัญหาแบบผมไหม? สมัยทำร้านเน็ต SiamCafe ยุคแรกๆ ข้อมูลลูกค้าโดนแฮกประจำ! Username, password หลุดไปว่อนเน็ต คือตอนนั้นความรู้เรื่อง Security เราน้อยมาก คิดแค่ว่าลง Anti-Virus ก็จบเรื่อง แต่จริงๆ แล้วมันไม่ใช่เลย Cryptography นี่แหละคือพระเอกตัวจริงที่จะช่วยปกป้องข้อมูลของเรา
ผมจำได้เลย เคสที่เจ็บปวดที่สุดคือ Hacker ดึงข้อมูลบัตรเครดิตลูกค้าที่ใช้ซื้อชั่วโมงเล่นเกมไปได้ (สมัยนั้นยังไม่มีระบบ Payment Gateway ที่ปลอดภัยขนาดนี้) เสียหายกันไปเยอะมาก นั่นเป็นจุดเริ่มต้นที่ผมต้องศึกษา Cryptography อย่างจริงจัง เพราะรู้แล้วว่าการป้องกันข้อมูลแบบเดิมๆ มันเอาไม่อยู่
ตั้งแต่นั้นมา ผมก็เริ่มเอา Cryptography มาประยุกต์ใช้กับงานต่างๆ ไม่ว่าจะเป็นการเข้ารหัสฐานข้อมูลลูกค้า, การทำ VPN ให้พนักงานที่ทำงานจากบ้าน, หรือแม้แต่การเซ็นเอกสารอิเล็กทรอนิกส์ ทุกวันนี้ Cryptography กลายเป็นส่วนสำคัญในการทำงานของผมไปแล้ว
บทความนี้ผมจะมาแชร์ประสบการณ์และความรู้เรื่อง Cryptography ที่ผมสั่งสมมาตลอด 28 ปี หวังว่าจะเป็นประโยชน์กับน้องๆ ที่สนใจเรื่องนี้นะครับ
Cryptography ไม่ได้ยากอย่างที่คิดครับ จริงๆ มันคือศาสตร์ของการเข้ารหัส (Encryption) และถอดรหัส (Decryption) ข้อมูล เพื่อให้คนที่ไม่ได้รับอนุญาตไม่สามารถอ่านข้อมูลของเราได้ ลองนึกภาพว่าเรามีจดหมายลับส่งให้เพื่อน เราก็ต้องเข้ารหัสจดหมายนั้นก่อน เพื่อไม่ให้ใครอ่านได้ระหว่างทาง
Cryptography มีองค์ประกอบหลักๆ 3 อย่าง:
Cryptography มีหลายประเภท แต่ที่นิยมใช้กันหลักๆ คือ:
Symmetric-key Cryptography เป็นวิธีที่เร็วและมีประสิทธิภาพ แต่ข้อเสียคือเราต้องส่ง Key ให้กับผู้รับอย่างปลอดภัย ซึ่งเป็นเรื่องที่ท้าทายมาก สมัยผมทำร้านเน็ต ผมเคยใช้ DES ในการเข้ารหัส Username/Password ลูกค้า แต่สุดท้ายก็โดน Crack ได้ เพราะ Key มันถูกเก็บไว้ใน Code ของโปรแกรม (ซึ่ง Hacker สามารถ Decompile เอา Key ออกมาได้)
ตัวอย่างการใช้ AES (Advanced Encryption Standard) ใน Python:
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
import base64
def encrypt(plaintext, key):
cipher = AES.new(key, AES.MODE_EAX)
nonce = cipher.nonce
ciphertext, tag = cipher.encrypt_and_digest(plaintext.encode('utf-8'))
return nonce, ciphertext, tag
def decrypt(nonce, ciphertext, tag, key):
cipher = AES.new(key, AES.MODE_EAX, nonce=nonce)
plaintext = cipher.decrypt_and_verify(ciphertext, tag)
return plaintext.decode('utf-8')
# Example usage
key = get_random_bytes(16) # 16 bytes = 128 bits
plaintext = "This is a secret message!"
nonce, ciphertext, tag = encrypt(plaintext, key)
decrypted_text = decrypt(nonce, ciphertext, tag, key)
print("Plaintext:", plaintext)
print("Ciphertext:", base64.b64encode(ciphertext).decode('utf-8'))
print("Decrypted text:", decrypted_text)
ใน Code นี้ เราใช้ Library PyCryptodome ในการเข้ารหัสและถอดรหัสด้วย AES mode EAX ซึ่งมีความปลอดภัยสูง ข้อสำคัญคือ Key ต้องเป็นความลับและไม่ควรเก็บไว้ใน Code โดยตรง
Asymmetric-key Cryptography แก้ปัญหาเรื่องการส่ง Key ของ Symmetric-key Cryptography ได้ เพราะเราใช้ Public Key ในการเข้ารหัส (ซึ่งใครก็สามารถมีได้) และใช้ Private Key ในการถอดรหัส (ซึ่งมีแค่เราคนเดียว) แต่ข้อเสียคือมันช้ากว่า Symmetric-key Cryptography มาก
สมัยก่อนตอนผมติดตั้งระบบ VPN ให้ลูกค้า ผมใช้ OpenVPN ซึ่ง Support ทั้ง Symmetric และ Asymmetric Encryption ผมเลือกใช้ Asymmetric Encryption (RSA) เพราะมันปลอดภัยกว่า ถึงแม้จะช้ากว่านิดหน่อยก็ตาม
ตัวอย่างการ Generate RSA Key pair ด้วย OpenSSL:
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -pubout -out public.pem
จากนั้นเราก็สามารถใช้ Public Key (public.pem) ในการเข้ารหัส และใช้ Private Key (private.pem) ในการถอดรหัสได้
Hashing เป็นการแปลงข้อมูลให้เป็นค่า Hash ที่มีความยาวคงที่ และไม่สามารถย้อนกลับได้ (One-way function) เราใช้ Hashing ในการตรวจสอบความถูกต้องของข้อมูล เช่น การตรวจสอบว่า File ที่ Download มานั้นถูกต้อง ไม่มีการเปลี่ยนแปลง
ผมเคยเจอเคสนี้ตอนทำระบบ Backup ข้อมูลของลูกค้า ข้อมูลที่ Backup ไว้บางครั้งก็เกิดการ Corruption ผมเลยใช้ Hashing (SHA-256) ในการตรวจสอบความถูกต้องของข้อมูลหลัง Backup ทุกครั้ง ถ้า Hash ไม่ตรงกัน แสดงว่าข้อมูลมีการเปลี่ยนแปลง
ตัวอย่างการใช้ SHA-256 ใน Python:
import hashlib
data = "This is the data to be hashed."
hash_object = hashlib.sha256(data.encode('utf-8'))
hex_dig = hash_object.hexdigest()
print(hex_dig)
Code นี้จะ Generate ค่า SHA-256 Hash ของ String "This is the data to be hashed." ซึ่งเราสามารถนำค่า Hash นี้ไปเปรียบเทียบกับค่า Hash ของข้อมูลต้นฉบับ เพื่อตรวจสอบความถูกต้องได้
Cryptography Algorithm มีเยอะมากครับ แต่ที่ผมอยากแนะนำให้รู้จักคือ Algorithm ที่นิยมใช้กันในปัจจุบัน และมีแนวโน้มว่าจะยังคงใช้กันต่อไปในอนาคต
Algorithm ที่ผมใช้บ่อยๆ ได้แก่:
AES นี่ผมใช้มาตั้งแต่สมัยเรียน ป.โท จนถึงปัจจุบันก็ยังใช้อยู่ เพราะมันเร็วและปลอดภัย (ถ้าตั้งค่าถูกต้องนะ) AES มี Key size ให้เลือก 3 ขนาด คือ 128-bit, 192-bit และ 256-bit ยิ่ง Key size ใหญ่ขึ้น ความปลอดภัยก็ยิ่งสูงขึ้น แต่ก็ต้องแลกมาด้วย Performance ที่ลดลง
ตอนผมติดตั้งระบบ Storage ให้ลูกค้า ผมแนะนำให้ใช้ AES-256 ในการเข้ารหัสข้อมูลทั้งหมด เพราะข้อมูลของลูกค้ามีความสำคัญมาก และ AES-256 ก็เป็น Algorithm ที่มีความปลอดภัยสูงที่สุดในปัจจุบัน
RSA นี่ผมใช้ในการทำ Digital Signature บ่อยมาก Digital Signature คือการแนบลายเซ็นอิเล็กทรอนิกส์ไปกับเอกสาร เพื่อยืนยันว่าเอกสารนั้นมาจากเราจริงๆ และไม่มีการแก้ไข
เคยเจอเคสนี้ตอนทำระบบ e-Tax Invoice ให้บริษัทแห่งหนึ่ง บริษัทต้องการให้ e-Tax Invoice ที่ออกไปนั้นมีความน่าเชื่อถือ ผมเลยแนะนำให้ใช้ Digital Signature (RSA) ในการเซ็น e-Tax Invoice ทุกฉบับ
ECC นี่ผมเพิ่งเริ่มศึกษาจริงจังเมื่อไม่นานมานี้ เพราะเห็นว่ามันเหมาะกับ Mobile Device และ IoT Device ที่มีทรัพยากรจำกัด ECC มีขนาด Key ที่เล็กกว่า RSA แต่ให้ความปลอดภัยเทียบเท่ากัน ทำให้มันเหมาะกับ Device ที่ต้องการความปลอดภัยสูง แต่มี Power และ Memory จำกัด
ผมกำลังศึกษาการนำ ECC มาใช้กับระบบ Smart Home ของผม เพราะ Device ใน Smart Home ส่วนใหญ่มี CPU และ Memory ที่ไม่สูงมาก การใช้ ECC จะช่วยให้ระบบ Smart Home ของผมมีความปลอดภัยมากขึ้น โดยที่ไม่กระทบกับ Performance
bcrypt นี่ผมใช้มา X ปี บอกเลยว่าดีจริง! bcrypt เป็น Hashing Algorithm ที่ออกแบบมาสำหรับการ Hash Password โดยเฉพาะ จุดเด่นของ bcrypt คือ Slow Hashing ซึ่งทำให้การ Brute-force attack ทำได้ยากขึ้น
ตอนผมพัฒนา Web Application ผมจะใช้ bcrypt ในการ Hash Password ของ User เสมอ เพราะผมรู้ว่า Password เป็นข้อมูลที่สำคัญที่สุด และต้องปกป้องอย่างดีที่สุด
การเลือกใช้ Cryptography Algorithm ที่เหมาะสมขึ้นอยู่กับหลายปัจจัย เช่น ความสำคัญของข้อมูล, ข้อจำกัดด้าน Performance, และความซับซ้อนในการ Implement
ตารางนี้จะช่วยให้เห็นภาพรวมของการเลือกใช้ Algorithm ที่เหมาะสม:
| Algorithm | ประเภท | ข้อดี | ข้อเสีย | Use Case |
|---|---|---|---|---|
| AES | Symmetric | เร็ว, ปลอดภัย | ต้องส่ง Key อย่างปลอดภัย | เข้ารหัสข้อมูลทั่วไป, File Encryption, Disk Encryption |
| RSA | Asymmetric | ปลอดภัย, ใช้ทำ Digital Signature ได้ | ช้ากว่า Symmetric | เข้ารหัส Key, Digital Signature |
| ECC | Asymmetric | Key เล็ก, เหมาะกับ Mobile/IoT | ซับซ้อนกว่า RSA | เข้ารหัส Key ใน Mobile/IoT, Digital Signature ใน Mobile/IoT |
| SHA-256 | Hashing | ตรวจสอบความถูกต้องของข้อมูล | ไม่สามารถย้อนกลับได้ | ตรวจสอบความถูกต้องของ File, Integrity Check |
| bcrypt | Hashing | ป้องกัน Brute-force attack | ช้ากว่า Hash ทั่วไป | Hash Password |
โดยทั่วไปเราจะใช้ Symmetric Encryption ในการเข้ารหัสข้อมูลจำนวนมาก เพราะมันเร็วกว่า Asymmetric Encryption ส่วน Asymmetric Encryption เราจะใช้ในการเข้ารหัส Key ของ Symmetric Encryption หรือใช้ในการทำ Digital Signature
ตัวอย่างเช่น ถ้าเราต้องการส่ง File ขนาดใหญ่ให้เพื่อน เราจะใช้วิธี:
Key Management คือกระบวนการจัดการ Key ทั้งหมด ตั้งแต่การ Generate, การจัดเก็บ, การแจกจ่าย, การหมุนเวียน, และการทำลาย Key Key Management ที่ดีจะช่วยให้ระบบ Cryptography ของเรามีความปลอดภัยมากขึ้น
ตอนผมทำระบบ Security ให้ลูกค้าหลายราย ผมพบว่า Key Management เป็นเรื่องที่ถูกมองข้ามมากที่สุด หลายคนคิดว่าแค่เข้ารหัสข้อมูลก็จบ แต่จริงๆ แล้วการจัดการ Key สำคัญกว่าอีก
หลักการ Key Management ที่ผมแนะนำเสมอคือ:
Cryptography ไม่ได้อยู่แค่ในตำราครับ มันอยู่ในชีวิตประจำวันของเราทุกคน ตั้งแต่ตอนที่เราเข้า Website ที่มี HTTPS, ตอนที่เราใช้ Mobile Banking, หรือตอนที่เราส่ง Email
ผมจะยกตัวอย่างการใช้งาน Cryptography ในโลกจริงที่ผมเคยเจอมา:
HTTPS คือ Protocol ที่ใช้ในการเข้ารหัสข้อมูลระหว่าง Browser กับ Web Server โดยใช้ TLS/SSL (Transport Layer Security/Secure Sockets Layer) HTTPS ช่วยป้องกันไม่ให้ Hacker ดักจับข้อมูลระหว่างทาง เช่น Username, Password, หรือข้อมูลบัตรเครดิต
ถ้า Website ไหนไม่มี HTTPS ผมจะไม่เข้าเด็ดขาด เพราะมันอันตรายมาก
VPN (Virtual Private Network) คือการสร้าง Tunnel ที่เข้ารหัสระหว่าง Client กับ Server VPN ช่วยให้เราสามารถเข้าถึง Internet ได้อย่างปลอดภัย โดยเฉพาะเวลาที่เราใช้ Public Wi-Fi
ผมใช้ VPN เป็นประจำเวลาเดินทางไปต่างประเทศ เพราะผมไม่ไว้ใจ Public Wi-Fi เลย
Blockchain เป็น Technology ที่ใช้ในการเก็บข้อมูลแบบกระจายศูนย์ และมีความปลอดภัยสูง Blockchain ใช้ Hashing และ Digital Signature ในการรักษาความปลอดภัยของ Transaction
ผมกำลังศึกษาเรื่อง Blockchain อย่างจริงจัง เพราะผมเชื่อว่ามันจะเข้ามาเปลี่ยนแปลงโลกในอนาคต
หวังว่าบทความนี้จะเป็นประโยชน์กับน้องๆ นะครับ อย่าลืมแวะไปอ่านบทความอื่นๆ ใน SiamCafe Blog กันด้วยนะครับ
สุดท้ายนี้ ผมอยากฝากไว้ว่า Cryptography ไม่ใช่แค่เรื่องของ Algorithm แต่เป็นเรื่องของ Mindset ที่เราต้องตระหนักถึงความสำคัญของ Security และต้องพยายามปกป้องข้อมูลของเราอยู่เสมอ
หากมีข้อสงสัยเพิ่มเติม สามารถสอบถามได้เลยนะครับ ที่ SiamCafe Blog
ดูวิดีโอเพิ่มเติมเกี่ยวกับCryptography — คู่มือฉบับสมบูร:
GPG นี่เป็นเครื่องมือสารพัดประโยชน์เลยนะ สมัยผมทำร้านเน็ตนี่ใช้บ่อยมาก เอาไว้เข้ารหัสข้อมูลสำคัญพวก password, username หรือแม้กระทั่งไฟล์ config ต่างๆ ที่ไม่อยากให้ใครมาแอบดู
ขั้นตอนการใช้งานก็ไม่ได้ยากอย่างที่คิด ลองดูตามนี้เลย
sudo apt-get install gnupg หรือ sudo yum install gnupg ส่วน macOS ก็ brew install gnupggpg --gen-key แล้วก็ตอบคำถามไปตามที่มันถาม (ชื่อ, อีเมล, รหัสผ่าน) จำรหัสผ่านให้ดีนะ ห้ามลืมเด็ดขาด!gpg --armor --export [your_email] > public.key (เปลี่ยน [your_email] เป็นอีเมลที่เราใช้ตอนสร้าง key)secret.txt ที่อยากจะเข้ารหัส เราก็ใช้คำสั่ง gpg --encrypt --recipient [your_email] secret.txt (เปลี่ยน [your_email] เป็นอีเมลที่เราใช้ตอนสร้าง key) มันจะสร้างไฟล์ใหม่ชื่อ secret.txt.gpg ซึ่งเป็นไฟล์ที่ถูกเข้ารหัสแล้วgpg --decrypt secret.txt.gpg มันจะถามหารหัสผ่านที่เราตั้งไว้ตอนสร้าง key pair พอใส่รหัสผ่านถูกต้อง มันก็จะถอดรหัสไฟล์ออกมาเป็น secret.txtตัวอย่าง command จริง:
gpg --gen-key
gpg --armor --export yourname@example.com > public.key
gpg --encrypt --recipient yourname@example.com secret.txt
gpg --decrypt secret.txt.gpg
สมัยก่อนตอนที่ผมต้องดูแล server หลายสิบเครื่อง การใส่ password ทุกครั้งที่ SSH เข้าไปนี่เสียเวลามาก ผมเลยหันมาใช้ SSH key แทน สะดวกและปลอดภัยกว่าเยอะ
ขั้นตอนการสร้าง SSH key ก็ง่ายๆ:
ssh-keygen แล้วก็กด Enter ไปเรื่อยๆ มันจะสร้างไฟล์ id_rsa (private key) และ id_rsa.pub (public key) ไว้ใน directory ~/.sshssh-copy-id user@server_ip (เปลี่ยน user และ server_ip ให้ถูกต้อง) มันจะ copy public key ของเราไปไว้ในไฟล์ ~/.ssh/authorized_keys บน serverssh user@server_ip ถ้าทำทุกอย่างถูกต้อง มันจะไม่ถาม password แล้วตัวอย่าง command จริง:
ssh-keygen
ssh-copy-id user@192.168.1.100
ssh user@192.168.1.100
Configuration file ที่ ~/.ssh/config (Client-side):
Host my-server
HostName 192.168.1.100
User myuser
IdentityFile ~/.ssh/id_rsa
อันนี้เป็นตัวอย่าง config ง่ายๆ ที่ผมใช้บ่อยๆ จะได้ไม่ต้องพิมพ์ user@ip ทุกครั้ง
สมัยนี้ SSL/TLS นี่เป็นเรื่องพื้นฐานไปแล้ว เว็บไซต์ไหนไม่มี HTTPS นี่ดูไม่น่าเชื่อถือเลย ผมแนะนำให้ใช้ Let's Encrypt เลย ฟรีและใช้งานง่าย
ขั้นตอนการติดตั้งก็ขึ้นอยู่กับ web server ที่ใช้ แต่หลักๆ จะคล้ายๆ กัน:
sudo apt-get install certbot python3-certbot-nginx (สำหรับ Nginx บน Ubuntu) หรือ sudo yum install certbot python3-certbot-nginx (สำหรับ Nginx บน CentOS)sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com (เปลี่ยน yourdomain.com ให้เป็น domain ของเรา) มันจะถามคำถามนิดหน่อย ก็ตอบไปตามที่มันถามsudo systemctl restart nginxตัวอย่าง config Nginx ที่ Certbot generate ให้:
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://yourdomain.com$request_uri;
}
server {
listen 443 ssl;
server_name yourdomain.com www.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
# Your other configurations here
}
Certbot จะจัดการเรื่อง renewal certificate ให้เราด้วยนะ มันจะ renew certificate โดยอัตโนมัติก่อนที่ certificate จะหมดอายุ
Hash function นี่เป็นอะไรที่ผมใช้บ่อยมากเวลา download file จาก internet สมัยก่อน internet bandwidth ไม่ได้ดีเท่าสมัยนี้ ไฟล์เสียบ่อยมาก การใช้ hash function ช่วยให้เรามั่นใจได้ว่าไฟล์ที่เรา download มามันถูกต้อง ไม่ถูกแก้ไข
วิธีการใช้งาน SHA256 ก็ง่ายๆ:
sha256sum filename (เปลี่ยน filename เป็นชื่อไฟล์ที่เราต้องการ generate hash) มันจะแสดง SHA256 hash ของไฟล์ตัวอย่าง command จริง:
sha256sum myimage.iso
Output:
a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6 myimage.iso
ถ้า hash ที่เรา generate ได้ ตรงกับ hash ที่ผู้ให้บริการไฟล์ให้มา ก็สบายใจได้เลยว่าไฟล์ถูกต้อง
อย่าลืมว่า iCafeForex ให้ความสำคัญกับความปลอดภัยของข้อมูลลูกค้าเสมอ
เคยเจอเคสนี้ตอนทำโปรเจคให้ลูกค้า จำ passphrase ของ GPG key ไม่ได้! งานเข้าเลย
วิธีแก้: ถ้าจำไม่ได้จริงๆ คือจบเห่เลย ต้อง generate key pair ใหม่ แต่ถ้าพอจำได้ลางๆ ลองใช้ gpg --change-passphrase แล้วลองใส่ passphrase ที่พอจำได้ดู อาจจะฟลุ๊ค
วิธีป้องกัน: จด passphrase เก็บไว้ในที่ปลอดภัย หรือใช้ password manager ช่วยจำ
อันนี้เจอบ่อยมาก เวลา SSH เข้า server แล้ว connection timeout โดยเฉพาะ server ที่อยู่ต่างประเทศ
วิธีแก้:
/etc/ssh/ssh_config (client-side) เพิ่ม ServerAliveInterval 60 และ ServerAliveCountMax 3 เข้าไป/etc/ssh/sshd_config (server-side) เพิ่ม TCPKeepAlive yes และ ClientAliveInterval 60, ClientAliveCountMax 3 เข้าไป แล้ว restart SSH serviceตัวอย่าง config /etc/ssh/ssh_config:
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
ผมใช้ตัวนี้มา 10 ปี บอกเลยว่าช่วยแก้ปัญหา connection timeout ได้เยอะมาก
อันนี้เป็นปัญหา classic เลย certificate หมดอายุ เว็บไซต์เข้าไม่ได้
วิธีแก้:
sudo certbot renew เพื่อ renew certificateผมเคยเจอเคสที่ cron job ไม่ทำงาน เพราะ server time ไม่ถูกต้อง ทำให้ certificate หมดอายุไปก่อน ควรตั้งค่า timezone ให้ถูกต้องด้วย
ตัวอย่าง cron job ที่ run Certbot renew ทุกวันตอนตี 3:
0 3 * * * /usr/bin/certbot renew --quiet --no-self-upgrade
การตั้ง cron job จะช่วยให้เราไม่ต้องกังวลเรื่อง certificate หมดอายุอีกต่อไป
เรื่องนี้สำคัญมาก! สมัยผมทำร้านเน็ต SiamCafe เมื่อ 20 กว่าปีก่อน ตอนนั้นยังไม่ค่อยมีใครรู้จัก SSL/TLS เท่าไหร่ แต่พอเริ่มมี e-commerce ผมก็เริ่มศึกษาเรื่องนี้จริงจัง แล้วพบว่า algorithm แต่ละตัวมันมีข้อดีข้อเสียต่างกัน
อย่าง DES นี่เก่ามาก เร็วก็จริง แต่ไม่ปลอดภัยแล้ว สมัยนี้ต้อง AES ไปเลย หรือถ้าเน้น asymmetric encryption ก็ RSA หรือ ECC แต่ ECC จะแรงกว่าถ้า key length เท่ากัน
เคยเจอเคสลูกค้าทำระบบ payment gateway เลือกใช้ RSA key length สั้นเกินไป โดน brute-force attack ได้ง่ายๆ ผมเลยแนะนำให้เปลี่ยนไปใช้ ECC (Elliptic Curve Cryptography) 256-bit แทน ปลอดภัยขึ้นเยอะ แถมประมวลผลเร็วกว่าเดิมด้วย
อันนี้เจอบ่อยมาก! หลายคนชอบเก็บ password แบบ plain text หรือไม่ก็ hash อย่างเดียว ซึ่งอันตรายสุดๆ ถ้า database หลุด hacker เอาไป crack แป๊บเดียวก็รู้ password หมด
หลักการง่ายๆ คือต้องใส่ salt (random string) เข้าไปก่อน hash ทุกครั้ง แล้วเก็บ salt ไว้ใน database ด้วย เวลา verify password ก็เอา salt ของ user นั้นมาใส่ก่อน hash แล้วเทียบกับ hash ที่เก็บไว้
import hashlib, os
def hash_password(password):
salt = os.urandom(16) # Generate random salt
salted_password = salt + password.encode('utf-8')
hashed_password = hashlib.sha256(salted_password).hexdigest()
return salt.hex() + ":" + hashed_password
def verify_password(password, stored_hash):
salt, hash = stored_hash.split(":")
salt = bytes.fromhex(salt)
salted_password = salt + password.encode('utf-8')
hashed_password = hashlib.sha256(salted_password).hexdigest()
return hashed_password == hash
# Example Usage
hashed_password = hash_password("mysecretpassword")
print(hashed_password)
is_correct = verify_password("mysecretpassword", hashed_password)
print(is_correct) # Output: True
สมัยผมเขียนเว็บให้ลูกค้า ผมใช้ bcrypt หรือ Argon2 ไปเลย พวกนี้มันออกแบบมาให้ slow ทำให้ brute-force ยากขึ้นเยอะ
เรื่อง key management นี่สำคัญสุดๆ เคยเจอเคสลูกค้าทำ e-commerce เก็บ private key ไว้ใน source code บน GitHub! อันตรายมาก
วิธีที่ถูกต้องคือต้องเก็บ private key ไว้ใน hardware security module (HSM) หรือ cloud KMS (Key Management Service) อย่าง AWS KMS หรือ Google Cloud KMS พวกนี้มันจะช่วย protect key ไม่ให้หลุดออกไปง่ายๆ
ถ้าเป็นพวก certificate authority (CA) นี่ต้องยิ่งระวังเป็นพิเศษ เพราะ private key ของ CA ถ้าหลุดไปนี่คือจบเลย ใครๆ ก็สามารถออก certificate ปลอมได้
Software ทุกอย่างมี bug ครับ ยิ่ง library หรือ framework ที่ใช้ cryptography ด้วยแล้ว ต้อง update บ่อยๆ เพราะ security vulnerability มันเจอเรื่อยๆ
สมัยผมทำระบบ security ให้ธนาคารแห่งหนึ่ง ผมต้อง monitor CVE (Common Vulnerabilities and Exposures) ตลอดเวลา ถ้าเจอ vulnerability ใน library ที่เราใช้ ต้องรีบ patch ทันที
เคยเจอเคส Apache Struts โดนเจาะ เพราะไม่ได้ update patch security ช่องโหว่นี้ ทำให้ hacker เข้ามา execute arbitrary code ได้
สมัยนี้ HTTPS เป็น default แล้วครับ ไม่ควรมีเว็บไหนที่ไม่ใช้ TLS อีกต่อไป เพราะมันไม่ปลอดภัยเลย
ตอนผมติดตั้งระบบให้ลูกค้า ผมจะบังคับ redirect ทุก traffic ไปที่ HTTPS เลย และใช้ HSTS (HTTP Strict Transport Security) เพื่อป้องกัน man-in-the-middle attack
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
# SSL Configuration (example)
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
# HSTS Configuration
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
}
นอกจากนี้ยังต้อง config TLS ให้ secure ด้วย cipher suite ต้องเลือกตัวที่แข็งแรง และ disable พวก cipher เก่าๆ ที่ไม่ปลอดภัยแล้ว
Hashing คือ one-way function คือแปลงข้อมูลไปแล้ว แปลงกลับไม่ได้ ใช้สำหรับเก็บ password หรือ verify integrity ของไฟล์ ส่วน Encryption คือ two-way function คือแปลงข้อมูลไปแล้ว สามารถแปลงกลับได้ ใช้สำหรับ protect confidential data
Salt คือ random string ที่เอามาใส่ก่อน hash password เพื่อป้องกัน rainbow table attack ซึ่งเป็น technique ที่ hacker ใช้ crack password ที่ hash ด้วย algorithm ที่อ่อนแอ ถ้าใช้ salt ที่ unique สำหรับแต่ละ user rainbow table จะใช้ไม่ได้ผล
AES เป็น symmetric encryption เร็วกว่า RSA (asymmetric encryption) มาก แต่ RSA ใช้สำหรับ key exchange ได้ดีกว่า โดยปกติจะใช้ RSA หรือ ECC ในการแลกเปลี่ยน key แล้วใช้ AES ในการ encrypt data ที่เหลือ
ปัจจุบัน AES ควรใช้ 128-bit ขึ้นไป RSA ควรใช้ 2048-bit ขึ้นไป ECC ควรใช้ 256-bit ขึ้นไป ยิ่ง key length ยาวเท่าไหร่ ก็ยิ่งปลอดภัย แต่ก็เปลือง resource มากขึ้น
ถ้า private key หลุด ต้อง revoke certificate ทันที และ generate key pair ใหม่ แล้วออก certificate ใหม่ นอกจากนี้ต้องตรวจสอบ log file เพื่อดูว่ามีใครใช้ key ที่หลุดไปทำอะไรบ้าง
Cryptography ไม่ใช่เรื่องยาก แต่ก็ไม่ใช่เรื่องง่าย ต้องเข้าใจหลักการทำงานของ algorithm แต่ละตัว และต้อง implement ให้ถูกต้องตาม best practices ที่สำคัญคือต้อง update ความรู้ตลอดเวลา เพราะ security landscape มันเปลี่ยนไปเรื่อยๆ
ถ้าใครอยากศึกษาเรื่อง cryptography เพิ่มเติม ผมแนะนำให้อ่านหนังสือ "Cryptography and Network Security" ของ William Stallings หรือไม่ก็ลองเล่น CTF (Capture The Flag) ดู จะได้ฝึกมือจริงๆ SiamCafe Blog มีบทความเกี่ยวกับ security อีกเยอะ ลองเข้าไปอ่านดูได้
สำหรับ step ถัดไป ลองศึกษาเรื่อง post-quantum cryptography ดูครับ เพราะ quantum computer จะมา disrupt cryptography ในอนาคตอันใกล้นี้แน่นอน