ToolDeck

Python HMAC — hmac.new() SHA-256 গাইড ও কোড উদাহরণ

·DevOps Engineer & Python Automation Specialist·পর্যালোচনা করেছেনMaria Santos·প্রকাশিত

বিনামূল্যে অনলাইন HMAC জেনারেটর সরাসরি আপনার ব্রাউজারে ব্যবহার করুন — ইনস্টলের প্রয়োজন নেই।

HMAC জেনারেটর অনলাইনে ব্যবহার করুন →

প্রতিটি ওয়েবহুক কলব্যাক, প্রতিটি স্বাক্ষরিত API রিকোয়েস্ট, প্রতিটি Stripe বা GitHub ইভেন্ট নোটিফিকেশন একটি HMAC স্বাক্ষর দিয়ে নিশ্চিত করে যে পেলোড পরিবর্তন হয়নি। Python-এর hmac মডিউল একটি মাত্র ফাংশন কলে Python-এ HMAC-SHA256 সামলায়: hmac.new(key, msg, hashlib.sha256)। pip install লাগবে না, কোনো C এক্সটেনশন বা থার্ড-পার্টি লাইব্রেরিও না। কোড না লিখে দ্রুত স্বাক্ষর পরীক্ষার জন্য, অনলাইন HMAC Generator তাৎক্ষণিক ফলাফল দেয়। এই গাইডে hmac.new(), hmac.digest(), hmac.compare_digest(), Base64 এনকোডিং, ওয়েবহুক যাচাই, API অনুরোধ স্বাক্ষর এবং SHA-1 থেকে SHA-512 পর্যন্ত সমস্ত হ্যাশ অ্যালগরিদম আলোচনা করা হয়েছে। সমস্ত উদাহরণ Python 3.7+ লক্ষ্য করে।

  • hmac.new(key, msg, hashlib.sha256) হল স্ট্যান্ডার্ড শুরুর জায়গা — key ও msg অবশ্যই bytes হতে হবে, digestmod Python 3.4 থেকে আবশ্যক।
  • hmac.digest(key, msg, "sha256") Python 3.7-এ যোগ করা একটি দ্রুততর এককালীন বিকল্প — কাঁচা bytes ফেরত দেয়, মধ্যবর্তী অবজেক্ট তৈরি করে না।
  • সর্বদা hmac.compare_digest() দিয়ে স্বাক্ষর যাচাই করুন টাইমিং আক্রমণ প্রতিরোধে — HMAC তুলনায় কখনো == ব্যবহার করবেন না।
  • HTTP হেডার ও ওয়েবহুক স্বাক্ষরের জন্য কাঁচা .digest() আউটপুট Base64-এ এনকোড করুন: base64.b64encode(h.digest())।
  • hmac মডিউল যেকোনো hashlib অ্যালগরিদম গ্রহণ করে: sha1, sha256, sha384, sha512, md5, blake2b।

HMAC কী?

HMAC (Hash-based Message Authentication Code) হল RFC 2104-এ সংজ্ঞায়িত একটি নির্মাণ যা একটি নির্দিষ্ট আকারের প্রমাণীকরণ ট্যাগ তৈরি করতে একটি গোপন চাবির সাথে একটি হ্যাশ ফাংশন একত্রিত করে। সাধারণ হ্যাশের বিপরীতে (যা যেকেউ গণনা করতে পারে), HMAC তৈরিতে গোপন চাবির জ্ঞান প্রয়োজন। এর মানে আপনি এটি ব্যবহার করে একটি বার্তার অখণ্ডতা ও সত্যতা উভয়ই যাচাই করতে পারেন। বার্তা বা চাবির একটি বাইটও পরিবর্তিত হলে আউটপুট সম্পূর্ণ আলাদা হয়ে যায়। এই নির্মাণটি চাবিকে দুটি ভিন্ন প্যাডিং ধ্রুবক (ipad ও opad) দিয়ে XOR করে এবং দুটি হ্যাশ অপারেশনের মধ্যে বার্তাটি মুড়িয়ে দেয়। Python-এর hmac মডিউল এই RFC সরাসরি বাস্তবায়ন করে।

Before · Python
After · Python
# সাধারণ SHA-256 হ্যাশ — কোনো গোপন চাবি নেই, যেকেউ গণনা করতে পারে
hashlib.sha256(b"payment:9950:USD").hexdigest()
# "7a3b1c..."  (নির্ধারণীয়, সর্বজনীন)
# HMAC-SHA256 — তৈরি করতে গোপন চাবি প্রয়োজন
hmac.new(b"api_secret", b"payment:9950:USD", hashlib.sha256).hexdigest()
# "e4f2a8..."  (শুধুমাত্র চাবির অধিকারী গণনা করতে পারে)

hmac.new() — স্ট্যান্ডার্ড লাইব্রেরির প্রবেশবিন্দু

hmac মডিউল Python স্ট্যান্ডার্ড লাইব্রেরির অংশ। দুটি আমদানি করলেই প্রস্তুত: import hmac, hashlib। তিনটি প্রধান ফাংশন হল hmac.new() (একটি HMAC অবজেক্ট তৈরি করে), hmac.digest() (এককালীন, Python 3.7+), এবং hmac.compare_digest() (স্থির-সময় তুলনা)। কোনো pip ইনস্টল প্রয়োজন নেই।

hmac.new(key, msg, digestmod) তিনটি আর্গুমেন্ট নেয়। key msg উভয়কেই bytes-সদৃশ অবজেক্ট হতে হবে ( bytes, bytearray, বা memoryview)। Python 3.4 থেকে digestmod আর্গুমেন্ট আবশ্যক এবং যেকোনো hashlib কনস্ট্রাক্টর (যেমন hashlib.sha256) বা "sha256" এর মতো স্ট্রিং নাম গ্রহণ করে।

Python 3.7+ — ন্যূনতম HMAC-SHA256 উদাহরণ
import hmac
import hashlib

key = b"webhook_signing_key_2026"
message = b'{"event":"invoice.paid","invoice_id":"inv_8f3a","amount":19900}'

# HMAC অবজেক্ট তৈরি করুন এবং হেক্স স্বাক্ষর পান
signature = hmac.new(key, message, hashlib.sha256).hexdigest()
print(signature)
# "b4e74f6c9a1d3e5f8b2a7c0d4e6f1a3b5c7d9e0f2a4b6c8d0e1f3a5b7c9d0e2f"

HMAC অবজেক্ট দুটি আউটপুট মেথড প্রদান করে। .digest() কাঁচা bytes ফেরত দেয় (SHA-256-এর জন্য ৩২ bytes, SHA-512-এর জন্য ৬৪)। .hexdigest() ছোট হাতের হেক্স স্ট্রিং ফেরত দেয়। হেক্স স্ট্রিং একটি সাধারণ Python str — কোনো ডিকোডিং ধাপের প্রয়োজন নেই।

Python 3.7+ — .digest() বনাম .hexdigest()
import hmac
import hashlib

key = b"service_auth_key"
msg = b"GET /api/v2/orders 2026-03-28T14:30:00Z"

h = hmac.new(key, msg, hashlib.sha256)

raw_bytes = h.digest()
print(type(raw_bytes), len(raw_bytes))
# <class 'bytes'> 32

hex_string = h.hexdigest()
print(type(hex_string), len(hex_string))
# <class 'str'> 64

