System Design শেখো
শেখো / সিকিউরিটি ও প্রাইভেসি

Password Hashing (bcrypt, salt)

9 মিনিট Module 7 · Security & Privacy
এক নজরে
  • Password কখনো plaintext-এ রাখা যাবে না; এক-মুখী hash করে রাখতে হয়।
  • Salt হলো প্রতিটি password-এর সাথে যোগ করা random মান, যা rainbow table আক্রমণ ঠেকায়।
  • bcrypt, scrypt, argon2— এসব ইচ্ছাকৃতভাবে ধীর algorithm password hashing-এর জন্য আদর্শ।

সমস্যাটা কী?

ধরো একটা কোম্পানির database হ্যাক হলো। হ্যাকার ইউজার টেবিল ডাউনলোড করে দেখল— প্রতিটি ইউজারের password সরাসরি লেখা: email: rahim@x.com, password: rahim1234। এখন হ্যাকার শুধু এই সাইটের ক্ষতি করবে না, কারণ বেশিরভাগ মানুষ সব জায়গায় একই password ব্যবহার করে— তাই Rahim-এর Facebook, ব্যাংক, সবই বিপদে।

এটাই সবচেয়ে মৌলিক নিরাপত্তা ভুল: plaintext-এ password রাখা। প্রশ্ন হলো— ইউজার লগইন করলে আমরা যাচাই করব কীভাবে, অথচ password নিজে সংরক্ষণ করব না? উত্তরই হলো password hashing।

মূল ধারণা

Password hashing হলো password-কে একটি একমুখী (irreversible) hash-এ রূপান্তর করে রাখা, যাতে database ফাঁস হলেও মূল password সরাসরি উদ্ধার করা না যায়।

মূল কথা— Hashing একমুখী। তুমি password থেকে hash বানাতে পারো, কিন্তু hash থেকে কখনো মূল password ফিরে পাবে না। তাহলে লগইন কীভাবে যাচাই হয়? ইউজার যখন password দেয়, সিস্টেম সেটিকে আবার hash করে, এবং সংরক্ষিত hash-এর সাথে মিলিয়ে দেখে। দুটো hash মিললে password সঠিক— মূল password জানার দরকারই নেই।

এখানে encryption আর hashing গুলিয়ে ফেলা মস্ত ভুল। Encryption reversible— key দিয়ে আবার মূল ডেটা পাওয়া যায়, তাই key চুরি হলে সব শেষ। Password-এ আমরা চাই এমন কিছু যা কেউই reverse করতে না পারে, এমনকি আমরাও না।

কীভাবে কাজ করে

Salt কেন দরকার

শুধু hashing-এও সমস্যা আছে। দুজন ইউজার যদি একই password (123456) ব্যবহার করে, তাদের hash একই হবে। হ্যাকার আগে থেকে কোটি কোটি common password-এর hash বানিয়ে একটা টেবিল রাখে— একে বলে Rainbow Table। তখন hash মিলিয়েই password বের করে ফেলে।

সমাধান Salt— প্রতিটি password-এর সাথে একটি অনন্য random মান যোগ করা হয়, তারপর hash করা হয়। ফলে একই password-এরও hash ভিন্ন হয়, আর precomputed rainbow table পুরোপুরি অকেজো হয়ে যায়।

hash("123456" + "x9$kLm")  →  abc...   (Rahim-এর)
hash("123456" + "p2#Qwe")  →  def...   (Karim-এর)

salt গোপন রাখার দরকার নেই; এটি hash-এর পাশেই সংরক্ষণ করা যায়। এর কাজ গোপনীয়তা নয়, প্রতিটি hash-কে অনন্য করা।

কেন ধীর algorithm

MD5 বা SHA-256 খুব দ্রুত— সেকেন্ডে কোটি কোটি hash বানানো যায়। কিন্তু password-এর জন্য এটা খারাপ, কারণ হ্যাকারও দ্রুত brute-force করতে পারে। তাই এমন algorithm দরকার যা ইচ্ছাকৃতভাবে ধীর ও memory-খরুচে।

Algorithmবৈশিষ্ট্যpassword-এ উপযুক্ত?
MD5খুব দ্রুত, ভাঙানা
SHA-256দ্রুতনা (একা)
bcryptধীর, salt built-inহ্যাঁ
scryptmemory-খরুচেহ্যাঁ
argon2আধুনিক, সুপারিশকৃতহ্যাঁ
সহজ উদাহরণ

