การเข้ารหัส (Encrypt) และถอดรหัส (Decrypt) ข้อมูลใน Python ด้วยไลบรารี่ cryptography ที่สร้างบนอัลกอริทึม AES แบบ Symmetric Encryption (Key เดียวกัน)
ติดตั้ง Library
pip install cryptography
1. สร้างและจัดการ Key
from cryptography.fernet import Fernet
def generate_key():
"""สร้าง Key ใหม่และบันทึกลงไฟล์"""
key = Fernet.generate_key()
with open("secret.key", "wb") as key_file:
key_file.write(key)
print("Key generated and saved to secret.key")
return key
def load_key():
"""โหลด Key จากไฟล์"""
return open("secret.key", "rb").read()
# ใช้งาน
# key = generate_key() # รันครั้งแรกเท่านั้น
key = load_key() # รันครั้งต่อๆ ไป
⚠️ คำเตือนสำคัญ: Key ต้องเก็บรักษาไว้ให้ปลอดภัย! หากสูญหาย จะถอดรหัสข้อมูลที่เข้ารหัสด้วย Key นั้นไม่ได้
2. เข้ารหัสข้อมูล (Encrypt)
def encrypt_message(message: str, key: bytes) -> bytes:
"""เข้ารหัสข้อความ คืนค่า bytes"""
f = Fernet(key)
encoded_message = message.encode() # String → bytes
encrypted = f.encrypt(encoded_message)
return encrypted
# ใช้งาน
key = load_key()
encrypted = encrypt_message("Secret message", key)
print(encrypted) # b'gAAAAABl7...'
3. ถอดรหัสข้อมูล (Decrypt)
def decrypt_message(encrypted_message: bytes, key: bytes) -> str:
"""ถอดรหัสข้อมูล คืนค่า String"""
f = Fernet(key)
decrypted = f.decrypt(encrypted_message)
return decrypted.decode() # bytes → String
# ใช้งาน
decrypted = decrypt_message(encrypted, key)
print(decrypted) # "Secret message"
4. ตัวอย่างเต็ม รันได้
from cryptography.fernet import Fernet
import os
KEY_FILE = "secret.key"
def generate_or_load_key():
if os.path.exists(KEY_FILE):
return open(KEY_FILE, "rb").read()
else:
key = Fernet.generate_key()
with open(KEY_FILE, "wb") as f:
f.write(key)
return key
def encrypt(message: str) -> str:
key = generate_or_load_key()
f = Fernet(key)
return f.encrypt(message.encode()).decode() # คืนค่า String (Base64)
def decrypt(token: str) -> str:
key = generate_or_load_key()
f = Fernet(key)
return f.decrypt(token.encode()).decode()
if __name__ == "__main__":
# Demo
original = "My secret password 123!"
print(f"Original: {original}")
encrypted = encrypt(original)
print(f"Encrypted: {encrypted}")
decrypted = decrypt(encrypted)
print(f"Decrypted: {decrypted}")
assert original == decrypted
print("✅ Success!")
5. เข้ารหัสไฟล์ (File Encryption)
def encrypt_file(input_path: str, output_path: str, key: bytes):
f = Fernet(key)
with open(input_path, "rb") as file:
file_data = file.read()
encrypted_data = f.encrypt(file_data)
with open(output_path, "wb") as file:
file.write(encrypted_data)
def decrypt_file(input_path: str, output_path: str, key: bytes):
f = Fernet(key)
with open(input_path, "rb") as file:
encrypted_data = file.read()
decrypted_data = f.decrypt(encrypted_data)
with open(output_path, "wb") as file:
file.write(decrypted_data)
Best Practices
- 🔐 Key Management: ไม่ควร Hardcode Key ในโค้ด ใช้ Environment Variable หรือ Key Management Service (AWS KMS, HashiCorp Vault)
- 🔄 Key Rotation: เปลี่ยน Key เป็นระยะ และ Re-encrypt ข้อมูลเก่า
- 📝 Authenticated Encryption: Fernet ให้ Integrity + Confidentiality (ป้องกัน Tampering)
- 🗑️ Memory: ล้างตัวแปรที่เก็บ Plaintext หลังใช้งาน (
del variable)
Common Errors
| Error | สาเหตุ | แก้ไข |
|---|---|---|
| InvalidToken | Key ผิด / ข้อมูลเสียหาย / Token ถูกแก้ไข | ตรวจสอบ Key, ข้อมูลไม่ถูกแก้ไข |
| TypeError: expected bytes | ส่ง String เข้า encrypt/decrypt | ใช้ .encode() / .decode() ให้ถูกต้อง |
| FileNotFoundError | หา secret.key ไม่เจอ | รัน generate_key() ก่อน หรือเช็ค Path |