এনকোডিং, হ্যাশিং আর এনক্রিপশন তিনটি আলাদা জিনিস
এই পেজের প্রায় প্রতিটি ভুল ধারণা আসে এগুলোকে একটির বদলে আরেকটি ভাবা থেকে, তাই ভালোভাবে আলাদা করে বোঝা দরকার।
এনকোডিং উল্টানো যায়, আর এতে কোনো গোপন কিছু নেই। Base64 আছে বাইনারি ডেটাকে এমন চ্যানেলের মধ্য দিয়ে পাঠানোর জন্য, যেগুলো শুধু টেক্সট নেয় — ইমেইল অ্যাটাচমেন্ট, data URI, JSON স্ট্রিং — প্রতি তিন বাইটকে চারটি অক্ষরে প্রকাশ করে, আর এ কারণেই ফলাফল সবসময় প্রায় এক-তৃতীয়াংশ বড় হয়। কোনো কি নেই। স্ট্রিংটি যে দেখবে সে-ই এক ধাপে ডিকোড করতে পারে, এই সাইটেও। Base64 নিরাপত্তা নয়, বলার মতো কোনো লুকোচুরিও নয়, আর যে দেখতে চায় তার কাছ থেকে কিছু লুকানোর উপায়ও নয়। পার্সেন্ট-এনকোডিং হলো URL-এর জন্য একই ধরনের জিনিস, আর আরেকটি সাধারণ বাগ থাকে এখানেই: কোয়েরি স্ট্রিংয়ে বসবে এমন একটি মান এনকোড করা আর পুরো তৈরি করা URL পরিষ্কার করা আলাদা কাজ, কারণ শুধু প্রথমটিই সেই &, =, ? আর / এস্কেপ করে, যেগুলো URL-কে তার কাঠামো দেয়। ভুল করলে “Smith & Sons” সার্ভারে পৌঁছায় একটি মান হিসেবে নয়, দুটি প্যারামিটার হিসেবে।
হ্যাশিং একমুখী, আর এতেও কোনো কি নেই। হ্যাশ যেকোনো ইনপুট নিয়ে নির্দিষ্ট দৈর্ঘ্যের একটি আঙুলের ছাপ (ফিঙ্গারপ্রিন্ট) তৈরি করে, আর এটি ফেরানোর কোনো উপায় নেই — এনক্রিপ্ট করা বলে নয়, তথ্যটাই হারিয়ে গেছে বলে। যা করা যায় তা হলো ইনপুট অনুমান করে মিলিয়ে দেখা, আর ঠিক এ কারণেই পাসওয়ার্ড সংরক্ষণের জন্য MD5, SHA-1 ও SHA-256 ভুল: এগুলো দ্রুত, একটি গ্রাফিক্স কার্ড প্রতি সেকেন্ডে শত শত কোটি হ্যাশ বের করে, আর চুরি হওয়া হ্যাশের টেবিল সেই গতিতেই ভেঙে ফেলা হয়। পাসওয়ার্ডের দরকার ইচ্ছাকৃতভাবে ধীর, সল্ট করা ফাংশন — bcrypt, scrypt বা Argon2। আলাদাভাবে, MD5 ও SHA-1 আরেকটি কারণেও ভাঙা: একই হ্যাশওয়ালা দুটি ভিন্ন ফাইল এখন ইচ্ছে করে বানানো যায়, তাই কোনোটিই প্রমাণ করতে পারে না যে ফাইলটি আপনার প্রত্যাশিত ফাইলই — তবে দুর্ঘটনাবশত নষ্ট হওয়া ডাউনলোড ধরার জন্য দুটোই এখনো ঠিক আছে।
এনক্রিপশনেই কেবল কি থাকে, আর এই টুলগুলোর কোনোটিই তা করে না। এটা বাদ পড়ে যাওয়া নয়। ঠিকভাবে এনক্রিপশন করতে কি ব্যবস্থাপনা লাগে, আর কি রাখার জন্য ওয়েব পেজ ভুল জায়গা।
JWT সাইন করা থাকে, এনক্রিপ্ট করা নয় — আর এখানেই মানুষ বারবার ভুল করেন। টোকেনের হেডার ও পেলোড Base64URL — টোকেন যার হাতে আছে সে-ই পড়তে পারে, কোনো কি লাগে না। সিগনেচার কাউকে টোকেন বদলাতে বাধা দেয়; পড়তে বাধা দেয় না, তাই গোপন কিছু পেলোডে রাখা চলে না। এর মানে দাঁড়ায়, টোকেন ডিকোড করলে তার সম্পর্কে কিছুই প্রমাণ হয় না: যে কেউ ইচ্ছেমতো ক্লেইম লিখে Base64 করতে পারে। যাচাই মানে ইস্যুকারীর কি দিয়ে সিগনেচার আবার হিসাব করা — এটা আপনার সার্ভারের কাজ, আর কোনো ওয়েবসাইটের কখনোই তা চাওয়া উচিত নয়। তাই আমাদের ডিকোডার যাচাইয়ের কোনো ইঙ্গিত দিতে অস্বীকার করে, এবং সমস্যার লক্ষণগুলো চিহ্নিত করে — মেয়াদ পেরোনো টোকেন, মেয়াদই নেই এমন টোকেন, আর “none” অ্যালগরিদম, যা কৌতূহলের বিষয় নয়, বরং নথিভুক্ত একটি অথেন্টিকেশন বাইপাস।
JSON-এ সংখ্যার নির্ভুলতার একটি সীমা আছে, যাতে বেশিরভাগ ফরম্যাটার নিঃশব্দে পা দেয়। JSON নিজে সংখ্যার আকারে কোনো সীমা রাখে না, কিন্তু JavaScript-এর সংখ্যা ৬৪-বিট ফ্লোট, তাই পূর্ণসংখ্যা শুধু 9,007,199,254,740,991 পর্যন্ত নির্ভুল থাকে। Twitter পোস্টের ID, Discord snowflake, ৬৪-বিটের ডেটাবেস কি বা ব্যাংক অ্যাকাউন্ট নম্বর এর চেয়ে বড়, আর প্রচলিত এক-লাইনের ফরম্যাটারে — parse, তারপর stringify — দিলে এর শেষের অঙ্কগুলো বদলে যায়। ফলাফলটি তখনো বিশ্বাসযোগ্য একটি সংখ্যার মতোই দেখায়, আর সেটাই বিপজ্জনক: 7205759403792793600 চুপচাপ হয়ে যায় 7205759403792793000। আমাদের JSON টুলগুলো আপনার পেস্ট করা হুবহু অঙ্কগুলোই আবার লেখে, এবং কতগুলো সংখ্যা রক্ষা করতে হয়েছে তা জানিয়ে দেয়।
UUID-এর ভার্সন বলে এটি কীভাবে তৈরি, কী নিশ্চয়তা দেয় তা নয়। কেউ UUID নিবন্ধন করে না, স্বতন্ত্রতাও কেউ বাধ্যতামূলক করে না; স্বতন্ত্রতা সম্ভাবনানির্ভর, আর ভার্সন বলে বিটগুলো কোথা থেকে এসেছে। ভার্সন ৪ হলো ব্রাউজারের ক্রিপ্টোগ্রাফিক জেনারেটর থেকে ১২২ বিটের র্যান্ডমনেস, যা একে অনুমান-অযোগ্য করে, তাই রিসেট লিংক, ইনভাইট কোড আর যেকোনো গোপন কিছুর জন্য সঠিক — আর ডেটাবেস কি হিসেবে ভুল, কারণ র্যান্ডম কি সাজানো ইনডেক্সে ছড়িয়ে পড়ে একে খণ্ডিত করে ফেলে। ভার্সন ৭ শুরুতে ৪৮-বিটের মিলিসেকেন্ড টাইমস্ট্যাম্প রাখে, ফলে কি-গুলো অটো-ইনক্রিমেন্ট পূর্ণসংখ্যার মতো ইনডেক্সের শেষে যোগ হয়, আবার বিশ্বজুড়ে স্বতন্ত্রও থাকে। বিনিময়ে v7 UUID যার হাতে আছে, তার কাছে স্পষ্টভাবে ফাঁস করে দেয় এটি কখন তৈরি হয়েছে, মিলিসেকেন্ড পর্যন্ত।
যেখানে ব্রাউজার সত্যিই ভুল টুল
এই তেরোটির কোনোটিই কোথাও কিছু পাঠায় না। কোনো রিকোয়েস্ট হয় না, কিছুই লগ করা হয় না, আর নেটওয়ার্ক বিচ্ছিন্ন থাকলেও পেজগুলো কাজ করে যায় — ঠিক এ কারণেই গ্রাহকদের রেকর্ডে ভরা API রেসপন্স বা এমন টোকেন, যা আপনি কাউকে ইমেইল করতেন না, এগুলোতে ব্যবহার করা যায়। এটাই এগুলোর পক্ষে সৎ যুক্তি। এবার বিপক্ষের সৎ যুক্তি।
চালু প্রোডাকশন সিক্রেট কোনো ওয়েব পেজে পেস্ট করা এমন অভ্যাস, যা না থাকাই ভালো — এই পেজসহ। আমাদের গোপনীয়তার দাবি সত্য, কিন্তু দাবি আপনাকে রক্ষা করে না; রক্ষা করে কোডের আচরণ, আর যেকোনো ওয়েব পেজের প্রতি একমাত্র যুক্তিসংগত মনোভাব হলো বিশ্বাস না করে যাচাই করা। যাচাইয়ে কোনো খরচ নেই: পেজ লোড হওয়ার পর ইন্টারনেট সংযোগ বিচ্ছিন্ন করুন, আর দেখুন টুলগুলো কাজ চালিয়ে যাচ্ছে। সার্ভার লাগলে টুলটি থেমে যেত। আর কোনো ক্রেডেনশিয়াল যদি এখনো বৈধ হয় এবং আপনি সেটি এমন কোথাও পেস্ট করে ফেলেছেন যা যাচাই করতে পারেন না, তবে সঠিক পদক্ষেপ হলো সেটি রোটেট করা, তা নিয়ে যুক্তি সাজানো নয়। এই মুহূর্তে চালু কোনো টোকেনের জন্য লোকালি ডিকোড করা — আপনার প্রোগ্রামিং ভাষার নিজস্ব Base64 ফাংশন, বা শেলে দুই লাইন — যেকোনো ওয়েবসাইটের চেয়ে ভালো অভ্যাস, আমাদেরটিসহ।
স্কিমা ভ্যালিডেশন। আমাদের JSON ও XML টুলগুলো দেখে ডকুমেন্টটি সুগঠিত কি না, আর এটি স্কিমার সঙ্গে মেলে কি না — সেটি আলাদা প্রশ্ন। JSON Schema বা XSD দিয়ে যাচাই করতে একটি স্কিমা ফাইল আনতে ও প্রয়োগ করতে হয়, অর্থাৎ একটি নেটওয়ার্ক রিকোয়েস্ট, যা এই পেজগুলো ইচ্ছাকৃতভাবেই কখনো করে না। JSON Schema-র জন্য ajv আর XSD ও DTD-র জন্য xmllint ব্যবহার করুন; দুটোই বিনামূল্যে, আর দুটোই এ কাজে যেকোনো ওয়েব পেজের চেয়ে ভালো।
সত্যিই বড় বা স্ট্রিম করা যেকোনো কিছু। ডকুমেন্ট পুরোটা মেমোরিতে রাখা হয়, ফরম্যাট করার সময় কখনো কখনো দুবার, তাই সীমা হলো ট্যাব। কয়েক মেগাবাইট সঙ্গে সঙ্গে হয়, কয়েকশো মেগাবাইট হয় না। jq কয়েক গিগাবাইটের JSON ফাইল স্ট্রিম করে, যা কোনো ব্রাউজার খুলবেই না, আর ripgrep একটি ফাইল পেস্ট করার আগেই পুরো রিপোজিটরি খুঁজে ফেলে। হ্যাশিংয়ে একই সীমা আরও তীব্র: ব্রাউজারের ক্রিপ্টোগ্রাফিতে ইনক্রিমেন্টাল ডাইজেস্ট নেই, তাই পুরো ফাইলটি একবারে মেমোরিতে আঁটতে হয় — একটি DVD ইমেজ ব্যর্থ হবে, যেখানে sha256sum, shasum বা certutil টেরও না পেয়ে সেটি স্ট্রিম করে ফেলে।
অটোমেশন ও CI। এগুলো চলে কেউ ক্লিক করলে। একটি রিপোজিটরির প্রতিটি ফাইল ফরম্যাট করা, একটি ফিক্সচারের জন্য দশ হাজার UUID তৈরি করা, বা পাইপলাইনে JSON যাচাই করা — এসব স্ক্রিপ্টের কাজ: jq, xmllint, uuidgen, openssl আর base64 কমান্ড বেশিরভাগ মেশিনে আগে থেকেই ইনস্টল করা থাকে।
সাইন করা যেকোনো কিছু যাচাই। সিগনেচার যাচাই, সার্টিফিকেট চেইন আর প্রাইভেট কি লাগে এমন যেকোনো কিছু হওয়া উচিত আপনার সার্ভারে, নিয়মিত রক্ষণাবেক্ষণ করা লাইব্রেরি দিয়ে। এই পেজ আপনাকে বলবে একটি টোকেন কী দাবি করছে; কখনো বলবে না যে টোকেনটি আসল — আর আপনার কি ছাড়াই এটা বলতে পারে বলে দাবি করা যেকোনো সাইটকে অবিশ্বাস করা উচিত।
একই রকম শোনায় এমন টুলগুলোর মধ্যে বাছাই
JSON ফরম্যাটার বনাম JSON ভ্যালিডেটর। একই পার্সার, আলাদা প্রশ্ন। ফরম্যাটার এমন ডকুমেন্ট পড়া ও নতুন করে সাজানোর জন্য, যা ইতিমধ্যে পার্স হয় — ইনডেন্ট করুন, মিনিফাই করুন, বড় সংখ্যাগুলো অক্ষত রাখুন। ভ্যালিডেটর এমন ডকুমেন্টের জন্য, যা পার্স হয় না, আর এর আউটপুট হলো লাইন, কলাম, নিচে ক্যারেট চিহ্নসহ সমস্যার অক্ষরটি, এবং চারটি সাধারণ কারণের কোনটি দায়ী। “Unexpected token” দেখে তাকিয়ে থাকলে আপনার দরকার ভ্যালিডেটর। XML ফরম্যাটার ও XML ভ্যালিডেটরের ক্ষেত্রেও একই ভাগ।
Base64 ডিকোড বনাম JWT ডিকোডার। JWT হলো তিনটি Base64URL অংশ, তাই সাধারণ ডিকোডারও টুকরোগুলো দেখাবে। JWT পেজ আপনার হয়ে সেগুলো আলাদা করে, JSON ফরম্যাট করে, মেয়াদ, ইস্যুর সময় ও not-before ক্লেইমগুলোকে Unix টাইমস্ট্যাম্প থেকে আপনার টাইমজোনের আসল তারিখে বদলায়, নিবন্ধিত ক্লেইমগুলোতে লেবেল দেয়, আর মেয়াদ ও “none” অ্যালগরিদম নিয়ে সতর্ক করে। Base64 ব্লবের জন্য সাধারণ ডিকোডার, আর টোকেনের জন্য JWT পেজ ব্যবহার করুন।
Base64 এনকোড বনাম URL এনকোড। আলাদা কাজ, যদিও দুটোই “নিরাপদ” টেক্সট তৈরি করে। Base64 যেকোনো বাইটকে টেক্সটে পরিণত করে ৩৩ শতাংশ বাড়তি সাইজের বিনিময়ে, আর সাধারণ Base64 URL-এ মোটেই নিরাপদ নয় — এর +, / আর = সেখানে বিশেষ অর্থ বহন করে, আর এ কারণেই Base64URL আছে। পার্সেন্ট-এনকোডিং পড়ার মতো টেক্সটকে পড়ার মতোই রাখে, শুধু সেটুকু এস্কেপ করে যা URL ভেঙে দিত — সার্চ টার্ম, ইমেইল ঠিকানা বা রিডাইরেক্ট টার্গেটের জন্য এটাই চাই। কোয়েরি স্ট্রিংয়ের জন্য পুরো একটি ফাইল এনকোড করা সাধারণত এই লক্ষণ যে এটি রিকোয়েস্ট বডি হওয়া উচিত ছিল।
হ্যাশ জেনারেটর বনাম UUID জেনারেটর। হ্যাশ তার ইনপুট থেকে তৈরি হয়, তাই একই ইনপুট সবসময় একই মান দেয় — এটাই একে আঙুলের ছাপ বানায়, ডাউনলোড যাচাই বা হুবহু একই কনটেন্টের ডুপ্লিকেট সরানোর জন্য ভালো। UUID হলো নতুন র্যান্ডমনেস, কোনো কিছুর সঙ্গে সম্পর্কহীন, তাই কখনো পুনরাবৃত্ত হয় না। একই কনটেন্টের জন্য একই শনাক্তকারী চাইলে হ্যাশ করুন। নতুন শনাক্তকারী চাইলে UUID তৈরি করুন।
QR কোড তৈরি বনাম বারকোড তৈরি। QR হলো দ্বিমাত্রিক গ্রিড, যা যেকোনো টেক্সট ধরে রাখে — একটি URL, Wi-Fi-এর তথ্য, ফোন নম্বর — আর ফোনের ক্যামেরা দিয়ে পড়া হয়। বারকোড পেজ তৈরি করে খুচরা বিক্রি ও লজিস্টিকসের একমাত্রিক কোড: EAN-13, EAN-8, UPC-A, ITF-14, Code 128 ও Code 39 — খুচরা পণ্যের চেক ডিজিট হিসাব করে, আর ভুল বা ছোট নম্বরকে চুপচাপ ভরাট করে অন্য কোনো পণ্যের বৈধ বারকোড না বানিয়ে প্রত্যাখ্যান করে।