Hashing অনেকটা ফল দিয়ে জুস বানানোর মতো— আম থেকে জুস বানানো সহজ, কিন্তু জুস থেকে আবার আস্ত আম ফেরানো অসম্ভব। এটাই একমুখীতা। আর salt হলো প্রতিটি গ্লাসে আলাদা গোপন মশলা মেশানো— ফলে দুজন একই আমের জুস বানালেও স্বাদ (hash) আলাদা হয়, কেউ আগে থেকে রেসিপি মিলিয়ে চিনতে পারে না।

কৌশল

bcrypt, scrypt, argon2

  • bcrypt: বহু বছরের পরীক্ষিত, salt নিজেই handle করে, "cost factor" বাড়িয়ে ধীরগতি নিয়ন্ত্রণ করা যায়। নিরাপদ ডিফল্ট পছন্দ।
  • scrypt: শুধু সময় নয়, প্রচুর memory-ও লাগে; ফলে বিশেষায়িত হার্ডওয়্যার (GPU/ASIC) দিয়ে আক্রমণ ব্যয়বহুল হয়।
  • argon2: Password Hashing Competition-এর বিজয়ী, আধুনিকতম সুপারিশ। সময় ও memory দুটোই tune করা যায়।

Pepper

Salt-এর পাশাপাশি একটি বাড়তি স্তর হলো Pepper— একটি গোপন মান যা সব password-এর সাথে যোগ হয়, কিন্তু database-এ নয়, আলাদা নিরাপদ জায়গায় (যেমন environment variable বা secret manager) রাখা হয়। database ফাঁস হলেও pepper না জানায় আক্রমণ আরও কঠিন হয়। salt আর pepper একে অন্যের বিকল্প নয়, পরিপূরক।

কখন ব্যবহার করবে / করবে না

সবসময় password hashing করো— ব্যতিক্রম নেই। নিজে hash logic না লিখে পরীক্ষিত library ব্যবহার করো (bcrypt/argon2)। হার্ডওয়্যার শক্তিশালী হওয়ার সাথে সাথে cost factor বাড়াও।

সাবধান

কখনোই MD5 বা সাধারণ SHA-256 একবার চালিয়ে password রাখবে না— এগুলো দ্রুত বলে আধুনিক GPU সেকেন্ডে কোটি কোটি চেষ্টা করতে পারে। আর কখনো নিজের "encryption" দিয়ে password রাখবে না; password reversible হওয়া মানেই বিপদ। সবসময় salt ব্যবহার করো এবং প্রতি ইউজারে আলাদা salt।

বাস্তব উদাহরণ

২০১২ সালে LinkedIn-এর ৬৫ লক্ষ password ফাঁস হয়। সমস্যা ছিল— তারা salt ছাড়া শুধু SHA-1 ব্যবহার করেছিল। ফলে হ্যাকাররা rainbow table দিয়ে দ্রুত বিপুল password উদ্ধার করে ফেলে। এর পর থেকে শিল্পে salt + ধীর algorithm (bcrypt/argon2) প্রায় বাধ্যতামূলক মানদণ্ড হয়ে দাঁড়িয়েছে। আজ Facebook, GitHub-সহ বড় প্রতিষ্ঠান salt-সহ ধীর hashing ব্যবহার করে এবং নিয়মিত cost factor বাড়ায়।

টিপস

ইন্টারভিউতে "password কীভাবে রাখবে?" জিজ্ঞেস করলে এক নিঃশ্বাসে বলো: "Plaintext নয়, reversible encryption নয়— বরং per-user salt-সহ bcrypt বা argon2 দিয়ে hash করব, এবং চাইলে pepper যোগ করব।" rainbow table ও কেন ধীর algorithm— এই দুটো ব্যাখ্যা করতে পারলে তুমি গভীরতা দেখালে।

মূল শব্দ (Key Terms)

মিনি কুইজ

1. Password কেন hashing দিয়ে রাখা হয়, encryption দিয়ে নয়?

2. Salt-এর মূল কাজ কী?

3. নিচের কোনটি password hashing-এর জন্য সবচেয়ে উপযুক্ত?