# উভয় একই ডেটা উপস্থাপন করে — হেক্স শুধু bytes-এর স্ট্রিং এনকোডিং
assert raw_bytes.hex() == hex_string

চাবি বা বার্তা Python স্ট্রিং হলে hmac.new()-এ পাস করার আগে bytes-এ রূপান্তর করতে .encode() কল করুন। প্রায় সবাই প্রথমবার এতে হোঁচট খায় — Python 3 স্ট্রিং ইউনিকোড, bytes নয়, এবং hmac মডিউল সেগুলো প্রত্যাখ্যান করে।

Python 3.7+ — স্ট্রিং bytes-এ রূপান্তর করা
import hmac
import hashlib

# স্ট্রিং চাবি ও বার্তা — .encode() UTF-8 bytes-এ রূপান্তর করে
api_key = "sk_live_9f3a2b7c4d8e"
request_body = '{"customer_id":"cust_4421","plan":"enterprise"}'

signature = hmac.new(
    api_key.encode(),
    request_body.encode(),
    hashlib.sha256
).hexdigest()

print(signature)
# "3a9f1b..."  — সামঞ্জস্যপূর্ণ হেক্স স্ট্রিং আউটপুট
নোট:Python 3.4 থেকে digestmod প্যারামিটারের কোনো ডিফল্ট নেই। এটি ছাড়া hmac.new(key, msg) কল করলে TypeError উত্থাপিত হয়। ৩.৪-এর আগে এটি MD5-এ ডিফল্ট ছিল, যে কারণে Python রক্ষণাবেক্ষণকারীরা ডিফল্টটি সরিয়ে দিয়েছেন — আপনাকে স্পষ্ট, নিরাপদ পছন্দ করতে বাধ্য করতে।

HMAC-SHA256 Base64, SHA-1, SHA-512 এবং MD5

hmac.new() ফাংশন hashlib-এ পাওয়া যায় এমন যেকোনো হ্যাশ অ্যালগরিদমের সাথে কাজ করে। অধিকাংশ ওয়েবহুক প্রদানকারী ও API গেটওয়ে HMAC-SHA256 ব্যবহার করে, তবে OAuth 1.0a-তে SHA-1, নির্দিষ্ট প্রোটোকলে SHA-512, এবং এখনো আপডেট না হওয়া পুরনো সিস্টেমে MD5 পাওয়া যায়।

Base64 আউটপুট সহ HMAC-SHA256

অনেক ওয়েবহুক প্রদানকারী HTTP হেডারে Base64-এনকোডেড স্ট্রিং হিসেবে স্বাক্ষর পাঠায়। একই ফরম্যাট তৈরি করতে, কাঁচা .digest() bytes base64.b64encode()-এ পাস করুন।

Python 3.7+ — HMAC-SHA256 Base64 এনকোডিং
import hmac
import hashlib
import base64

key = b"whsec_MbkP7x9yFqHGn3tRdWz5"
payload = b'{"id":"evt_1Nq","type":"charge.succeeded","data":{"amount":4200}}'

# কাঁচা ডাইজেস্ট → Base64 (Authorization হেডার ও ওয়েবহুক স্বাক্ষরের জন্য সাধারণ)
raw_digest = hmac.new(key, payload, hashlib.sha256).digest()
b64_signature = base64.b64encode(raw_digest).decode("ascii")

print(b64_signature)
# "dGhpcyBpcyBhIHNhbXBsZSBzaWduYXR1cmU="

# এটি X-Signature হেডারের সাথে তুলনার মান
header_value = f"sha256={b64_signature}"
print(header_value)
# "sha256=dGhpcyBpcyBhIHNhbXBsZSBzaWduYXR1cmU="

HMAC-SHA1 — পুরনো প্রোটোকল সামঞ্জস্য

SHA-1 নতুন ডিজাইনে দুর্বল বলে বিবেচিত, তবে OAuth 1.0a এবং কিছু পুরনো ওয়েবহুক বাস্তবায়নে HMAC-SHA1 এখনো প্রয়োজন। কোড একই — শুধু অ্যালগরিদম বদলান।

Python 3.7+ — HMAC-SHA1
import hmac
import hashlib

consumer_secret = b"oauth_consumer_secret_2026"
token_secret = b"oauth_token_secret_2026"

# OAuth 1.0a consumer_secret&token_secret স্বাক্ষর চাবি হিসেবে ব্যবহার করে
signing_key = consumer_secret + b"&" + token_secret
base_string = b"GET&https%3A%2F%2Fapi.service.com%2Fv1%2Forders&oauth_nonce%3D7f3a91bc"

sig = hmac.new(signing_key, base_string, hashlib.sha1).digest()

import base64
oauth_signature = base64.b64encode(sig).decode("ascii")
print(oauth_signature)
# "Tza3R9sE..."  — Authorization হেডারের জন্য URL-এনকোড করুন

HMAC-SHA512 — দীর্ঘ আউটপুট

Python 3.7+ — HMAC-SHA512
import hmac
import hashlib

key = b"high_security_signing_key_64_bytes_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
msg = b'{"transfer_id":"xfr_9c2e","amount":500000,"currency":"EUR"}'

h = hmac.new(key, msg, hashlib.sha512)

print(len(h.digest()))   # ৬৪ bytes (৫১২ বিট)
print(len(h.hexdigest()))  # ১২৮ হেক্স অক্ষর
print(h.hexdigest()[:40] + "...")
# "8e3a1f9b2c4d6e7f0a1b3c5d7e9f0a2b4c6d8e0f..."

HMAC-MD5 — শুধুমাত্র পুরনো সিস্টেমের জন্য

Python 3.7+ — HMAC-MD5
import hmac
import hashlib

# MD5 ক্রিপ্টোগ্রাফিকভাবে ভাঙা — শুধুমাত্র পুরনো প্রোটোকল সামঞ্জস্যের জন্য ব্যবহার করুন
key = b"legacy_api_key"
msg = b"action=charge&amount=1500&merchant=store_42"

sig = hmac.new(key, msg, hashlib.md5).hexdigest()
print(sig)  # ৩২-অক্ষরের হেক্স স্ট্রিং
# "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
সতর্কতা:HMAC-MD5 শুধুমাত্র পুরনো সিস্টেমের সাথে backward compatibilityের জন্য গ্রহণযোগ্য যেখান থেকে স্থানান্তর সম্ভব নয়। যেকোনো নতুন প্রকল্পে ন্যূনতম HMAC-SHA256 ব্যবহার করুন। HMAC মোডে কম প্রত্যক্ষভাবে শোষণযোগ্য হলেও MD5-এর পরিচিত কোলিশন দুর্বলতা রয়েছে, যা এটিকে দুর্বল ডিফল্ট পছন্দ করে তোলে।

hmac.new() প্যারামিটার রেফারেন্স

কনস্ট্রাক্টর স্বাক্ষর হল hmac.new(key, msg=None, digestmod)। মডিউলের সমস্ত তিনটি ফাংশন চাবি ও অ্যালগরিদম আর্গুমেন্টের একই প্যাটার্ন অনুসরণ করে।

hmac.new() কনস্ট্রাক্টর

