رمز عبور، هش و رمزنگاری
چرا رمز عبور نباید ذخیره شود و بهجایش چه نگه داشته میشود: هش بهعنوان اثر انگشت یکطرفه با sha256sum، بررسی سلامت فایل دانلودی، چرا هش ساده برای رمز کافی نیست، نمک (salt) و هش کند، فرمت /etc/shadow، فرق encoding و هش و رمزنگاری، رمزنگاری متقارن با openssl، کلید عمومی و خصوصی، و حساب کردن قدرت یک رمز.
- حدود ۲۴ دقیقه مطالعه
- ۷ مثال اجراشده
- ۳ تمرین با جواب
- مقدماتی (از صفر مطلق)
- بهروزرسانی: ۲۹ مهر ۱۴۰۵
توی این درس یاد میگیری سایتها چطور رمز تو را چک میکنند بدون اینکه خود رمز را نگه دارند. با هش آشنا میشوی (اثر انگشت یکطرفهی هر داده) و با sha256sum با آن کار میکنی، میفهمی چرا هش ساده برای رمز کافی نیست و نمک (salt) و هش کند چه مشکلی را حل میکنند، سه چیزی را که همه قاطی میکنند از هم جدا میکنی (encoding، هش و رمزنگاری)، یک فایل را با openssl رمزنگاری و باز میکنی و ایدهی کلید عمومی و خصوصی را که پایهی HTTPS و SSH است میشناسی. در آخر حساب میکنی یک رمز واقعاً چقدر قوی است.
مسئله: دیتابیسی که لو میرود
Section titled “مسئله: دیتابیسی که لو میرود”هر چند وقت یک بار خبر میرسد: «اطلاعات میلیونها کاربر فلان سایت فاش شد». فرض کن دیتابیس سایتی که در آن عضوی، کامل دست کسی بیفتد. اگر رمزها همانطور که تایپ شدهاند ذخیره شده باشند، مهاجم رمز همه را دارد و چون خیلیها یک رمز را همهجا استفاده میکنند، با همان رمز سراغ ایمیل و بانک و شبکههای اجتماعیشان میرود. سؤال این است: سایت چطور میتواند بفهمد رمزی که الان وارد کردی درست است، بدون اینکه رمز درست را جایی نوشته باشد؟
تشبیه: اثر انگشت
Section titled “تشبیه: اثر انگشت”هش مثل اثر انگشت یک داده است. از روی یک آدم میشود اثر انگشتش را گرفت، ولی از روی اثر انگشت نمیشود خود آدم را ساخت. دو آدم متفاوت (تقریباً) هیچوقت اثر انگشت یکسان ندارند، و یک آدم همیشه همان اثر انگشت را دارد. برای ورود به ساختمان، نگهبان لازم نیست خود تو را در کشو نگه دارد؛ اثر انگشتت را در پرونده دارد و هر بار انگشتت را با آن مقایسه میکند.
سایتها با رمز همین کار را میکنند: موقع ثبتنام هش رمز را ذخیره میکنند، و موقع ورود، از رمزی که تایپ کردی دوباره هش میگیرند و دو هش را مقایسه میکنند. خود رمز هیچجا نیست.
مثالهای عملی
Section titled “مثالهای عملی”مثال ۱: اولین هش
Section titled “مثال ۱: اولین هش”printf 'سلام' | sha256sumprintf 'سلام' | sha256sumprintf 'سلام!' | sha256sumprintf 'a' | sha256sumbda1fa48345336618741fd2c4bc02809eb099c49a9b02fb5056401ab6d4dc3e6 -bda1fa48345336618741fd2c4bc02809eb099c49a9b02fb5056401ab6d4dc3e6 -903c0515c0763a585585cdbe653ad9217a1b330dd35239e4c5a589190eb24969 -ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb -(printf متن را بدون خط جدید آخر میدهد و | آن را به sha256sum میدهد. - یعنی ورودی از pipe آمد، نه فایل.) SHA-256 یکی از رایجترین تابعهای هش است. چهار ویژگی را همینجا میبینی:
- همیشه یکسان: یک ورودی، همیشه همان هش (خط ۱ و ۲).
- اندازهی ثابت: ۶۴ رقم هگز = ۳۲ بایت = ۲۵۶ بیت (اسمش از همین است؛ درس بیت و بایت)، چه ورودی یک حرف باشد چه یک فیلم.
- اثر بهمنی: یک
!اضافه، هشی کاملاً متفاوت ساخت. هیچ شباهتی نمانده که نشان دهد ورودیها نزدیک بودند. - یکطرفه: از
bda1fa48...هیچ راهی برای رسیدن به «سلام» نیست، جز حدس زدن ورودیها و هش گرفتن از هر کدام.
مثال ۲: هش یک فایل، و بررسی دانلود
Section titled “مثال ۲: هش یک فایل، و بررسی دانلود”هش فقط برای رمز نیست. یک فایل ۱۰ مگابایتی بساز و هشش را بگیر:
head -c 10000000 /dev/zero > big.binls -l big.binsha256sum big.bin-rw-r--r-- 1 ali ali 10000000 Oct 22 00:30 big.binf5e02aa71e67f41d79023a128ca35bad86cf7b6656967bfe0884b3a3c4325eaf big.bin(/dev/zero یک «فایل» بیانتهای صفر است و head -c ده میلیون بایت از آن برمیدارد.) ده میلیون بایت، باز هم ۶۴ رقم. اگر حتی یک بیت از فایل عوض شود، هش کاملاً عوض میشود. برای همین سایتهایی که فایل نصب (مثلاً ISO اوبونتو) میدهند، هش آن را هم کنارش مینویسند (فایلی به اسم SHA256SUMS). بعد از دانلود هش بگیر و مقایسه کن: اگر یکی بود، فایل سالم و دستنخورده به تو رسیده؛ نه خراب شده، نه کسی وسط راه چیزی در آن جا داده.
مثال ۳: چرا هش ساده برای رمز کافی نیست
Section titled “مثال ۳: چرا هش ساده برای رمز کافی نیست”printf '123456' | sha256sum8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 -این هش را در یک موتور جستوجو بزن: در ثانیهی اول میبینی مال 123456 است. مهاجمها جدولهای عظیمی از «رمزهای رایج و هششان» دارند. دو مشکل دیگر هم هست:
- همهی کسانی که رمز
123456دارند، هش یکسان دارند. مهاجم با یک نگاه به دیتابیس میفهمد ده هزار نفر یک رمز دارند و با شکستن یکی، همه را دارد. - SHA-256 خیلی سریع است. برای فایل خوب است، برای رمز بد. ببین یک کامپیوتر معمولی (و فقط با پایتون، که کند است) در یک ثانیه چند هش میسازد:
python3 -c "import hashlib, timen = 1_000_000t = time.perf_counter()for i in range(n): hashlib.sha256(str(i).encode()).hexdigest()print(f'{n} sha256 in {time.perf_counter() - t:.2f} s')"1000000 sha256 in 0.96 sیک میلیون حدس در یک ثانیه، با پایتون روی یک هسته. کارت گرافیکهایی که برای شکستن رمز استفاده میشوند، دهها میلیارد در ثانیه میزنند. با این سرعت، هر رمز ۸ حرفی در چند ساعت امتحان میشود (مثال ۷).
مثال ۴: نمک و هش کند
Section titled “مثال ۴: نمک و هش کند”دو راهحل، با هم:
- نمک (salt): یک رشتهی تصادفی که برای هر کاربر جدا ساخته میشود و قبل از هش به رمز چسبانده میشود. حالا دو کاربر با رمز
123456دو هش متفاوت دارند و جدولهای آمادهی مهاجم بیفایدهاند. نمک محرمانه نیست؛ کنار هش ذخیره میشود. کارش فقط یکتا کردن است. - هش کند: تابعهایی که عمداً کند و حافظهخورند (bcrypt، scrypt، Argon2، yescrypt). برای کاربر، صبر کردن ۰٫۱ ثانیه موقع ورود اهمیتی ندارد؛ برای مهاجمی که میلیاردها حدس لازم دارد، یعنی میلیونها برابر کندتر.
openssl passwd هش نمکدار به همان شکلی که لینوکس استفاده میکند میسازد:
openssl passwd -6 '123456'openssl passwd -6 '123456'$6$Bm.s0qhRapEHxeU0$Wz5rMnOhvvxxJ50P3XsWUFNFRKZ7U/KwCI51Ekbdm.dQucDQ5G/99CrW4molKvPdJfy9Q76RUXJSsSsSq99Dk1$6$qGXQRnnwESYKKPiE$jShlpqk8FwFY.OBQfj6X4SIQW6IFri/rQp3BQsiA3FvH5r19MuhCCzzwd6mfwuVSyB.UK7/563r.FrLTZRDZc0یک رمز، دو هش کاملاً متفاوت (برای تو هم متفاوتاند؛ نمک تصادفی است). قالب با $ سه بخش دارد: 6 نوع الگوریتم (SHA-512 با هزاران دور تکرار)، Bm.s0qhRapEHxeU0 نمک، و بقیه خود هش. برای چک کردن رمز، سیستم نمک را از همین رشته برمیدارد، رمز واردشده را با همان نمک هش میکند و مقایسه میکند. اگر نمک را دستی بدهی، نتیجه همیشه همان است:
openssl passwd -6 -salt Xk3pQ9aB '123456'openssl passwd -6 -salt Xk3pQ9aB '123456'$6$Xk3pQ9aB$tKCyKhygrHw4fGfGAlzht.vDSi8zNiAHWSfoZ/Wbhko48uuTgJcHZJgJKXU.Erd.Xh.LS4XMblXL4yMkXNoxY1$6$Xk3pQ9aB$tKCyKhygrHw4fGfGAlzht.vDSi8zNiAHWSfoZ/Wbhko48uuTgJcHZJgJKXU.Erd.Xh.LS4XMblXL4yMkXNoxY1و یک هش واقعاً کند، scrypt:
python3 -c "import hashlib, timet = time.perf_counter()hashlib.scrypt(b'123456', salt=b'random-salt-1234', n=2**14, r=8, p=1)print(f'1 scrypt in {time.perf_counter() - t:.3f} s')"1 scrypt in 0.049 sیک هش در ۵۰ میلیثانیه، در برابر یک میلیون SHA-256 در یک ثانیه: حدود ۵۰ هزار برابر کندتر، و چون هر کدام ۱۶ مگابایت حافظه میخواهد، کارت گرافیک هم کمک زیادی نمیکند. همین عدد را تنظیم میکنی تا با سختافزار جدیدتر هم کند بماند.
مثال ۵: رمزهای لینوکس کجا هستند؟
Section titled “مثال ۵: رمزهای لینوکس کجا هستند؟”لینوکس رمز کاربرها را در /etc/shadow نگه میدارد، فایلی که فقط مدیر سیستم میتواند بخواند (درس سیستمعامل دیدی cat /etc/shadow برای کاربر معمولی Permission denied میدهد):
sudo grep "^$USER:" /etc/shadowali:$y$j9T$Hq3s0x8pR0ZcVvXo1rN2n/$Jt8CqgN7mU0w8b3Wl6yC2vF0xSx9QnB4pA1dE5r7kQ.:20380:0:99999:7:::همان قالب $نوع$نمک$هش، این بار با y یعنی yescrypt: هش کند و حافظهخوری که اوبونتو از نسخهی ۲۲٫۰۴ به بعد استفاده میکند. (ستونهای بعد از : تاریخ آخرین تغییر رمز و قوانین انقضا هستند؛ دورهی لینوکس.) حتی مدیر سیستم هم رمز تو را نمیبیند؛ فقط میتواند آن را عوض کند.
دو کاربر رمز یکسان دارند ولی در /etc/shadow هشهایشان کاملاً متفاوت است. چرا؟
جواب درست: هر کاربر نمک تصادفی خودش را دارد
نمک فرق دارد، پس هش فرق دارد؛ با همان نمک، هش همیشه یکسان است.
مثال ۶: encoding، هش، رمزنگاری؛ سه چیز متفاوت
Section titled “مثال ۶: encoding، هش، رمزنگاری؛ سه چیز متفاوت”این سه را خیلیها قاطی میکنند و اشتباه گرفتنشان باعث نشت داده میشود:
echo -n "salam" | base64echo "c2FsYW0=" | base64 -d; echoc2FsYW0=salamBase64 یک encoding است (مثل UTF-8 در درس متن): داده را به حرفهای قابلچاپ تبدیل میکند تا از جاهایی که فقط متن قبول میکنند (ایمیل، JSON، URL) رد شود. هیچ امنیتی ندارد: هر کس با یک دستور برش میگرداند. اگر در یک فایل تنظیمات «رمز» را به شکل UzNjdXJlLVBhc3M= دیدی، آن رمز رمزنگاری نشده؛ فقط لباس عوض کرده.
رمزنگاری (encryption) داده را با یک کلید طوری درهم میکند که فقط کسی که کلید را دارد بتواند برش گرداند. یک فایل محرمانه را با رمزنگاری AES (رایجترین الگوریتم متقارن) قفل کن:
echo "قرارداد محرمانه: مبلغ ۴۰۰ میلیون" > secret.txtopenssl enc -aes-256-cbc -pbkdf2 -salt -in secret.txt -out secret.enc -pass pass:'Long-Pass-2026'ls -l secret.txt secret.encfile secret.enchead -c 32 secret.enc | od -c | head -2-rw-r--r-- 1 ali ali 80 Oct 22 00:30 secret.enc-rw-r--r-- 1 ali ali 60 Oct 22 00:30 secret.txtsecret.enc: openssl enc'd data with salted password0000000 S a l t e d _ _ 352 363 ^ 242 016 a 8 `0000020 ( 7 302 m i \f 256 352 ] 374 361 001 ( Y 030 gفایل رمزنگاریشده با Salted__ و نمک شروع میشود و بقیهاش بایتهای بیمعنی است (od -c بایتها را نشان میدهد؛ عددها برای تو فرق میکنند). -pbkdf2 یعنی از رمز تو با یک هش کند کلید واقعی AES ساخته شود. باز کردنش:
openssl enc -d -aes-256-cbc -pbkdf2 -in secret.enc -pass pass:'Long-Pass-2026'openssl enc -d -aes-256-cbc -pbkdf2 -in secret.enc -out /dev/null -pass pass:'wrong'echo "exit=$?"قرارداد محرمانه: مبلغ ۴۰۰ میلیونbad decrypt4077F77DF67F0000:error:1C800064:Provider routines:ossl_cipher_unpadblock:bad decrypt:../providers/implementations/ciphers/ciphercommon_block.c:124:exit=1با کلید درست، متن برگشت؛ با کلید غلط، bad decrypt. (در عمل رمز را در خط فرمان ننویس؛ در تاریخچهی ترمینال میماند. بدون -pass، openssl رمز را بیصدا میپرسد.)
| برمیگردد؟ | کلید لازم؟ | کاربرد | |
|---|---|---|---|
| Encoding (Base64، UTF-8) | بله، برای همه | نه | سازگاری؛ امنیت صفر |
| هش (SHA-256، yescrypt) | نه | نه | رمز عبور، بررسی سلامت |
| رمزنگاری (AES، RSA) | بله، فقط با کلید | بله | محرمانه نگه داشتن |
مثال ۷: یک رمز چقدر قوی است؟
Section titled “مثال ۷: یک رمز چقدر قوی است؟”قدرت رمز یعنی تعداد حالتهایی که مهاجم باید امتحان کند: (تعداد حرفهای ممکن) به توان (طول). این برنامهی کوچک (crack.py) بدترین حالت را برای دو سرعت حساب میکند: هش سریع با ده میلیارد حدس در ثانیه، و هش کند با ده هزار:
import math
def human(seconds): for unit, size in [("سال", 365 * 86400), ("روز", 86400), ("ساعت", 3600), ("دقیقه", 60)]: if seconds >= size: return f"{seconds / size:,.0f} {unit}" return "کمتر از یک دقیقه"
cases = [ ("PIN چهاررقمی", 10, 4), ("۸ حرف کوچک", 26, 8), ("۸ حرف بزرگ و کوچک و رقم", 62, 8), ("۱۲ حرف بزرگ و کوچک و رقم", 62, 12), ("۵ کلمهی تصادفی از ۷۷۷۶", 7776, 5),]print(f"{'رمز':28} {'بیت':>5} {'هش سریع':>16} {'هش کند':>18}")for name, alphabet, length in cases: combos = alphabet ** length print(f"{name:28} {math.log2(combos):5.1f} {human(combos / 1e10):>16} {human(combos / 1e4):>18}")python3 crack.pyرمز بیت هش سریع هش کندPIN چهاررقمی 13.3 کمتر از یک دقیقه کمتر از یک دقیقه۸ حرف کوچک 37.6 کمتر از یک دقیقه 242 روز۸ حرف بزرگ و کوچک و رقم 47.6 6 ساعت 692 سال۱۲ حرف بزرگ و کوچک و رقم 71.5 10,230 سال 10,230,424,792 سال۵ کلمهی تصادفی از ۷۷۷۶ 64.6 90 سال 90,151,852 سالدرسهای این جدول:
- طول از هر چیز مهمتر است. از ۸ به ۱۲ حرف رفتن، شش ساعت را به ده هزار سال رساند. هر حرف اضافه، حالتها را ۶۲ برابر میکند (توان!).
- هش کند (کار سایت) همان رمز ضعیف را از چند ساعت به چند صد سال میرساند. ولی رمز خیلی ضعیف (PIN) را هیچ چیز نجات نمیدهد.
- ستون «بیت» همان عدد را به زبان درس بیت و بایت میگوید: log2 تعداد حالتها. ۸۰ بیت به بالا امروز قوی حساب میشود.
- اینها برای رمز تصادفی است.
Ali1370هشت حرف است، ولی در فهرستهای رمزهای رایج و «اسم + سال تولد» در چند ثانیه پیدا میشود. آدمها در ساختن رمز تصادفی خیلی بدند؛ برای همین مدیر رمز (password manager) رمز را میسازد و نگه میدارد.
پشت پرده: کلید عمومی و خصوصی
Section titled “پشت پرده: کلید عمومی و خصوصی”رمزنگاری مثال ۶ متقارن است: یک کلید برای قفل و باز کردن. مشکلش این است که کلید را چطور به طرف مقابل برسانی؟ اگر از همان شبکه بفرستی، هر کس وسط راه کلید را میبیند.
راهحل، رمزنگاری نامتقارن (کلید عمومی) است: هر کس یک جفت کلید دارد که با هم ساخته میشوند. کلید عمومی مثل یک قفل باز است که میتوانی هزار نسخه از آن را به همه بدهی: هر کس میتواند با آن چیزی را قفل کند. کلید خصوصی تنها کلیدی است که آن قفل را باز میکند و هرگز از دست تو بیرون نمیرود. کسی که قفل باز تو را دارد، میتواند برایت پیام قفلشده بفرستد، ولی خودش هم نمیتواند بازش کند.
همین جفت، برعکس هم کار میکند: چیزی که با کلید خصوصی «امضا» شود، همه میتوانند با کلید عمومی بررسی کنند که واقعاً از صاحب کلید آمده. به این امضای دیجیتال میگویند.
این دو ایده را در درسهای بعدی و دورههای دیگر مدام میبینی:
- SSH: کلید عمومیات را روی سرور میگذاری؛ سرور با آن ثابت میکند که کلید خصوصی دست توست، بدون اینکه رمزی رد و بدل شود (دورهی لینوکس، درس SSH).
- HTTPS: سرور با کلید خصوصیاش ثابت میکند واقعاً
bank.irاست و با کمک کلید عمومی، یک کلید متقارن موقت با مرورگر توافق میکند تا بقیهی گفتوگو سریع رمزنگاری شود (درس بعد).
جدولهای مرجع
Section titled “جدولهای مرجع”| دستور | کار |
|---|---|
sha256sum file |
هش یک فایل |
printf 'text' | sha256sum |
هش یک متن |
sha256sum -c SHA256SUMS |
بررسی هش فایلهای دانلودی |
openssl passwd -6 'pass' |
هش نمکدار به قالب لینوکس |
base64 / base64 -d |
encoding (نه امنیت!) |
openssl enc -aes-256-cbc -pbkdf2 -in f -out f.enc |
رمزنگاری فایل |
openssl enc -d -aes-256-cbc -pbkdf2 -in f.enc |
باز کردن |
| اصطلاح | معنی |
|---|---|
| hash | اثر انگشت یکطرفه و ثابتاندازه |
| salt | رشتهی تصادفی برای یکتا کردن هش هر کاربر |
| bcrypt / scrypt / Argon2 / yescrypt | هشهای عمداً کند برای رمز |
| symmetric | یک کلید برای قفل و باز کردن (AES) |
| asymmetric | جفت کلید عمومی و خصوصی (RSA، Ed25519) |
| signature | امضا با کلید خصوصی، بررسی با کلید عمومی |
اشتباهات رایج
Section titled “اشتباهات رایج”۱) ذخیرهی رمز بهصورت متن یا Base64
Section titled “۱) ذخیرهی رمز بهصورت متن یا Base64”سناریوی درس. راهحل: فقط هش کند و نمکدار؛ هیچوقت خود رمز، حتی «رمزنگاریشده».
۲) هش سریع (MD5، SHA-256) برای رمز
Section titled “۲) هش سریع (MD5، SHA-256) برای رمز”برای فایل خوب، برای رمز بد (مثال ۳). راهحل: bcrypt، Argon2 یا scrypt؛ هر زبان برنامهنویسی کتابخانهی آماده دارد. هرگز الگوریتم خودت را اختراع نکن.
۳) «رمزنگاری» بهجای «هش» برای رمز عبور
Section titled “۳) «رمزنگاری» بهجای «هش» برای رمز عبور”اگر رمزها با یک کلید رمزنگاری شده باشند، هر کس کلید را بدزدد (معمولاً کنار همان دیتابیس است)، همهی رمزها را دارد. راهحل: رمز عبور را هرگز نباید برگرداند؛ پس هش، نه رمزنگاری.
۴) رمز تکراری
Section titled “۴) رمز تکراری”یک سایت ضعیف لو برود، همهی حسابهایت لو رفتهاند. راهحل: مدیر رمز با رمز تصادفی جدا برای هر سایت، و تأیید دومرحلهای (2FA) برای حسابهای مهم.
۵) رمز در خط فرمان و فایلها
Section titled “۵) رمز در خط فرمان و فایلها”-pass pass:... در تاریخچهی bash (~/.bash_history) میماند و در فهرست پروسهها برای بقیهی کاربرها دیده میشود. راهحل: بگذار برنامه رمز را بپرسد، یا از فایل با مجوز محدود بخواند (دورهی لینوکس، مجوزها).
یک فایل متنی notes.txt بساز، هشش را بگیر، یک حرف از آن را عوض کن و دوباره هش بگیر. دو هش چقدر به هم شبیهاند؟ بعد هش را در فایل notes.sha256 ذخیره کن و با sha256sum -c بررسی کن.
دیدن جواب
echo "خرید: نان، شیر" > notes.txtsha256sum notes.txtsha256sum notes.txt > notes.sha256sha256sum -c notes.sha256echo "خرید: نان، پنیر" > notes.txtsha256sum notes.txtsha256sum -c notes.sha256ecfde1d6d218b423395fca0575dacf40e11ce1fe0d22016dd3eebf3a89f10f10 notes.txtnotes.txt: OK8acaebf11878aabc89e8923c3d04e83e92b626db22f5dbb5d3120f37078c52a6 notes.txtnotes.txt: FAILEDsha256sum: WARNING: 1 computed checksum did NOT matchهش دوم هیچ شباهتی به اولی ندارد. sha256sum -c هش ذخیرهشده را با هش فعلی فایل مقایسه میکند: OK یعنی دستنخورده، FAILED یعنی تغییر کرده. همین کار را برای ISO اوبونتو با فایل SHA256SUMS سایتش انجام میدهی.
نشان بده چرا نمک مهم است: برای یک رمز (Tehran1405) با openssl passwd -6 سه هش بدون دادن نمک بساز و یک بار هم با نمک ثابت AbCd1234 دو بار. بعد توضیح بده سیستم چطور در زمان ورود رمز را چک میکند، در حالی که هشها هر بار عوض میشوند.
دیدن جواب
for i in 1 2 3; do openssl passwd -6 'Tehran1405'; doneopenssl passwd -6 -salt AbCd1234 'Tehran1405'openssl passwd -6 -salt AbCd1234 'Tehran1405'$6$Lq0Uo3m5bX2JdG8k$...$6$7vVnA1zQe9PpR0sW$...$6$cH2mZt8Kq4YjL6aN$...$6$AbCd1234$1i9N1Y/w3m8C4DWIorTpvKCAJqP9pUtsK/Du5Y.d0sLkuO9mSjSX.4I3tmBgHgJKYZajl4A72OJikGrrKpntC1$6$AbCd1234$1i9N1Y/w3m8C4DWIorTpvKCAJqP9pUtsK/Du5Y.d0sLkuO9mSjSX.4I3tmBgHgJKYZajl4A72OJikGrrKpntC1بدون نمک دستی، هر بار یک نمک تصادفی جدید ساخته شد و هش عوض شد. با نمک ثابت، هش ثابت. موقع ثبتنام، سیستم یکی از این رشتهها را (با نمکش) ذخیره میکند. موقع ورود، نمک را از خود رشتهی ذخیرهشده (بخش بین $ دوم و سوم) برمیدارد، رمز تایپشده را با همان نمک هش میکند و نتیجه را با بخش آخر مقایسه میکند. یکی بود: رمز درست است.
به crack.py دو ردیف اضافه کن: «۱۶ حرف کوچک» و «۱۰ حرف با همهی ۹۵ نماد صفحهکلید». کدام قویتر است؟ بعد حساب کن یک رمز ۸ حرفی از ۶۲ حرف، در بدترین حالت، با هش سریع چند ساعت طول میکشد و چرا «بهطور متوسط» نصف آن است.
دیدن جواب
("۱۶ حرف کوچک", 26, 16), ("۱۰ حرف از ۹۵ نماد", 95, 10),۱۶ حرف کوچک 75.2 138,282 سال 138,282,416,601 سال۱۰ حرف از ۹۵ نماد 65.7 190 سال 189,858,238 سال۱۶ حرف کوچک (۷۵ بیت) خیلی قویتر از ۱۰ حرف پیچیده (۶۶ بیت) است و حفظ کردنش هم راحتتر (مثلاً چند کلمه کنار هم). طول برنده است. برای ۸ حرف از ۶۲: ۶۲۸ ≈ ۲٫۱۸ × ۱۰۱۴ حالت؛ تقسیم بر ۱۰۱۰ در ثانیه ≈ ۲۱٬۸۰۰ ثانیه ≈ ۶ ساعت (همان عدد جدول). بهطور متوسط مهاجم رمز را وسط راه پیدا میکند (گاهی زود، گاهی دیر؛ میانگین وسط فهرست است)، پس حدود ۳ ساعت.
آزمونک
Section titled “آزمونک”هش چیست؟
جواب درست: اثر انگشت یکطرفه و ثابتاندازهی داده
از هش نمیشود به ورودی رسید.
سایت درست کار میکند اگر برای رمز کاربر چه ذخیره کند؟
جواب درست: هش کند و نمکدار رمز
رمز هرگز نباید قابلبرگشت باشد.
نمک (salt) چه مشکلی را حل میکند؟
جواب درست: یکسان بودن هش رمزهای یکسان و جدولهای آمادهی مهاجم
نمک محرمانه نیست؛ فقط یکتا میکند.
رشتهی UzNjdXJlLVBhc3M= در فایل تنظیمات چیست؟
جواب درست: احتمالاً Base64؛ با یک دستور برمیگردد و امنیتی ندارد
encoding ≠ رمزنگاری.
کدام تغییر بیشترین اثر را روی قدرت رمز تصادفی دارد؟
جواب درست: طولانیتر کردن رمز
هر حرف اضافه، حالتها را چند ده برابر میکند.
در رمزنگاری نامتقارن، چه چیزی را میشود آزادانه به همه داد؟
جواب درست: کلید عمومی
کلید خصوصی هرگز از دست صاحبش بیرون نمیرود.
جمعبندی
Section titled “جمعبندی”- هش اثر انگشت یکطرفه است: همیشه یکسان، اندازهی ثابت، اثر بهمنی، بدون راه برگشت. برای بررسی سلامت فایل و ذخیرهی رمز.
- رمز عبور: هرگز خود رمز؛ هش کند + نمک (bcrypt، Argon2، scrypt، yescrypt). SHA-256 برای رمز خیلی سریع است.
- encoding (Base64) امنیت ندارد؛ رمزنگاری با کلید برمیگردد؛ هش برنمیگردد.
- رمزنگاری متقارن (AES) یک کلید دارد؛ نامتقارن جفت کلید عمومی/خصوصی، پایهی SSH و HTTPS و امضای دیجیتال.
- قدرت رمز = تعداد حالتها؛ طول مهمترین عامل است؛ مدیر رمز و 2FA.
| دستور | کاری که میکند |
|---|---|
sha256sum file | هش فایل |
sha256sum -c SHA256SUMS | بررسی دانلود |
openssl passwd -6 'pass' | هش نمکدار به قالب لینوکس |
$6$salt$hash / $y$... | قالب هش در /etc/shadow |
base64 / base64 -d | encoding، نه امنیت |
openssl enc -aes-256-cbc -pbkdf2 -in f -out f.enc | رمزنگاری فایل |
openssl enc -d -aes-256-cbc -pbkdf2 -in f.enc | باز کردن فایل |
طول > پیچیدگی | قانون رمز قوی |