فصل ۳: رمزنگاری و رمزگذاری
تاریخچه رمزنگاری، رمزنگاری متقارن (AES) و نامتقارن (RSA، ECC، Diffie-Hellman)، توابع hash، امضای دیجیتال، PKI، handshake در TLS 1.3 و تمرین عملی با GPG.
تاریخچهٔ مختصر رمزنگاری
رمزنگاری (Cryptography) علم نگهداری از اطلاعات در حضور مهاجم است. تاریخچهٔ آن به بیش از ۴۰۰۰ سال پیش و استفادهٔ مصریان باستان از هیروگلیف تغییر یافته برمیگردد. رمز سزار (Caesar Cipher) جابجایی حروف الفبا را میتوان سادهترین رمز متقارن دانست. در جنگ جهانی دوم، ماشین انیگما (Enigma) آلمانها و تلاشهای آلن تورینگ در بلچلی پارک، نقطهٔ عطفی در تاریخ رمزنگاری و رایانه بود.
در دوران مدرن، با ظهور کامپیوترها و اینترنت، رمزنگاری از حالت نظامی به حوزهٔ روزمره وارد شد. استاندارد DES در ۱۹۷۷، AES در ۲۰۰۱، و منحنیهای بیضوی (ECC) در دههٔ ۲۰۰۰، پایههای امروز را بنا نهادند.
اصل Kerckhoffs
بهگفتهٔ آگوست کرکوفس در ۱۸۸۳: «امنیت یک سیستم رمزنگاری نباید به مخفیماندن الگوریتم وابسته باشد، بلکه فقط به مخفیماندن کلید.» به همین دلیل AES، RSA و SHA عمومی هستند؛ مخفی بودن کلید است که امنیت میآورد.
رمزنگاری متقارن (Symmetric)
در رمزنگاری متقارن، فرستنده و گیرنده از یک کلید مشترک استفاده میکنند. مزیت اصلی سرعت بالاست؛ معایب اصلی، مشکل توزیع کلید است.
الگوریتمهای شناختهشده
- DES (Data Encryption Standard): کلید ۵۶ بیتی؛ از ۲۰۰۵ منسوخ اعلام شده. امروز در کمتر از ۲۴ ساعت با سختافزار تخصصی شکسته میشود.
- 3DES: سهبار DES؛ کند و منسوخ.
- AES-128/192/256: استاندارد فعلی؛ سریع و امن. AES-256 برای دادههای طبقهبندیشدهٔ Top Secret توسط NSA تأیید شده.
- Blowfish / Twofish: جایگزینهای آزاد AES؛ Twofish فینالیست رقابت AES بود.
- ChaCha20: جریانمحور و سریع در دستگاههای بدون شتابدهنده سختافزاری؛ استفاده در TLS و WireGuard.
مثال: رمزگذاری AES با Python
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.backends import default_backend
import os
key = os.urandom(32) # AES-256
iv = os.urandom(16)
padder = padding.PKCS7(128).padder()
padded = padder.update(b"secret message") + padder.finalize()
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
encryptor = cipher.encryptor()
ciphertext = encryptor.update(padded) + encryptor.finalize()
print(ciphertext.hex())هرگز IV را دوباره استفاده نکنید
در حالت CBC، استفادهٔ مجدد از Initialization Vector با همان کلید، نشت اطلاعات جدی ایجاد میکند. برای هر رمزگذاری یک IV تصادفی جدید تولید کنید. در حالت GCM، تکرار nonce فاجعهبار است و کل کلید را لو میدهد.
رمزنگاری نامتقارن (Asymmetric)
رمزنگاری نامتقارن از یک جفت کلید استفاده میکند: کلید عمومی برای رمزگذاری و کلید خصوصی برای رمزگشایی. این الگوریتمها کندتر از متقارن هستند، اما مشکل توزیع کلید را حل میکنند.
الگوریتمهای کلیدی
- RSA: بر پایهٔ سختی تجزیهٔ اعداد بزرگ. کلیدهای ۲۰۴۸ بیتی حداقل امروزی؛ ۴۰۹۶ بیتی برای امنیت بلندمدت پیشنهاد میشود.
- ECC (Elliptic Curve Cryptography): با کلید ۲۵۶ بیتی امنیتی معادل RSA 3072 دارد؛ ایدهآل برای موبایل و IoT.
- Diffie-Hellman (DH): تبادل کلید بدون نیاز به کانال امن؛ پایهٔ Forward Secrecy در TLS.
- Ed25519: امضای دیجیتال سریع و امن؛ در SSH و Signal استفاده میشود.
مثال: تبادل کلید Diffie-Hellman
from cryptography.hazmat.primitives.asymmetric import x25519
# Alice
alice_private = x25519.X25519PrivateKey.generate()
alice_public = alice_private.public_key()
# Bob
bob_private = x25519.X25519PrivateKey.generate()
bob_public = bob_private.public_key()
# هر دو به یک shared secret یکسان میرسند
alice_shared = alice_private.exchange(bob_public)
bob_shared = bob_private.exchange(alice_public)
assert alice_shared == bob_shared # Trueتوابع درهمساز (Hash)
Hash یکطرفه است: ورودی هر اندازه را به خروجی با طول ثابت تبدیل میکند. کاربرد اصلی: تأیید یکپارچگی و ذخیرهٔ رمز عبور.
| الگوریتم | طول خروجی | وضعیت امنیتی |
|---|---|---|
| MD5 | ۱۲۸ بیت | شکسته — فقط برای checksum غیرامنیتی |
| SHA-1 | ۱۶۰ بیت | شکسته — منسوخ |
| SHA-256 | ۲۵۶ بیت | امن — استاندارد فعلی |
| SHA-3 | ۲۲۴ تا ۵۱۲ بیت | امن — ساختار متفاوت |
| bcrypt | ۱۸۴ بیت | برای رمز عبور — کند عمدی |
| scrypt | متغیر | برای رمز عبور — memory-hard |
| Argon2 | متغیر | برندهٔ Password Hashing Competition 2015 |
هرگز MD5 یا SHA-1 برای امنیت
MD5 از ۲۰۰۴ بهطور کامل شکسته شد و collision در کمتر از یک ثانیه ساخته میشود. SHA-1 نیز در ۲۰۱۷ با حملهٔ SHAttered شکسته شد. از این دو فقط برای fingerprint غیرامنیتی استفاده کنید، هرگز برای رمز عبور، گواهی دیجیتال یا امضا.
ذخیرهٔ رمز عبور با bcrypt
import bcrypt
password = b"my_secret_password"
# هش کردن با salt خودکار
hashed = bcrypt.hashpw(password, bcrypt.gensalt(rounds=14))
print(hashed.decode())
# تأیید
if bcrypt.checkpw(password, hashed):
print("رمز صحیح است")پارامتر rounds هزینهٔ محاسباتی را تعیین میکند؛ ۱۴ امروزی، اما هر دو سال با افزایش قدرت سختافزار باید افزایش یابد.
امضای دیجیتال و گواهیها
امضای دیجیتال ترکیب hash و رمزنگاری نامتقارن است: فرستنده hash پیام را با کلید خصوصی خود امضا میکند و گیرنده با کلید عمومی فرستنده صحت را بررسی میکند. این کار اصالت، یکپارچگی و عدمانکار را همزمان تأمین میکند.
PKI و X.509
زیرساخت کلید عمومی (PKI) شامل سه بازیگر اصلی است:
- CA (Certificate Authority): مرجع صدور گواهی، مانند Let's Encrypt یا DigiCert.
- گواهی X.509: فایلی که کلید عمومی یک سرور را با هویتش متصل میکند.
- Chain of Trust: گواهی سرور توسط CA میانی امضا میشود و آن نیز توسط CA ریشهای.
مرورگر شما مجموعهای از CAهای ریشهٔ مورداعتماد را دارد و اگر گواهی سایت با هیچکدام تطبیق نیابد، هشدار میدهد.
handshake در TLS 1.3
TLS 1.3 سادهشدهٔ نسخههای قبلی است و handshake در یک رفتوبرگشت انجام میشود:
1. Client Hello
Client به Server: ciphers مورد پشتیبانی، key share (ECDHE)، random
2. Server Hello
Server به Client: انتخاب cipher، key share، گواهی، امضای handshake
3. Client
بررسی گواهی → محاسبه shared secret → Finished (رمزگذاریشده)
4. Application Data (هر دو طرف کلید مشترک دارند)TLS 1.3 از Forward Secrecy استفاده میکند: اگر کلید خصوصی سرور در آینده لو برود، ترافیک گذشته قابل رمزگشایی نیست.
مقایسهٔ الگوریتمها
| الگوریتم | نوع | کلید | سرعت | کاربرد |
|---|---|---|---|---|
| AES-256 | متقارن | ۲۵۶ بیت | سریع | رمزگذاری داده |
| ChaCha20 | متقارن | ۲۵۶ بیت | سریع (نرمافزاری) | TLS، WireGuard |
| RSA-2048 | نامتقارن | ۲۰۴۸ بیت | کند | امضا، تبادل کلید |
| ECC P-256 | نامتقارن | ۲۵۶ بیت | متوسط | موبایل، IoT |
| Ed25519 | نامتقارن | ۲۵۶ بیت | سریع | امضای SSH |
| SHA-256 | Hash | — | سریع | یکپارچگی |
| Argon2id | Password Hash | — | کند عمدی | رمز عبور |
تمرین عملی: رمزگذاری فایل با GPG
GnuPG ابزار استاندارد رمزنگاری فایل و ایمیل است. رمزگذاری متقارن یک فایل:
# رمزگذاری با AES-256 و درخواست passphrase
gpg --symmetric --cipher-algo AES256 secret.txt
# خروجی: secret.txt.gpg
# رمزگشایی
gpg --decrypt secret.txt.gpg > secret.txt
# عبارت عبور پرسیده میشود
# رمزگذاری نامتقارن با کلید عمومی گیرنده
gpg --encrypt --recipient alice@example.com secret.txt
# امضای دیجیتال
gpg --sign secret.txt
# امضا و رمزگذاری همزمان
gpg --sign --encrypt --recipient alice@example.com secret.txtبرای تولید کلید شخصی:
gpg --full-generate-key
# انتخاب: (9) ECC and ECC
# الگوریتم: Curve25519
# مدت اعتبار: 2y
# لیست کلیدهای خصوصی
gpg --list-secret-keys
# صادرات کلید عمومی برای اشتراک با دیگران
gpg --armor --export alice@example.com > alice_public.ascاصول کلید GPG
کلید خصوصی GPG باید در حافظهٔ رمزگزار (smartcard) یا حداقل با passphrase قوی محافظت شود. هرگز آن را در GitHub یا سرویس اشتراک فایل قرار ندهید. برای مصارف حساس، از زیرکلید (subkey) روی YubiKey استفاده کنید.
خلاصه و گام بعدی
در این فصل با تاریخچه، انواع رمزنگاری متقارن و نامتقارن، توابع hash، امضای دیجیتال، PKI و handshake TLS آشنا شدید. بهخاطر داشته باشید: AES-256 برای داده، RSA 2048+ یا ECC برای تبادل کلید، SHA-256+ برای hash، و Argon2 برای رمز عبور.
در فصل بعد به احراز هویت و دسترسی میپردازیم؛ اولین خط دفاعی هر سیستم.
این صفحه در تاریخ ۸ تیر ۱۴۰۵ بهروزرسانی شده است.