Password Hashing คือการแปลง password เป็นค่าทิศทางเดียวที่ไม่ควรถอดกลับได้ โดย bcrypt เพิ่ม Salt และ Cost Factor เพื่อทำให้การเดารหัสผ่านจำนวนมากทำได้ยากขึ้น
%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#fabd2f", "primaryTextColor": "#282828", "primaryBorderColor": "#b57614", "lineColor": "#7c6f64", "secondaryColor": "#83a598", "tertiaryColor": "#b8bb26", "background": "#fbf1c7", "mainBkg": "#ebdbb2", "fontFamily": "Tahoma, sans-serif"}}}%%
flowchart LR
subgraph Era1["ยุค Plain Text / Unsafe Storage"]
A["Plain Password
รั่วแล้วใช้ได้ทันที"]
end
subgraph Era2["ยุค Fast Hash / Weak Hash"]
B["MD5/SHA1
เร็วเกินไปสำหรับ password"]
C["Rainbow Table
เดาจากตารางสำเร็จรูป"]
end
subgraph Era3["ยุค Password Hash / Adaptive Hash"]
D["Salt
ค่าสุ่มต่อ password"]
E["bcrypt Cost
ปรับความยากได้"]
end
A --> B --> C --> D --> E
bcrypt.hash(password, saltRounds)| วิธี | ถอดกลับได้ | เหมาะกับ Password | หมายเหตุ |
|---|---|---|---|
| Plain Text | ไม่ต้องถอด | ไม่เหมาะอย่างยิ่ง | เสี่ยงสูง |
| Encryption | ได้เมื่อมีกุญแจ | ไม่ควรใช้เป็นหลัก | เหมาะกับข้อมูลที่ต้องอ่านคืน |
| MD5/SHA1 | ไม่ได้ | ไม่เหมาะ | เร็วเกินไป |
| bcrypt | ไม่ได้ | เหมาะ | มี salt และ cost |
%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#fabd2f", "primaryTextColor": "#282828", "primaryBorderColor": "#b57614", "lineColor": "#7c6f64", "secondaryColor": "#83a598", "tertiaryColor": "#b8bb26", "background": "#fbf1c7", "mainBkg": "#ebdbb2", "fontFamily": "Tahoma, sans-serif"}}}%%
flowchart TD
A["Register
สมัครสมาชิก"] --> B["Plain Password
รหัสผ่านที่กรอก"]
B --> C["bcrypt.hash
hash + salt"]
C --> D["Store Hash
เก็บ hash"]
E["Login
เข้าสู่ระบบ"] --> F["bcrypt.compare
เทียบ input กับ hash"]
D --> F
F --> G{"Valid?
ถูกต้องไหม"}
G -->|Yes| H["Login Success
เข้าสู่ระบบสำเร็จ"]
G -->|No| I["Reject
ปฏิเสธ"]
// bcrypt-demo.mjs
// ตัวอย่างสมัครสมาชิกและ login ด้วย bcryptjs
import express from 'express';
import bcrypt from 'bcryptjs';
const app = express();
app.use(express.json());
const users = [];
const saltRounds = 12;
app.post('/register', async (req, res) => {
const { email, password } = req.body;
const passwordHash = await bcrypt.hash(password, saltRounds);
users.push({ id: Date.now(), email, passwordHash });
res.status(201).json({ message: 'registered' });
});
app.post('/login', async (req, res) => {
const { email, password } = req.body;
const user = users.find(item => item.email === email);
if (!user) return res.status(401).json({ message: 'invalid credentials' });
const ok = await bcrypt.compare(password, user.passwordHash);
if (!ok) return res.status(401).json({ message: 'invalid credentials' });
res.json({ message: 'login success' });
});
app.listen(3000, () => console.log('bcrypt demo on http://localhost:3000'));
// ตัวอย่างการใช้งาน:
// npm install express bcryptjs
// POST /register { "email": "ana@example.com", "password": "secret123" }
// POST /login { "email": "ana@example.com", "password": "secret123" }
saltRounds เป็น 10, 12 และสังเกตเวลาประมวลผล