Authentication হলো আপনার অ্যাপ্লিকেশনের দরজায় দাঁড়িয়ে থাকা একজন বাউন্সার। যখনই কেউ সাইন আপ করে বা লগ ইন করে, আপনার সিস্টেমকে সিদ্ধান্ত নিতে হয় যে তারা আসলেই তারা কি না। এটি ভুল হলে, আপনি কেবল একটি ব্যর্থ লগ ইন ডিবাগ করছেন না; বরং আপনি ব্যবহারকারীর আসল ডেটা সরাসরি চুরি হওয়ার ঝুঁকি নিচ্ছেন। এটি সঠিকভাবে করার জন্য দুটি নির্ভরযোগ্য টুলের প্রয়োজন: সংরক্ষিত পাসওয়ার্ড সুরক্ষিত রাখতে Bcrypt, এবং ব্যবহারকারী যখন আপনার অ্যাপের মধ্যে চলাফেরা করেন তখন তার পরিচয় যাচাই করতে JSON Web Tokens।

কেন Plaintext স্টোরেজ ব্যর্থ হয়

এই নিবন্ধ থেকে আপনি যদি কেবল একটি নিয়ম মনে রাখতে চান, তবে সেটি হলো: আপনার ডেটাবেসে কখনোই পাসওয়ার্ড plaintext হিসেবে সংরক্ষণ করবেন না। আপনার ডেটাবেস একটি ফায়ারওয়ালের পেছনে থাকুক বা আপনি টিমের প্রতিটি ইঞ্জিনিয়ারকে বিশ্বাস করেন—তা কোনো ব্যাপারই না। পাসওয়ার্ডগুলোকে সরাসরি বা র (raw) আকারে টেবিলে লিখে রাখা মানে হলো দরজার ম্যাটের নিচে ঘরের চাবি রেখে দেওয়া। যে মুহূর্তে কেউ একটি ভুল কনফিগার করা API, লিক হওয়া ব্যাকআপ বা ইনজেকশন অ্যাটাকের মাধ্যমে সেই ডেটাবেসে প্রবেশ করতে পারবে—প্রতিটি ক্রেডেনশিয়াল তাৎক্ষণিকভাবে প্রকাশ হয়ে পড়বে।

ক্ষতি বহুগুণ বেড়ে যায় কারণ মানুষ একই পাসওয়ার্ড বারবার ব্যবহার করে। একটি মাত্র নিরাপত্তা লঙ্ঘন (breach) কেবল আপনার অ্যাপ্লিকেশনকেই নয়, বরং ব্যবহারকারীর ইমেল, ব্যাংকিং এবং সোশ্যাল মিডিয়া অ্যাকাউন্টকেও ঝুঁকির মুখে ফেলতে পারে। এই কারণেই আমরা পাসওয়ার্ড হ্যাশ (hash) করি। হ্যাশিং পাসওয়ার্ডকে এমন একটি এলোমেলো স্ট্রিংয়ে রূপান্তরিত করে যার সাথে মূল পাসওয়ার্ডের কোনো দৃশ্যমান মিল থাকে না। এই প্রক্রিয়াটি একমুখী এবং অপরিবর্তনীয়। আপনি একটি হ্যাশের ওপর কোনো গাণিতিক অ্যাসিড ঢেলে সেটিকে পুনরায় মূল পাসওয়ার্ডে রূপান্তর করতে পারবেন না।

Bcrypt দিয়ে পাসওয়ার্ড হ্যাশ করা

Bcrypt হলো বিশেষভাবে পাসওয়ার্ডের জন্য তৈরি একটি হ্যাশিং ফাংশন। এটি একটি প্লেইন স্ট্রিং গ্রহণ করে, সেটিকে Blowfish cipher-এর মধ্য দিয়ে চালায় এবং এমন একটি ফলাফল প্রদান করে যা দেখতে অনেকটা $2b$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy-এর মতো। সেই প্রিফিক্সটি আপনাকে অ্যালগরিদম এবং কস্ট ফ্যাক্টর (cost factor) সম্পর্কে জানায়। শেষের লম্বা অংশটি হলো সল্ট (salt) এবং হ্যাশের একটি সংমিশ্রণ।