প্যারামিটার
ধরন
ডিফল্ট
বিবরণ
key
bytes | bytearray
(আবশ্যক)
গোপন চাবি — অবশ্যই bytes হতে হবে, str নয়
msg
bytes | None
None
হ্যাশ করার প্রাথমিক বার্তা; পরে .update() দিয়ে আরও ডেটা যোগ করা যায়
digestmod
str | callable
(আবশ্যক)
হ্যাশ অ্যালগরিদম — যেমন hashlib.sha256 অথবা "sha256" স্ট্রিং

hmac.digest() এককালীন (Python 3.7+)

প্যারামিটার
ধরন
বিবরণ
key
bytes
গোপন চাবি
msg
bytes
যাচাই করার বার্তা
digest
str | callable
হ্যাশ অ্যালগরিদম — hmac.new()-এর digestmod-এর মতোই

digestmod প্যারামিটার একটি callable (যেমন hashlib.sha256) বা একটি স্ট্রিং নাম (যেমন "sha256") গ্রহণ করে। callable ফর্ম পছন্দনীয় কারণ এটি আমদানির সময় যাচাই হয় — স্ট্রিং ফর্মে ভুল টাইপিং শুধুমাত্র রানটাইমে ব্যর্থ হয়।

hmac.digest() — দ্রুত এককালীন HMAC (Python 3.7+)

Python 3.7 মডিউল-স্তরীয় ফাংশন হিসেবে hmac.digest(key, msg, digest) যোগ করেছে। এটি মধ্যবর্তী HMAC অবজেক্ট তৈরি না করেই একটি মাত্র কলে HMAC গণনা করে। ফেরত মান হল কাঁচা bytes (অবজেক্টে .digest() কল করার সমতুল্য)। এই ফাংশন CPython-এ অপ্টিমাইজড C বাস্তবায়ন ব্যবহার করে এবং অবজেক্ট বরাদ্দের ওভারহেড এড়ায়, যা সঘন লুপে পরিমাপযোগ্যভাবে দ্রুত।

Python 3.7+ — hmac.digest() এককালীন
import hmac
import hashlib

key = b"batch_signing_key_2026"
messages = [
    b'{"order_id":"ord_001","total":4500}',
    b'{"order_id":"ord_002","total":8900}',
    b'{"order_id":"ord_003","total":2200}',
]

# এককালীন ডাইজেস্ট — মধ্যবর্তী HMAC অবজেক্ট নেই
signatures = [hmac.digest(key, msg, hashlib.sha256) for msg in messages]

# প্রদর্শনের জন্য হেক্সে রূপান্তর করুন
for msg, sig in zip(messages, signatures):
    print(f"{msg[:30]}... -> {sig.hex()[:24]}...")

সীমাবদ্ধতা: hmac.digest() শুধুমাত্র কাঁচা bytes ফেরত দেয়। সরাসরি হেক্স স্ট্রিং দরকার হলে এখনো hmac.new() এবং এর .hexdigest() মেথড প্রয়োজন, অথবা bytes ফলাফলে .hex() চেইন করুন।

নোট:hmac.digest() ক্রমান্বয়ে .update() কল সমর্থন করে না। বড় ফাইল খণ্ডে পড়ে HMAC করতে হলে hmac.new() ব্যবহার করুন এবং লুপে .update(chunk) কল করুন।

ওয়েবহুক ও API প্রতিক্রিয়া থেকে HMAC স্বাক্ষর যাচাই

Python-এ HMAC-এর সবচেয়ে সাধারণ ব্যবহার হল ওয়েবহুক স্বাক্ষর যাচাই। প্রতিটি বড় প্রদানকারী (Stripe, GitHub, Shopify, Twilio) HMAC-SHA256 দিয়ে পেলোড স্বাক্ষর করে এবং হেডারে স্বাক্ষর পাঠায়। প্যাটার্ন সর্বদা একই: কাঁচা অনুরোধের বডির উপর HMAC পুনরায় গণনা করুন, তারপর hmac.compare_digest() দিয়ে তুলনা করুন।

ওয়েবহুক স্বাক্ষর যাচাই

Python 3.7+ — ওয়েবহুক HMAC যাচাই (Flask)
import hmac
import hashlib
from flask import Flask, request, abort

app = Flask(__name__)
WEBHOOK_SECRET = b"whsec_MbkP7x9yFqHGn3tRdWz5"

@app.route("/webhooks/payments", methods=["POST"])
def handle_payment_webhook():
    # কাঁচা বডি পান — যা স্বাক্ষরিত হয়েছিল তার সাথে হুবহু মিলতে হবে
    raw_body = request.get_data()

    # হেডার থেকে স্বাক্ষর পান
    received_sig = request.headers.get("X-Signature-256", "")

    # কাঁচা বডির উপর HMAC পুনরায় গণনা করুন
    expected_sig = hmac.new(WEBHOOK_SECRET, raw_body, hashlib.sha256).hexdigest()

    # স্থির-সময় তুলনা — টাইমিং আক্রমণ প্রতিরোধ করে
    if not hmac.compare_digest(f"sha256={expected_sig}", received_sig):
        abort(403, "Invalid signature")

    # স্বাক্ষর যাচাই হয়েছে — ইভেন্ট প্রক্রিয়া করুন
    event = request.get_json()
    print(f"Verified event: {event['type']} for {event['data']['amount']}")
    return "", 200

hmac.compare_digest() ফাংশন দুটি স্ট্রিং বা byte ক্রম স্থির সময়ে তুলনা করে। একটি সাধারণ == তুলনা প্রথম অমিল বাইটেই সংক্ষিপ্ত হয়। একজন আক্রমণকারী অনেক অনুরোধে প্রতিক্রিয়া সময় পরিমাপ করে ধীরে ধীরে প্রত্যাশিত স্বাক্ষর বাইট-বাইট পুনর্গঠন করতে পারে। স্থির-সময় তুলনা এই পার্শ্বচ্যানেল দূর করে।

GitHub ওয়েবহুক যাচাই

GitHub-এর ওয়েবহুক ফরম্যাট পূর্ণ প্যাটার্নটি স্পষ্টভাবে দেখায়। এটি একটি X-Hub-Signature-256 হেডার পাঠায় যাতে sha256= এবং তারপর কাঁচা অনুরোধের বডির হেক্স-এনকোডেড HMAC-SHA256 থাকে, আপনার রিপোজিটরি সেটিংসে কনফিগার করা ওয়েবহুক সিক্রেট দিয়ে স্বাক্ষরিত। সাধারণ ওয়েবহুক যাচাইয়ের মূল পার্থক্য হল তুলনার আগে sha256= উপসর্গ সরাতে হবে, এবং অনুরোধের বডির কাঁচা bytes পড়তে হবে — আগে JSON পার্স করলে byte উপস্থাপনা পরিবর্তিত হয় এবং যাচাই ভেঙে যায়।

Python 3.7+ — GitHub X-Hub-Signature-256 যাচাই
import hmac
import hashlib
from flask import Flask, request, abort

app = Flask(__name__)
GITHUB_WEBHOOK_SECRET = b"your_github_webhook_secret"

