হ্যাশিং, HMAC ও ডিজিটাল সিগনেচার
এই পাঠে যা শিখবেন
- হ্যাশিং, HMAC ও ডিজিটাল সিগনেচার — এই তিনটির মধ্যে সুনির্দিষ্ট পার্থক্য
- কেন প্লেইন হ্যাশিং authenticity প্রমাণ করে না, শুধু integrity
- real stdlib
hmacমডিউল দিয়ে HMAC কীভাবে একটি সিক্রেট কী যোগ করে authenticity নিশ্চিত করে - কোন পরিস্থিতিতে HMAC এবং কোন পরিস্থিতিতে ডিজিটাল সিগনেচার ব্যবহার করবেন
১ · হ্যাশিং রিক্যাপ — শুধু Integrity, Authenticity নয়
L01-এ আমরা দেখেছিলাম কীভাবে একটি ক্রিপ্টোগ্রাফিক হ্যাশ ফাংশন যেকোনো ইনপুট থেকে একটি নির্দিষ্ট-দৈর্ঘ্যের "ফিঙ্গারপ্রিন্ট" তৈরি করে — এবং ইনপুটে সামান্যতম পরিবর্তন আউটপুটকে সম্পূর্ণ বদলে দেয় (avalanche effect)। এটি চমৎকারভাবে integrity (ডেটা অপরিবর্তিত থাকা) প্রমাণ করে।
কিন্তু হ্যাশিং একটি সর্বজনীন, কী-বিহীন অ্যালগরিদম — যে কেউ (আক্রমণকারীসহ) যেকোনো বার্তার হ্যাশ কম্পিউট করতে পারে, এমনকি একটি দূষিতভাবে পরিবর্তিত বার্তারও। যদি কোনো আক্রমণকারী ট্রানজিটে বার্তা এবং তার সাথে সংযুক্ত হ্যাশ — দুটোই বদলে দিতে পারে, তাহলে শুধু হ্যাশ তুলনা করলে এটি ধরা পড়বে না। এখানেই একটি সিক্রেট (HMAC) বা একটি প্রাইভেট কী (ডিজিটাল সিগনেচার) প্রয়োজন হয় — যা আক্রমণকারীর কাছে নেই — চেকটিকে সত্যিকারের tamper-resistant করতে।
২ · HMAC — হ্যাশ + সিক্রেট কী = Authenticity
HMAC (Hash-based Message Authentication Code)HMACএকটি হ্যাশ ফাংশনকে একটি গোপন কী-এর সাথে একত্রিত করে — শুধুমাত্র সেই কী জানা কেউই একটি নির্দিষ্ট বার্তার জন্য বৈধ HMAC তৈরি করতে পারে, যা authenticity ও integrity উভয়ই প্রমাণ করে। একটি হ্যাশকে একটি সিক্রেট কী-এর সাথে একত্রিত করে এমনভাবে যে, শুধুমাত্র সেই সিক্রেট জানা কেউই একটি নির্দিষ্ট বার্তার জন্য বৈধ HMAC তৈরি করতে পারে। কোনো আক্রমণকারী ট্রানজিটে বার্তা বদলে দিলেও, সিক্রেট না জানায় সে সেই পরিবর্তিত বার্তার জন্য একটি মিলে-যাওয়া HMAC তৈরি করতে পারবে না — রিসিভার recompute করে তুলনা করলেই অমিল ধরা পড়ে।
নিচের কোড সেলটি real, কার্যকরী stdlib hmac মডিউল ব্যবহার করে — কোনো সিমুলেশন নয়। এটি দেখায়
একটি বৈধ HMAC কীভাবে সঠিকভাবে ভেরিফাই হয়, এবং একটি ট্যাম্পার-করা বার্তার HMAC কীভাবে মিলতে ব্যর্থ হয়
(L01-এর হ্যাশ-তুলনা প্যাটার্নের ঠিক একই ধরনের, শুধু একটি সিক্রেট কী দিয়ে বর্ধিত)।
import hmac
import hashlib
secret_key = b"abcltech-shared-api-secret" # শুধুমাত্র sender ও receiver জানে
# --- ধাপ ১: sender আসল বার্তা পাঠানোর সময় HMAC গণনা করে সংযুক্ত করে ---
original_message = b"transfer:1000:to:account_42"
sent_hmac = hmac.new(secret_key, original_message, hashlib.sha256).hexdigest()
print("প্রেরিত বার্তা:", original_message.decode())
print("প্রেরিত HMAC: ", sent_hmac)
print()
# --- ধাপ ২ক: বার্তাটি অপরিবর্তিত অবস্থায় রিসিভারের কাছে পৌঁছালে ---
received_message_ok = original_message
recomputed_hmac_ok = hmac.new(secret_key, received_message_ok, hashlib.sha256).hexdigest()
print("অপরিবর্তিত বার্তার recompute করা HMAC মিলছে কি? ",
hmac.compare_digest(recomputed_hmac_ok, sent_hmac))
# --- ধাপ ২খ: ট্রানজিটে কেউ বার্তাটি বদলে দিলে (শুধু amount পরিবর্তিত) ---
received_message_tampered = b"transfer:9000:to:account_42"
recomputed_hmac_tampered = hmac.new(secret_key, received_message_tampered, hashlib.sha256).hexdigest()
print("পরিবর্তিত বার্তার recompute করা HMAC মিলছে কি? ",
hmac.compare_digest(recomputed_hmac_tampered, sent_hmac))
hmac.compare_digest() ব্যবহার করা হয়েছে, সাধারণ == নয় — এটি একটি
constant-time তুলনা যা timing attack প্রতিরোধ করে (একটি আক্রমণকারী ==-এর তুলনার সময় পরিমাপ করে
ধীরে ধীরে সঠিক HMAC অনুমান করতে পারত)।
৩ · ডিজিটাল সিগনেচার — অ্যাসিমেট্রিক ক্রিপ্টো দিয়ে Publicly-Verifiable Authenticity
ডিজিটাল সিগনেচার (Digital Signature)Digital Signatureঅ্যাসিমেট্রিক ক্রিপ্টো ব্যবহার করে — প্রেরক তার প্রাইভেট কী দিয়ে সাইন করে, যে কেউ প্রেরকের পাবলিক কী দিয়ে ভেরিফাই করতে পারে — কোনো শেয়ার্ড সিক্রেট ছাড়াই। HMAC-এর মতো একটি সিক্রেট কী শেয়ার করার বদলে অ্যাসিমেট্রিক ক্রিপ্টো ব্যবহার করে: প্রেরক তার প্রাইভেট কী দিয়ে বার্তায় সাইন করেন, এবং যে কেউ প্রেরকের পাবলিক কী দিয়ে সেই সিগনেচার ভেরিফাই করতে পারেন। এর সুবিধা: কোনো পূর্ব-শেয়ার্ড সিক্রেটের প্রয়োজন নেই — যে কোনো সংখ্যক অজানা ভেরিফায়ার প্রেরকের সাথে আগে থেকে কোনো সম্পর্ক ছাড়াই যাচাই করতে পারে। ক্লাসিক ব্যবহার: সফটওয়্যার আপডেট সাইনিং (L28-এর সাথে সম্পর্কিত) — ভেন্ডর একবার সাইন করেন, লক্ষ লক্ষ ব্যবহারকারী সহজেই ভেরিফাই করতে পারেন।
৪ · কোনটি কখন — HMAC বনাম ডিজিটাল সিগনেচার
দুই পক্ষ ইতিমধ্যে একটি সিক্রেট শেয়ার করে (যেমন একটি API ক্লায়েন্ট/সার্ভার জোড়া)। দ্রুত, সরল।
কোনো পূর্ব-শেয়ার্ড সিক্রেট নেই এবং publicly-verifiable authenticity দরকার (যেমন সফটওয়্যার বিতরণ, L37-এর PKI-এর ভিত্তি)।
হ্যাশ (শুধু integrity) → HMAC (integrity + authenticity, একটি শেয়ার্ড সিক্রেট দিয়ে) → ডিজিটাল সিগনেচার (integrity + authenticity, publicly verifiable, কোনো শেয়ার্ড সিক্রেট ছাড়াই)। প্রতিটি ধাপ আগেরটির উপর একটি নির্দিষ্ট নিরাপত্তা গ্যারান্টি যোগ করে — সঠিক টুল বেছে নেওয়া নির্ভর করে ঠিক কোন গ্যারান্টিটি আপনার দরকার তার উপর।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ প্লেইন হ্যাশিং (যেমন L01-এ দেখানো) কেন authenticity প্রমাণ করে না?
হ্যাশিং একটি সর্বজনীন, কী-বিহীন অ্যালগরিদম — যে কেউ, আক্রমণকারীসহ, যেকোনো বার্তার (এমনকি একটি দূষিতভাবে পরিবর্তিত বার্তারও) হ্যাশ কম্পিউট করতে পারে। যদি আক্রমণকারী বার্তা এবং তার সাথে যুক্ত হ্যাশ — দুটোই ট্রানজিটে বদলে দিতে পারে, তাহলে শুধু হ্যাশ তুলনা করলে সেটি ধরা পড়বে না — একটি সিক্রেট (HMAC) বা প্রাইভেট কী (সিগনেচার) দরকার, যা আক্রমণকারীর কাছে নেই, চেকটিকে সত্যিকারের tamper-resistant করতে।
প্র ০২ HMAC আর ডিজিটাল সিগনেচারের মূল পার্থক্য কী — কেন উভয়ই দরকার, একটি যথেষ্ট নয়?
HMAC-এর জন্য দুই পক্ষকেই আগে থেকে একটি সিক্রেট কী শেয়ার করতে হয় (সিমেট্রিক-স্টাইল) — এটি এমন পরিস্থিতিতে কার্যকর যেখানে এমন একটি সম্পর্ক ইতিমধ্যে বিদ্যমান (যেমন একটি নির্দিষ্ট API ক্লায়েন্ট/সার্ভার)। ডিজিটাল সিগনেচার অ্যাসিমেট্রিক ক্রিপ্টো ব্যবহার করে — কোনো পূর্ব-শেয়ার্ড সিক্রেট প্রয়োজন নেই, পাবলিক কী থাকা যে কেউ ভেরিফাই করতে পারে। কোনটি ব্যবহার করবেন তা নির্ভর করে ভেরিফায়ারদের সংখ্যা/পরিচয় আগে থেকে জানা কি না তার উপর — একটি অন্যটির বিকল্প নয়, ভিন্ন পরিস্থিতির জন্য ভিন্ন টুল।
প্র ০৩
কেন কোডে hmac.compare_digest() ব্যবহার করা হলো, সাধারণ == নয়?
compare_digest() একটি constant-time তুলনা করে — অর্থাৎ তুলনায় যে সময় লাগে তা ইনপুটের উপর
নির্ভর করে না। সাধারণ == প্রথম অমিল পাওয়ামাত্র বন্ধ হয়ে যেতে পারে (short-circuit), এবং সেই
ক্ষুদ্র সময়ের পার্থক্য পরিমাপ করে একজন আক্রমণকারী তাত্ত্বিকভাবে ধাপে ধাপে সঠিক HMAC অনুমান করতে পারত
(timing attack) — compare_digest() এই ঝুঁকি দূর করে।
অনুশীলন
-
চিন্তা করুন: একটি সফটওয়্যার আপডেট বিতরণ ব্যবস্থায় কেন HMAC-এর বদলে ডিজিটাল সিগনেচার ব্যবহার করা হয়?
কারণ ভেন্ডর প্রতিটি একক ব্যবহারকারীর সাথে একটি সিক্রেট শেয়ার করে না (তা মাপযোগ্যও নয়, এবং একটি সিক্রেট এতজনের সাথে শেয়ার করলে লিক হওয়ার ঝুঁকিও বাড়ে)। একটি ডিজিটাল সিগনেচার ভেন্ডরকে একবার তার প্রাইভেট কী দিয়ে সাইন করার সুযোগ দেয়, এবং যে কেউ (লক্ষ লক্ষ ব্যবহারকারী) ভেন্ডরের পাবলিক কী দিয়ে যাচাই করতে পারে — কোনো শেয়ার্ড সিক্রেট ছাড়াই।
-
পরীক্ষা করুন: উপরের কোডে
secret_keyপরিবর্তন করে recompute-এর সময় একটি ভুল/ভিন্ন key ব্যবহার করুন (মূল বার্তা অপরিবর্তিত রেখেই), তারপর Run করে দেখুনcompare_digestকী রিটার্ন করে।বার্তাটি অপরিবর্তিত থাকলেও, একটি ভুল সিক্রেট কী সম্পূর্ণ ভিন্ন একটি HMAC তৈরি করে, এবং
compare_digestFalseরিটার্ন করে। এটি নিশ্চিত করে যে HMAC-এর বৈধতা শুধু বার্তার উপর নয়, বরং বার্তা এবং সঠিক শেয়ার্ড সিক্রেট — দুটোই একসাথে সঠিক থাকার উপর নির্ভর করে।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৬০টি পাঠ পরবর্তী পাঠ — PKI ও সার্টিফিকেট: X.509, CA ট্রাস্ট চেইন — ডিজিটাল সিগনেচার কীভাবে বাস্তব ট্রাস্ট সিস্টেম তৈরি করে তা দেখাবে।
- Discrete Mathematics কোর্স সহায়ক কোর্স RSA ও অ্যাসিমেট্রিক ক্রিপ্টোর গাণিতিক ভিত্তি এখানে বিস্তারিত দেখুন।
- System Design & Software Architecture কোর্স সঙ্গী কোর্স API অথেন্টিকেশন ও সিগনেচার-ভিত্তিক ভেরিফিকেশন বড় সিস্টেমে কীভাবে প্রয়োগ হয় দেখুন।
- সব Courses দেখুন ABCL TECH C, C++, Python, Java, JavaScript, DSA, DBMS, Discrete Mathematics, System Design ও Cybersecurity — সব এক জায়গায়।