সল্ট হলো হ্যাশিং শুরু করার আগে পাসওয়ার্ডের সাথে মিশিয়ে দেওয়া কিছু র‍্যান্ডম ডেটা। যেহেতু প্রতিটি ব্যবহারকারীর জন্য সল্ট আলাদা হয়, তাই দুইজন ব্যক্তি যদি "password123" পাসওয়ার্ডটি বেছে নেন, তবুও আপনার ডেটাবেসে তাদের হ্যাশ দুটি সম্পূর্ণ ভিন্ন হবে। এই সামান্য পার্থক্যটি রেইনবো টেবিলকে (rainbow tables)—যা সাধারণ পাসওয়ার্ডের হ্যাশগুলোর একটি পূর্ব-গণিতকৃত ডিকশনারি—ব্যর্থ করে দেয়; কারণ আক্রমণকারীদের প্রতিটি ইউনিক সল্টের জন্য পুরো টেবিলটি পুনরায় তৈরি করতে হবে।

Bcrypt ইচ্ছাকৃতভাবে ধীরগতির। আধুনিক হার্ডওয়্যার SHA-256-এর মতো দ্রুত অ্যালগরিদম ব্যবহার করে প্রতি সেকেন্ডে বিলিয়ন বিলিয়ন হ্যাশ অনুমান করতে পারে। কিন্তু Bcrypt ধীরগতিতে কাজ করে। এটি হ্যাশিং প্রক্রিয়াটি একাধিকবার চালায়, যা একটি কস্ট ফ্যাক্টর দ্বারা নিয়ন্ত্রিত হয়; কম্পিউটার যত দ্রুত হবে, আপনি সেই ফ্যাক্টরটি তত বাড়িয়ে দিতে পারেন। এই ধীরগতি চুরি করা ডেটাবেসের মাধ্যমে ব্রুট-ফোর্স (brute-force) করার চেষ্টা করা যে কাউকে বাধা দেয়। লগ ইন করার সময় একজন বৈধ ব্যবহারকারী অতিরিক্ত দুইশ মিলিসেকেন্ড অপেক্ষা করলে তা খেয়াল করবেন না। কিন্তু একজন আক্রমণকারী যখন লক্ষ লক্ষ অনুমান পরীক্ষা করার চেষ্টা করবেন, তখন তিনি অবশ্যই এটি টের পাবেন।

JSON Web Tokens কীভাবে কাজ করে

Bcrypt যখন সদর দরজার দায়িত্ব পালন করে, তখন JWT কাজ করে করিডোর পাস হিসেবে। একটি JSON Web Token হলো একটি সংক্ষিপ্ত, URL-safe স্ট্রিং যা প্রমাণ করে যে ব্যবহারকারী ইতিমধ্যে অথেন্টিকেটেড হয়েছেন। এটিকে একটি ডিজিটাল আইডি কার্ড হিসেবে ভাবুন যা সার্ভার ইস্যু করে এবং ক্লায়েন্ট সেটি সাথে নিয়ে ঘোরে।

একটি JWT-তে ডট (.) দিয়ে আলাদা করা তিনটি অংশ থাকে: হেডার (header), পেলোড (payload), এবং সিগনেচার (signature)। হেডার টোকেনের ধরন এবং সাইনিং অ্যালগরিদম নির্দিষ্ট করে। পেলোড ক্লেইমস (claims) বহন করে—যা ব্যবহারকারী এবং টোকেন সম্পর্কে কিছু তথ্য দেয়—যেমন ইউজার আইডি, ইউজারনেম এবং একটি এক্সপায়ারেশন টাইমস্ট্যাম্প। সিগনেচার হলো একটি ক্রিপ্টোগ্রাফিক সিল। সার্ভার হেডার এবং পেলোড এনকোড করে এবং তারপর সেগুলোকে একটি সিক্রেট কী-এর মধ্য দিয়ে চালিয়ে এটি তৈরি করে। যদি কেউ পেলোডে কোনো পরিবর্তন করার চেষ্টা করে, তবে সিগনেচার আর মিলবে না এবং সার্ভার সরাসরি টোকেনটি প্রত্যাখ্যান করবে।