@app.route("/webhooks/github", methods=["POST"])
def handle_github_webhook():
    # GitHub পাঠায়: X-Hub-Signature-256: sha256=<hex_digest>
    sig_header = request.headers.get("X-Hub-Signature-256", "")

    if not sig_header.startswith("sha256="):
        abort(403, "Missing or malformed signature header")

    received_hex = sig_header[len("sha256="):]
    raw_body = request.get_data()  # কাঁচা bytes — এর আগে JSON পার্স করবেন না

    expected_hex = hmac.new(
        GITHUB_WEBHOOK_SECRET, raw_body, hashlib.sha256
    ).hexdigest()

    if not hmac.compare_digest(expected_hex, received_hex):
        abort(403, "Signature mismatch — payload may have been tampered with")

    event_type = request.headers.get("X-GitHub-Event", "unknown")
    payload = request.get_json()
    print(f"Verified GitHub {event_type} event: {payload.get('action', '')}")
    return "", 200

একই প্যাটার্ন Shopify (X-Shopify-Hmac-SHA256) এবং Twilio (X-Twilio-Signature)-এ প্রযোজ্য, শুধু হেডার নাম ও স্বাক্ষর হেক্স নাকি Base64-এনকোডেড তা আলাদা। এনকোডিং ফরম্যাট নিশ্চিত করতে সর্বদা প্রদানকারীর ডকুমেন্টেশন দেখুন — হেক্স ও Base64 মেশানো স্বাক্ষর অমিলের সবচেয়ে সাধারণ কারণ।

HMAC দিয়ে API অনুরোধ প্রমাণীকরণ

কিছু API-এর ক্লায়েন্টকে HMAC দিয়ে প্রতিটি রিকোয়েস্ট সাইন করতে হয়। সাইনড স্ট্রিং-এ সাধারণত HTTP মেথড, পাথ, টাইমস্ট্যাম্প ও রিকোয়েস্ট বডি থাকে। internal service-to-service authentication-এ এই প্যাটার্নটা খুব কমন।

Python 3.7+ — HMAC-SHA256 দিয়ে API অনুরোধ স্বাক্ষর করা
import hmac
import hashlib
import time
import json

def sign_request(secret: bytes, method: str, path: str, body: str) -> dict:
    """API অনুরোধের জন্য HMAC-SHA256 স্বাক্ষর তৈরি করুন।"""
    timestamp = str(int(time.time()))

    # স্বাক্ষর স্ট্রিং তৈরি করুন — method + path + timestamp + body
    signing_string = f"{method}\n{path}\n{timestamp}\n{body}"

    signature = hmac.new(
        secret,
        signing_string.encode(),
        hashlib.sha256
    ).hexdigest()

    return {
        "X-Timestamp": timestamp,
        "X-Signature": signature,
    }

# ব্যবহার
api_secret = b"sk_hmac_9f3a2b7c4d8e1a6f"
body = json.dumps({"customer_id": "cust_4421", "action": "suspend_account"})

headers = sign_request(api_secret, "POST", "/api/v2/customers/actions", body)
print(headers)
# {"X-Timestamp": "1711612200", "X-Signature": "a3f1b9c0..."}

requests লাইব্রেরি দিয়ে HTTP অনুরোধ স্বাক্ষর করা

Python 3.7+ — requests লাইব্রেরি দিয়ে HMAC-স্বাক্ষরিত অনুরোধ
import hmac
import hashlib
import time
import json
import requests

API_SECRET = b"sk_hmac_9f3a2b7c4d8e1a6f"
BASE_URL = "https://api.billing-service.internal"

def make_signed_request(method: str, path: str, payload: dict) -> requests.Response:
    body = json.dumps(payload, separators=(",", ":"))  # সংক্ষিপ্ত JSON, নির্ধারণীয়
    timestamp = str(int(time.time()))

    signing_string = f"{method}\n{path}\n{timestamp}\n{body}"
    signature = hmac.new(API_SECRET, signing_string.encode(), hashlib.sha256).hexdigest()

    headers = {
        "Content-Type": "application/json",
        "X-Timestamp": timestamp,
        "X-Signature": f"hmac-sha256={signature}",
    }

    try:
        return requests.request(method, f"{BASE_URL}{path}", data=body, headers=headers)
    except requests.RequestException as e:
        raise RuntimeError(f"Signed request failed: {e}") from e

# একটি স্বাক্ষরিত POST অনুরোধ পাঠান
resp = make_signed_request("POST", "/api/v2/invoices", {
    "customer_id": "cust_4421",
    "line_items": [
        {"description": "Pro plan - March 2026", "amount": 4900},
        {"description": "Extra seats (3)", "amount": 2100},
    ],
})
print(resp.status_code, resp.json())

দ্রষ্টব্য: স্বাক্ষরের জন্য বডি ক্রমবদ্ধ করার সময় separators=(",", ":") ব্যবহার করুন। ডিফল্ট json.dumps() বিভাজকের পরে ফাঁকা স্থান যোগ করে, যা byte উপস্থাপনা পরিবর্তন করে এবং সার্ভার ভিন্নভাবে ক্রমবদ্ধ করলে স্বাক্ষর যাচাই ভেঙে যায়। সংক্ষিপ্ত JSON একটি প্রমাণিক রূপ দেয়।

কমান্ড-লাইনে HMAC তৈরি করা

কখনো কখনো স্ক্রিপ্ট না লিখেই HMAC গণনা করতে হয়। Python-এর -c ফ্ল্যাগ ও openssl উভয়ই টার্মিনাল থেকে এটি সামলাতে পারে।

bash — Python ওয়ান-লাইনার দিয়ে HMAC-SHA256
python3 -c "
import hmac, hashlib
print(hmac.new(b'my_secret', b'message_to_sign', hashlib.sha256).hexdigest())
"
# আউটপুট: ৬৪-অক্ষরের হেক্স স্ট্রিং
bash — openssl দিয়ে HMAC-SHA256 (তুলনার জন্য)
echo -n "message_to_sign" | openssl dgst -sha256 -hmac "my_secret"
# SHA2-256(stdin)= 7d11...

# ফাইল openssl HMAC-এর মধ্যে দিয়ে পাস করুন
openssl dgst -sha256 -hmac "my_secret" < payload.json
bash — এনভায়রনমেন্ট ভেরিয়েবল চাবি থেকে HMAC
# শেল ইতিহাস প্রকাশ এড়াতে চাবি env ভেরিয়েবলে সংরক্ষণ করুন
export HMAC_KEY="sk_live_9f3a2b"
echo -n '{"event":"test"}' | python3 -c "
import hmac, hashlib, sys, os
key = os.environ['HMAC_KEY'].encode()
msg = sys.stdin.buffer.read()
print(hmac.new(key, msg, hashlib.sha256).hexdigest())
"
নোট:echo -n ফ্ল্যাগটি গুরুত্বপূর্ণ — এটি ছাড়া echo বার্তার শেষে একটি নতুন লাইন অক্ষর যোগ করে, যা HMAC আউটপুট পরিবর্তন করে দেয়। টার্মিনাল থেকে ডিবাগ করার সময় স্বাক্ষর অমিলের এটি সবচেয়ে সাধারণ কারণ।

উচ্চ-কার্যক্ষমতার বিকল্প — cryptography লাইব্রেরি

অধিকাংশ অ্যাপ্লিকেশনের জন্য স্ট্যান্ডার্ড hmac মডিউল যথেষ্ট দ্রুত। TLS বা সার্টিফিকেট হ্যান্ডলিংয়ের জন্য আপনি যদি ইতিমধ্যে cryptography লাইব্রেরি ব্যবহার করেন, এটি OpenSSL-সমর্থিত HMAC-ও সরবরাহ করে। stdlib থেকে মূল ব্যবহারিক পার্থক্য হল নিচে বর্ণিত ব্যতিক্রম-ভিত্তিক .verify() API — অমিলে boolean ফেরানোর বদলে এটি ব্যতিক্রম উত্থাপন করে যা ডেভেলপার ভুলে যাচাই না করতে পারেন।

