⚠️ สำคัญ: บทความต้นฉบับแนะนำใช้ MD5() ซึ่ง ไม่ปลอดภัยแล้วในปัจจุบัน (Broken, Fast, No Salt) ควรใช้ bcrypt, Argon2, หรือ PBKDF2 แทน
วิธีเก่า (ไม่แนะนำ) - ใช้ MD5()
CREATE TABLE UserNameAndPasswordDemo (
U_Id INT AUTO_INCREMENT PRIMARY KEY,
UserId VARCHAR(255) UNIQUE,
UserPassword VARCHAR(255)
);
-- เก็บ Password Hash ด้วย MD5
INSERT INTO UserNameAndPasswordDemo (UserId, UserPassword)
VALUES ('John@gg.com', MD5('john123'));
-- ผลลัพธ์: 6e0b7076126a29d5dfcbd54835387b7b (32 Hex Chars)
❌ ทำไม MD5 ไม่ปลอดภัย
- เร็วเกินไป - GPU คำนวณได้ Billions/sec
- ไม่มี Salt - Rainbow Table Attack ได้ง่าย
- มี Collision Vulnerability
- ถูก Deprecated สำหรับ Cryptographic Use
✅ วิธีที่แนะนำในปัจจุบัน
1. ใช้ bcrypt (PHP: password_hash, Node.js: bcrypt, Python: bcrypt)
-- Application Layer (ไม่ใช่ใน SQL)
$hash = password_hash('john123', PASSWORD_BCRYPT);
// ผลลัพธ์: $2y$10$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-- Verify
password_verify('john123', $hash); // true/false
2. ใช้ Argon2 (Winner Password Hashing Competition 2015)
-- PHP 7.2+
$hash = password_hash('john123', PASSWORD_ARGON2ID);
3. MySQL 8.0+ Built-in: SHA2 (ยังต้อง Salt เอง)
-- ดีกว่า MD5 แต่มันไม่ใช่ Password Hash Function
SELECT SHA2(CONCAT('salt', 'password'), 256);
Schema แนะนำสำหรับ Password Storage
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL, -- bcrypt: 60 chars, Argon2: ~97 chars
password_algo VARCHAR(20) DEFAULT 'bcrypt', -- บันทึก Algorithm ไว้เพื่อ Upgrade ภายหลัง
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Best Practice Checklist
- ✅ ใช้ Password Hashing Library (bcrypt/Argon2) ใน Application Layer
- ✅ ไม่เคยเก็บ Plain Text Password
- ✅ ใช้ Cost Factor ที่เหมาะสม (bcrypt cost 10-12, Argon2 memory/time)
- ✅ รองรับ Algorithm Migration (เก็บ Algo Name ไว้)
- ✅ ใช้ HTTPS เสมอ
- ✅ Implement Rate Limiting / Account Lockout