bash — cryptography ইনস্টল করুন
pip install cryptography
Python 3.7+ — cryptography লাইব্রেরি দিয়ে HMAC
from cryptography.hazmat.primitives import hashes, hmac as crypto_hmac

key = b"webhook_signing_key_2026"
message = b'{"event":"subscription.renewed","plan":"enterprise"}'

h = crypto_hmac.HMAC(key, hashes.SHA256())
h.update(message)
signature = h.finalize()  # কাঁচা bytes

print(signature.hex())
# "9c4e2a..."

# যাচাই মোড — অমিলে InvalidSignature উত্থাপন করে
h_verify = crypto_hmac.HMAC(key, hashes.SHA256())
h_verify.update(message)
h_verify.verify(signature)  # ভুল হলে cryptography.exceptions.InvalidSignature উত্থাপন করে

cryptography লাইব্রেরির .verify() মেথড বিশেষভাবে সুবিধাজনক: boolean ফেরানোর বদলে অমিলে ব্যতিক্রম উত্থাপন করে। এটি যাচাই ব্যর্থতা ভুলবশত উপেক্ষা করা কঠিন করে তোলে। স্ট্যান্ডার্ড লাইব্রেরির hmac.compare_digest() True/ False ফেরত দেয়, যা ডেভেলপার ফেরত মান যাচাই করতে ভুলে গেলে নীরবে উপেক্ষিত হতে পারে।

সিনট্যাক্স হাইলাইটিং সহ টার্মিনাল আউটপুট

টার্মিনালে HMAC স্বাক্ষর ডিবাগ করার সময় রঙিন আউটপুট চাইলে rich এটি ভালোভাবে সামলায়।

bash — rich ইনস্টল করুন
pip install rich
Python 3.7+ — rich দিয়ে রঙিন HMAC আউটপুট
import hmac
import hashlib
from rich.console import Console
from rich.table import Table

console = Console()

key = b"debug_signing_key"
messages = {
    "/api/v2/orders": b'{"status":"active"}',
    "/api/v2/invoices": b'{"status":"pending"}',
    "/api/v2/customers": b'{"status":"verified"}',
}

table = Table(title="HMAC-SHA256 Signatures")
table.add_column("Endpoint", style="cyan")
table.add_column("Signature (first 32 chars)", style="green")

for endpoint, body in messages.items():
    sig = hmac.new(key, body, hashlib.sha256).hexdigest()
    table.add_row(endpoint, sig[:32] + "...")

console.print(table)
নোট:Rich শুধুমাত্র টার্মিনাল প্রদর্শনের জন্য। ফাইল, HTTP হেডার বা লগ একত্রীকরণ সিস্টেমে HMAC স্বাক্ষর লেখার সময় এটি ব্যবহার করবেন না — ANSI এস্কেপ কোড আউটপুট নষ্ট করে দেবে।

বড় ফাইল নিয়ে কাজ — ক্রমান্বয়ে HMAC

৫০ MB বা তার বেশি ফাইলের জন্য শুধু HMAC গণনার জন্য সব কিছু মেমোরিতে লোড করা অপচয়। HMAC অবজেক্টের .update() মেথড আপনাকে খণ্ডে খণ্ডে ডেটা দিতে দেয়। এটি ফাইলের আকার নির্বিশেষে মেমোরি ব্যবহার স্থির রাখে।

Python 3.7+ — বড় ফাইল খণ্ডে HMAC করা
import hmac
import hashlib

def hmac_file(key: bytes, filepath: str, chunk_size: int = 8192) -> str:
    """পুরো ফাইল মেমোরিতে না নিয়ে HMAC-SHA256 গণনা করুন।"""
    h = hmac.new(key, digestmod=hashlib.sha256)

    try:
        with open(filepath, "rb") as f:
            while True:
                chunk = f.read(chunk_size)
                if not chunk:
                    break
                h.update(chunk)
    except OSError as e:
        raise OSError(f"Cannot read file '{filepath}': {e}") from e

    return h.hexdigest()

# ২ GB ডেটাবেস এক্সপোর্ট স্বাক্ষর করুন
signing_key = b"backup_integrity_key_2026"
signature = hmac_file(signing_key, "/var/backups/db-export-2026-03.sql.gz")
print(f"HMAC-SHA256: {signature}")
Python 3.7+ — ডাউনলোড করা ফাইলের HMAC স্বাক্ষর যাচাই
import hmac
import hashlib

def verify_file_hmac(key: bytes, filepath: str, expected_hex: str) -> bool:
    """ফাইলের HMAC-SHA256 স্বাক্ষর যাচাই করুন।"""
    h = hmac.new(key, digestmod=hashlib.sha256)

    with open(filepath, "rb") as f:
        for chunk in iter(lambda: f.read(65536), b""):
            h.update(chunk)

    return hmac.compare_digest(h.hexdigest(), expected_hex)

# ডাউনলোড করা আর্টিফ্যাক্ট যাচাই করুন
is_valid = verify_file_hmac(
    key=b"release_signing_key",
    filepath="/tmp/release-v3.2.0.tar.gz",
    expected_hex="8e3a1f9b2c4d6e7f0a1b3c5d7e9f0a2b4c6d8e0f1a2b3c4d5e6f7a8b9c0d1e2f",
)
print(f"File integrity: {'valid' if is_valid else 'CORRUPTED'}")
নোট:ফাইল ৫০-১০০ MB ছাড়িয়ে গেলে বা ওয়েব সার্ভারে আপলোড প্রক্রিয়া করার সময় যেখানে প্রতি অনুরোধে মেমোরি গুরুত্বপূর্ণ, সেখানে খণ্ডিত HMAC-এ স্যুইচ করুন। .update() পদ্ধতি ফাইলের আকার নির্বিশেষে স্থির chunk_size মেমোরি ব্যবহার করে। আমি ডিফল্ট হিসেবে ৬৪ KB খণ্ড ব্যবহার করি — syscall ওভারহেড কমানোর জন্য যথেষ্ট বড়, এবং অধিকাংশ হার্ডওয়্যারের L2 ক্যাশে ধরে রাখার জন্য যথেষ্ট ছোট।

Python-এ ক্রিপ্টোগ্রাফিকভাবে নিরাপদ HMAC চাবি তৈরি করা

দুর্বল বা অনুমানযোগ্য চাবি সম্পূর্ণ HMAC নির্মাণকে দুর্বল করে দেয়। secrets মডিউল (Python 3.6+) ক্রিপ্টোগ্রাফিকভাবে শক্তিশালী র‍্যান্ডম bytes সরবরাহ করে। HMAC-SHA256-এর জন্য ৩২-বাইট চাবি ব্যবহার করুন। HMAC-SHA512-এর জন্য ৬৪ বাইট। এগুলো সংশ্লিষ্ট হ্যাশ অ্যালগরিদমের অভ্যন্তরীণ ব্লক আকারের সাথে মিলে যায়, যা RFC 2104 অনুযায়ী সর্বোত্তম চাবির দৈর্ঘ্য।

Python 3.7+ — secrets দিয়ে HMAC চাবি তৈরি করুন
import secrets

# হ্যাশ অ্যালগরিদমের ব্লক আকারের সাথে মিলিয়ে চাবি তৈরি করুন
sha256_key = secrets.token_bytes(32)   # ২৫৬ বিট — HMAC-SHA256-এর জন্য
sha512_key = secrets.token_bytes(64)   # ৫১২ বিট — HMAC-SHA512-এর জন্য

# হেক্স উপস্থাপনা — কনফিগ ফাইল ও এনভায়রনমেন্ট ভেরিয়েবলের জন্য নিরাপদ
print(f"HMAC-SHA256 key: {sha256_key.hex()}")
# যেমন "a3f1b9c04e7d2f8a1b3c5d7e9f0a2b4c6d8e0f1a2b3c4d5e6f7a8b9c0d1e2f"

print(f"HMAC-SHA512 key: {sha512_key.hex()}")
# ১২৮-অক্ষরের হেক্স স্ট্রিং

# URL-নিরাপদ Base64 — সংক্ষিপ্ত, HTTP হেডারের জন্য নিরাপদ
import base64
b64_key = base64.urlsafe_b64encode(sha256_key).decode("ascii")
print(f"Base64 key: {b64_key}")
# যেমন "o_G5wE59L4obPF1-nwortG2ODwobPExdXnqLnA0dLi8="
সতর্কতা:HMAC চাবির জন্য random মডিউল থেকে random.random() বা random.randbytes() কখনো ব্যবহার করবেন না। ডিফল্ট random মডিউল Mersenne Twister PRNG ব্যবহার করে, যা ৬২৪টি আউটপুট পর্যবেক্ষণের পরে অনুমানযোগ্য। নিরাপত্তা-সংবেদনশীল র‍্যান্ডমনেসের জন্য সর্বদা secrets.token_bytes() ব্যবহার করুন।

চাবির দৈর্ঘ্য ও RFC 2104 প্রয়োজনীয়তা

RFC 2104 নির্দিষ্ট করে যে HMAC চাবি যেকোনো দৈর্ঘ্যের হতে পারে, তবে কমপক্ষে L bytes-এর চাবি সুপারিশ করে — যেখানে L হল অন্তর্নিহিত হ্যাশ ফাংশনের আউটপুট দৈর্ঘ্য। HMAC-SHA256-এর জন্য এটি ৩২ bytes (২৫৬ বিট)। L বিটের চেয়ে ছোট চাবি আনুপাতিকভাবে নিরাপত্তা মার্জিন কমিয়ে দেয়। হ্যাশের ব্লক আকারের (SHA-256-এর জন্য ৬৪ bytes, SHA-512-এর জন্য ১২৮ bytes) চেয়ে দীর্ঘ চাবি প্রথমে ব্লক আকারে হ্যাশ করা হয়, তাই ব্লক আকারের চেয়ে বড় চাবি ব্যবহারে কোনো সুবিধা নেই। HMAC-SHA256-এর জন্য ৩২ bytes এবং HMAC-SHA512-এর জন্য ৬৪ bytes ব্যবহার করুন।

নিরাপদ চাবি সংরক্ষণ ও আবর্তন

সোর্স কোডে HMAC চাবি কখনো হার্ডকোড করবেন না। উৎপাদন ডিপ্লয়মেন্টের জন্য প্রমাণিত পদ্ধতি হল স্টার্টআপে এনভায়রনমেন্ট ভেরিয়েবল থেকে চাবি লোড করা: os.environ["HMAC_SECRET"].encode()। উচ্চ-নিশ্চয়তার পরিবেশে AWS Secrets Manager, HashiCorp Vault বা GCP Secret Manager-এর মতো সিক্রেটস ম্যানেজমেন্ট সিস্টেমে চাবি সংরক্ষণ করুন এবং রানটাইমে আনুন। এই সিস্টেমগুলো অডিট লগ, অ্যাক্সেস নিয়ন্ত্রণ এবং কোড ডিপ্লয় ছাড়াই স্বয়ংক্রিয় আবর্তন সরবরাহ করে।

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

hmac.new() দিয়ে bytearray ও memoryview ব্যবহার

hmac.new() ফাংশন key ও msg উভয় প্যারামিটারে যেকোনো bytes-সদৃশ অবজেক্ট গ্রহণ করে। এর মানে আপনি কপি বা রূপান্তর ছাড়াই সরাসরি bytes, bytearray, বা memoryview পাস করতে পারেন। এটি দুটি পরিস্থিতিতে সবচেয়ে গুরুত্বপূর্ণ: নেটওয়ার্ক প্রোটোকল বাস্তবায়নে যেখানে socket.recv_into() পূর্ব-বরাদ্দ bytearray বাফারে ডেটা লেখে, এবং উচ্চ-থ্রুপুট সিস্টেমে যেখানে মধ্যবর্তী কপি এড়ানো GC চাপ কমায়। একটি memoryview স্লাইস শূন্য-কপি: এটি নতুন মেমোরি বরাদ্দ না করে মূল বাফারে একটি উইন্ডো প্রকাশ করে। প্রতি সেকেন্ডে হাজার হাজার বার্তায়, সেই বরাদ্দগুলো দূর করা লেটেন্সি ও থ্রুপুটে পরিমাপযোগ্য পার্থক্য আনে।

Python 3.7+ — HMAC-এর সাথে bytearray ও memoryview
import hmac
import hashlib

# bytearray — পরিবর্তনযোগ্য bytes, বাইনারি প্রোটোকল বাফারের জন্য উপযোগী
key = bytearray(b"protocol_signing_key")
frame = bytearray(b'\x01\x02\x03\x04payload_data_here')

sig = hmac.new(key, frame, hashlib.sha256).hexdigest()
print(f"Frame signature: {sig[:32]}...")

# memoryview — বড় বাফারের শূন্য-কপি স্লাইস
large_buffer = bytearray(4096)
large_buffer[:20] = b"sensor_reading_12345"

# কপি না করে শুধু প্রথম ২০ bytes-এর HMAC করুন
view = memoryview(large_buffer)[:20]
sig = hmac.new(key, view, hashlib.sha256).hexdigest()
print(f"Sensor signature: {sig[:32]}...")

সাধারণ ভুলসমূহ

ওয়েবহুক হ্যান্ডলার সম্পর্কিত প্রায় প্রতিটি কোড রিভিউতে প্রথম দুটি ভুল আমি দেখি। সময়ের চাপে এগুলো সহজে ঢুকে পড়ে এবং কী খুঁজতে হবে না জানলে ধরা কঠিন।

hmac.compare_digest()-এর বদলে == দিয়ে HMAC স্বাক্ষর তুলনা করা

সমস্যা: == অপারেটর প্রথম byte অমিলে সংক্ষিপ্ত হয়, টাইমিং তথ্য ফাঁস করে যা আক্রমণকারীকে প্রত্যাশিত স্বাক্ষর ধীরে ধীরে পুনর্গঠন করতে দেয়।

সমাধান: স্বাক্ষর তুলনায় সর্বদা hmac.compare_digest() ব্যবহার করুন — এটি অমিল যেখানেই হোক স্থির সময়ে চলে।

Before · Python
After · Python
received_sig = request.headers["X-Signature"]
expected_sig = hmac.new(key, body, hashlib.sha256).hexdigest()

if received_sig == expected_sig:  # টাইমিং আক্রমণের ঝুঁকি
    process_webhook(body)
received_sig = request.headers["X-Signature"]
expected_sig = hmac.new(key, body, hashlib.sha256).hexdigest()

if hmac.compare_digest(received_sig, expected_sig):  # স্থির-সময়
    process_webhook(body)
hmac.new()-এ bytes-এর বদলে স্ট্রিং পাস করা

সমস্যা: hmac.new()-এ bytes-সদৃশ অবজেক্ট প্রয়োজন। Python str পাস করলে TypeError: "key: expected bytes or bytearray, but got 'str'" উত্থাপিত হয়।

সমাধান: hmac.new()-এ পাস করার আগে স্ট্রিং চাবি ও বার্তায় .encode() কল করুন।

Before · Python
After · Python
key = "my_api_secret"  # str, bytes নয়
msg = '{"event":"test"}'  # str, bytes নয়
sig = hmac.new(key, msg, hashlib.sha256)  # TypeError!
key = "my_api_secret"
msg = '{"event":"test"}'
sig = hmac.new(key.encode(), msg.encode(), hashlib.sha256)
digestmod ভুলে যাওয়া (Python 3.4+)

সমস্যা: তৃতীয় আর্গুমেন্ট ছাড়া hmac.new(key, msg) কল করলে TypeError উত্থাপিত হয়। Python 3.4-এর আগে এটি MD5-এ ডিফল্ট ছিল, কিন্তু নিরাপত্তার কারণে ডিফল্ট সরিয়ে দেওয়া হয়েছে।

সমাধান: সর্বদা অ্যালগরিদম স্পষ্টভাবে পাস করুন: hashlib.sha256, hashlib.sha512, বা আপনার প্রোটোকলে যেটি প্রয়োজন।

Before · Python
After · Python
# digestmod অনুপস্থিত — Python 3.4+-এ TypeError উত্থাপন করে
sig = hmac.new(key, msg).hexdigest()
# সর্বদা হ্যাশ অ্যালগরিদম নির্দিষ্ট করুন
sig = hmac.new(key, msg, hashlib.sha256).hexdigest()
প্রদানকারী Base64 প্রত্যাশা করলে .hexdigest() ব্যবহার করা

সমস্যা: অনেক ওয়েবহুক প্রদানকারী (Stripe, Shopify) Base64-এনকোডেড স্বাক্ষর পাঠায়, হেক্স নয়। হেক্স স্ট্রিং Base64 মানের বিপরীতে তুলনা করলে সবসময় ব্যর্থ হয়, সব ওয়েবহুক প্রত্যাখ্যাত হয়।

সমাধান: স্বাক্ষর ফরম্যাটের জন্য প্রদানকারীর ডকুমেন্টেশন দেখুন। Base64 ব্যবহার হলে .hexdigest() স্ট্রিং নয়, কাঁচা .digest() bytes এনকোড করুন।

Before · Python
After · Python
# প্রদানকারী Base64 পাঠায়, কিন্তু আমরা হেক্স গণনা করি — কখনো মেলে না
expected = hmac.new(key, body, hashlib.sha256).hexdigest()
# "a3f1b9c0..."  বনাম  "o/G5wE59..."  — সবসময় অমিল
import base64
# প্রদানকারীর ফরম্যাট মেলান: কাঁচা bytes → Base64
raw = hmac.new(key, body, hashlib.sha256).digest()
expected = base64.b64encode(raw).decode("ascii")
# "o/G5wE59..."  — হেডারের সাথে মেলে

stdlib hmac বনাম cryptography — দ্রুত তুলনা

মেথড
অ্যালগরিদম
আউটপুট
স্ট্রিমিং
কাস্টম টাইপ
ইনস্টল প্রয়োজন
hmac.new() + hexdigest()
যেকোনো hashlib
হেক্স স্ট্রিং
✓ .update() দিয়ে
প্রযোজ্য নয়
না (stdlib)
hmac.new() + digest()
যেকোনো hashlib
কাঁচা bytes
✓ .update() দিয়ে
প্রযোজ্য নয়
না (stdlib)
hmac.digest()
যেকোনো hashlib
কাঁচা bytes
✗ (এককালীন)
প্রযোজ্য নয়
না (stdlib, 3.7+)
hashlib.sha256 (সাধারণ হ্যাশ)
শুধু SHA-256
হেক্স বা bytes
✓ .update() দিয়ে
প্রযোজ্য নয়
না (stdlib)
cryptography (HMAC)
যেকোনো
কাঁচা bytes
✓ .update() দিয়ে
প্রযোজ্য নয়
pip install
pyca/cryptography + CMAC
AES-CMAC
কাঁচা bytes
✓ .update() দিয়ে
প্রযোজ্য নয়
pip install

ওয়েবহুক যাচাই, API স্বাক্ষর ও সাধারণ HMAC অপারেশনের জন্য stdlib hmac মডিউল ব্যবহার করুন — এর কোনো নির্ভরতা নেই এবং প্রতিটি প্রমাণিত অ্যালগরিদম কভার করে। ব্যাচ অপারেশনে এককালীন গতি গুরুত্বপূর্ণ হলে hmac.digest() ব্যবহার করুন। cryptography লাইব্রেরি শুধুমাত্র তখন ব্যবহার করুন যখন আপনি ইতিমধ্যে অন্য অপারেশনের (TLS, X.509, প্রতিসাম্য এনক্রিপশন) জন্য এটির উপর নির্ভর করছেন এবং ব্যতিক্রম-ভিত্তিক .verify() API চান। কোনো Python না লিখে দ্রুত স্বাক্ষর পরীক্ষার জন্য HMAC Generator টুল ব্যবহার করুন — চাবি ও বার্তা পেস্ট করুন, তাৎক্ষণিক ফলাফল পান।

সচরাচর জিজ্ঞাসা

Python-এ hmac.new() এবং hmac.digest()-এর মধ্যে পার্থক্য কী?

hmac.new() একটি HMAC অবজেক্ট ফেরত দেয় যা ক্রমান্বয়ে .update() কল সমর্থন করে এবং .digest() (কাঁচা bytes) ও .hexdigest() (হেক্স স্ট্রিং) উভয় দেয়। hmac.digest() Python 3.7-এ যোগ করা একটি এককালীন ফাংশন যা মধ্যবর্তী অবজেক্ট তৈরি না করেই সরাসরি কাঁচা bytes ফেরত দেয়। যখন সম্পূর্ণ বার্তা পাওয়া থাকে এবং শুধু ফলাফল দরকার তখন hmac.digest() ব্যবহার করুন। যখন ডেটা খণ্ডে খণ্ডে দিতে হবে বা হেক্স আউটপুট দরকার তখন hmac.new() ব্যবহার করুন।

Python
import hmac, hashlib

key = b"webhook_secret_2026"
body = b'{"event":"payment.completed","amount":9950}'

# এককালীন — কাঁচা bytes ফেরত দেয়
raw = hmac.digest(key, body, hashlib.sha256)

# অবজেক্ট-ভিত্তিক — ক্রমান্বয়ে আপডেট ও হেক্স আউটপুট সমর্থন করে
h = hmac.new(key, body, hashlib.sha256)
hex_sig = h.hexdigest()

Python-এ HMAC স্বাক্ষর কীভাবে যাচাই করব?

ভাগ করা গোপন চাবি ব্যবহার করে মূল বার্তার উপর HMAC পুনরায় গণনা করুন, তারপর hmac.compare_digest() দিয়ে তুলনা করুন। স্বাক্ষর তুলনায় কখনো == ব্যবহার করবেন না। == অপারেটর প্রথম অমিল বাইটেই সংক্ষিপ্ত হয় বলে প্রত্যাশিত স্বাক্ষরের দৈর্ঘ্য ও বিষয়বস্তু সম্পর্কে তথ্য ফাঁস করে দিতে পারে, যা টাইমিং আক্রমণের সুযোগ দেয়।

Python
import hmac, hashlib

def verify_signature(secret: bytes, message: bytes, received_sig: str) -> bool:
    expected = hmac.new(secret, message, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, received_sig)

Python HMAC SHA-256 কি hashlib.sha256 দিয়ে সাধারণ হ্যাশিংয়ের মতো?

না। hashlib.sha256 ইনপুটের একটি সাধারণ SHA-256 হ্যাশ গণনা করে, যা যেকেউ পুনরুৎপাদন করতে পারে। HMAC-SHA256 RFC 2104 অনুযায়ী হ্যাশ গণনায় একটি গোপন চাবি মিশিয়ে দেয়, তাই শুধুমাত্র চাবির অধিকারী সঠিক আউটপুট তৈরি বা যাচাই করতে পারে। সাধারণ হ্যাশ ডেটার অখণ্ডতা প্রমাণ করে। HMAC উভয় অখণ্ডতা ও সত্যতা প্রমাণ করে।

Python
import hmac, hashlib

msg = b"transfer:9950:USD"
key = b"api_secret_k8x2"

plain_hash = hashlib.sha256(msg).hexdigest()  # যেকেউ এটি গণনা করতে পারে
hmac_hash = hmac.new(key, msg, hashlib.sha256).hexdigest()  # চাবি প্রয়োজন

Python 3-এ কি HMAC-SHA1 ব্যবহার করা যায়?

হ্যাঁ, digestmod আর্গুমেন্ট হিসেবে hashlib.sha1 পাস করুন। HMAC-SHA1 Python 3-এ ঠিকঠাক কাজ করে এবং hmac মডিউলে এর জন্য কোনো অবচয় সতর্কতা নেই। তবে নতুন ডিজাইনে SHA-1 দুর্বল বলে বিবেচিত — এর কোলিশন প্রতিরোধ ক্ষমতা ৮০ বিটের নিচে এবং NIST ২০১৫ সালে অধিকাংশ ডিজিটাল স্বাক্ষর ব্যবহারে এটি অবচয় করেছে। আজকের দিনে HMAC-SHA1 ব্যবহারের মূল কারণ হল OAuth 1.0a বা কিছু পুরনো ওয়েবহুক সিস্টেমের মতো বিদ্যমান প্রোটোকলের সাথে backward compatibility। যখন উভয় পক্ষ নিয়ন্ত্রণ আপনার হাতে, সমস্ত নতুন কাজে HMAC-SHA256 বা HMAC-SHA512 পছন্দ করুন।

Python
import hmac, hashlib

key = b"oauth_consumer_secret"
base_string = b"GET&https%3A%2F%2Fapi.example.com&oauth_nonce%3Dabc123"
sig = hmac.new(key, base_string, hashlib.sha1).digest()

Python-এ নিরাপদ HMAC চাবি কীভাবে তৈরি করব?

স্ট্যান্ডার্ড লাইব্রেরির secrets.token_bytes() ব্যবহার করুন। HMAC-SHA256-এর জন্য ৩২-বাইট চাবি প্রমাণিত সুপারিশ কারণ এটি হ্যাশের ব্লক আকারের সাথে মিলে যায়। HMAC-SHA512-এর জন্য ৬৪ বাইট ব্যবহার করুন। অ্যাপ্লিকেশন কোডে চাবি তৈরিতে random.random() বা os.urandom() ব্যবহার করবেন না — Python 3.6 থেকে নিরাপত্তা-সংবেদনশীল র‍্যান্ডমনেসের জন্য secrets হল সঠিক মডিউল।

Python
import secrets

hmac_sha256_key = secrets.token_bytes(32)  # ২৫৬ বিট
hmac_sha512_key = secrets.token_bytes(64)  # ৫১২ বিট

# কনফিগ ফাইলের জন্য হেক্স হিসেবে সংরক্ষণ করুন
print(hmac_sha256_key.hex())
# যেমন "a3f1b9c04e..."

Python 3-এ hmac.new()-এ digestmod কেন আবশ্যক?

Python 3.4-এর আগে digestmod ডিফল্ট ছিল MD5, যা ক্রিপ্টোগ্রাফিকভাবে ভাঙা — MD5-এর পরিচিত কোলিশন আক্রমণ রয়েছে এবং নতুন নিরাপত্তা-সংবেদনশীল কোডে কখনো এটি ব্যবহার করা উচিত নয়। Python রক্ষণাবেক্ষণকারীরা ডিফল্টটি সরিয়ে দিয়েছেন যাতে ডেভেলপারদের অ্যালগরিদম স্পষ্টভাবে নির্বাচন করতে বাধ্য করা যায়। digestmod ছাড়া hmac.new(key, msg) কল করলে TypeError পাবেন। সর্বদা অ্যালগরিদম স্পষ্টভাবে পাস করুন: hashlib.sha256, hashlib.sha512 বা অন্য যেকোনো hashlib কনস্ট্রাক্টর। সন্দেহ হলে hashlib.sha256 নিরাপদ ডিফল্ট — কোনো পরিচিত দুর্বলতা নেই এবং যেকোনো ব্যবহারিক কাজের জন্য যথেষ্ট দ্রুত।

Python
import hmac, hashlib

key = b"secret"
msg = b"data"

# Python 3.4+-এ এটি TypeError উত্থাপন করে
# hmac.new(key, msg)  # TypeError: missing required argument: 'digestmod'

# সর্বদা অ্যালগরিদম নির্দিষ্ট করুন
h = hmac.new(key, msg, hashlib.sha256)

Python স্ক্রিপ্ট চালু না করে দ্রুত HMAC পরীক্ষার জন্য, চাবি ও বার্তা অনলাইন HMAC Generator-এ পেস্ট করুন — এটি SHA-256, SHA-384 ও SHA-512 তাৎক্ষণিক ফলাফল সহ সমর্থন করে।

সংশ্লিষ্ট টুলসমূহ

DV
Dmitri VolkovDevOps Engineer & Python Automation Specialist

Dmitri is a DevOps engineer who relies on Python as his primary scripting and automation language. He builds internal tooling, CI/CD pipelines, and infrastructure automation scripts that run in production across distributed teams. He writes about the Python standard library, subprocess management, file processing, encoding utilities, and the practical shell-adjacent Python that DevOps engineers use every day.

MS
Maria Santosপ্রযুক্তিগত পর্যালোচক

Maria is a backend developer specialising in Python and API integration. She has broad experience with data pipelines, serialisation formats, and building reliable server-side services. She is an active member of the Python community and enjoys writing practical, example-driven guides that help developers solve real problems without unnecessary theory.