ToolDeck

HMAC در Python — راهنمای hmac.new()‎ SHA-256 + مثال‌های کد

·DevOps Engineer & Python Automation Specialist·بررسی‌شده توسطMaria Santos·منتشر شده

از تولیدکننده HMAC آنلاین رایگان مستقیم در مرورگرتان استفاده کنید — نیازی به نصب نیست.

امتحان کردن تولیدکننده HMAC آنلاین ←

هر callback وب‌هوک، هر درخواست API امضاشده، هر رویداد Stripe یا GitHub از یک امضای HMAC برای تضمین یکپارچگی محتوا استفاده می‌کند. ماژول hmac در Python با یک فراخوانی تابع، HMAC-SHA256 در Python را پیاده‌سازی می‌کند: hmac.new(key, msg, hashlib.sha256). بدون pip install، بدون افزونه C، بدون وابستگی خارجی. برای بررسی سریع امضا بدون نوشتن کد، مولد آنلاین HMAC نتیجه را فوری ارائه می‌دهد. این راهنما شامل 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 استفاده نکنید.
  • خروجی خام .digest() را برای هدرهای HTTP و امضاهای وب‌هوک به Base64 تبدیل کنید: base64.b64encode(h.digest()).
  • ماژول hmac هر الگوریتم hashlib را می‌پذیرد: sha1، sha256، sha384، sha512، md5، blake2b.

HMAC چیست؟

HMAC (کد احراز هویت پیام مبتنی بر هش) یک ساختار تعریف‌شده در RFC 2104 است که یک کلید محرمانه را با یک تابع هش ترکیب می‌کند تا یک برچسب احراز هویت با اندازه ثابت تولید کند. بر خلاف هش ساده (که هر کسی می‌تواند آن را محاسبه کند)، یک HMAC نیاز به دانستن کلید محرمانه دارد. این یعنی می‌توانید از آن برای تأیید هم صحت و هم اصالت یک پیام استفاده کنید. اگر حتی یک بایت از پیام یا کلید تغییر کند، خروجی کاملاً متفاوت خواهد بود. این ساختار با هش کردن کلید XOR شده با دو ثابت پدینگ مختلف (ipad و opad) کار می‌کند و پیام را بین دو عملیات هش قرار می‌دهد. ماژول hmac Python این RFC را مستقیماً پیاده‌سازی می‌کند.

After · Python
Before · Python
# HMAC-SHA256 — برای تولید به کلید محرمانه نیاز دارد
hmac.new(b"api_secret", b"payment:9950:USD", hashlib.sha256).hexdigest()
# "e4f2a8..."  (فقط دارنده کلید می‌تواند محاسبه کند)
# هش SHA-256 ساده — بدون کلید محرمانه، هر کسی می‌تواند محاسبه کند
hashlib.sha256(b"payment:9950:USD").hexdigest()
# "7a3b1c..."  (قطعی، عمومی)

hmac.new() — نقطه ورود کتابخانه استاندارد

ماژول hmac بخشی از کتابخانه استاندارد Python است. دو import و آماده‌اید: import hmac, hashlib. سه تابع اصلی عبارتند از hmac.new() (یک شیء HMAC می‌سازد)، hmac.digest() (یک‌مرحله‌ای، Python 3.7+)، و hmac.compare_digest() (مقایسه با زمان ثابت). نیازی به pip install نیست.

hmac.new(key, msg, digestmod) سه آرگومان می‌گیرد. هر دوی key و msg باید از نوع bytes-like باشند ( bytes، bytearray، یا memoryview). آرگومان digestmod از Python 3.4 الزامی است و هر سازنده 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، ۶۴ بایت برای SHA-512). .hexdigest() یک رشته هگز با حروف کوچک برمی‌گرداند. رشته هگز یک str ساده Python است — نیازی به مرحله رمزگشایی نیست.

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()، .encode() را فراخوانی کنید تا به bytes تبدیل شود. این تقریباً همه را بار اول گیج می‌کند — رشته‌های Python 3 از نوع Unicode هستند، نه bytes، و ماژول hmac آن‌ها را نمی‌پذیرد.

Python 3.7+ — تبدیل رشته به bytes
import hmac
import hashlib

# کلید و پیام رشته‌ای — .encode() به bytes UTF-8 تبدیل می‌کند
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..."  — خروجی رشته هگز یکسان
توجه:پارامتر digestmod از Python 3.4 هیچ مقدار پیش‌فرضی ندارد. فراخوانی hmac.new(key, msg) بدون آن TypeError ایجاد می‌کند. قبل از نسخه ۳.۴ به طور پیش‌فرض MD5 بود، به همین دلیل نگهدارندگان Python پیش‌فرض را حذف کردند — تا شما را مجبور کنند انتخاب صریح و امنی داشته باشید.

HMAC-SHA256 با Base64، SHA-1، SHA-512، و MD5

تابع hmac.new() با هر الگوریتم هش موجود در hashlib کار می‌کند. اکثر ارائه‌دهندگان وب‌هوک و دروازه‌های API از HMAC-SHA256 استفاده می‌کنند، اما SHA-1 را در OAuth 1.0a، SHA-512 را در پروتکل‌هایی که آن را الزامی می‌کنند، و MD5 را در سیستم‌های قدیمی که به‌روزرسانی نشده‌اند خواهید دید.

HMAC-SHA256 با خروجی Base64

بسیاری از ارائه‌دهندگان وب‌هوک امضا را به صورت رشته Base64 در یک هدر HTTP ارسال می‌کنند. برای تولید همین فرمت، bytes خام .digest() را به 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 برای پروژه‌های جدید ضعیف در نظر گرفته می‌شود، اما HMAC-SHA1 همچنان توسط OAuth 1.0a و برخی پیاده‌سازی‌های قدیمی‌تر وب‌هوک الزامی است. کد یکسان است — فقط الگوریتم را عوض کنید.

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-encode کنید

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()))   # 64 بایت (512 بیت)
print(len(h.hexdigest()))  # 128 کاراکتر هگز
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 تنها برای سازگاری با سیستم‌هایی که نمی‌توانید آن‌ها را مهاجرت دهید قابل قبول است. برای هر پروژه جدید، حداقل از HMAC-SHA256 استفاده کنید. MD5 آسیب‌پذیری‌های برخورد شناخته‌شده‌ای دارد که اگرچه در حالت HMAC بهره‌برداری مستقیم از آن‌ها سخت‌تر است، آن را انتخاب ضعیفی می‌کند.

مرجع پارامترهای 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
الگوریتم هش — مانند digestmod در hmac.new()

پارامتر digestmod هم callable (مانند hashlib.sha256) و هم نام رشته‌ای (مانند "sha256") می‌پذیرد. فرم callable ترجیح داده می‌شود زیرا در زمان import اعتبارسنجی می‌شود — یک اشتباه تایپی در فرم رشته‌ای فقط در زمان اجرا خطا می‌دهد.

hmac.digest() — HMAC یک‌مرحله‌ای سریع (Python 3.7+)

Python 3.7 تابع hmac.digest(key, msg, digest) را به عنوان یک تابع سطح ماژول اضافه کرد. این تابع HMAC را در یک فراخوانی بدون ساختن شیء HMAC میانی محاسبه می‌کند. مقدار بازگشتی bytes خام است (معادل فراخوانی .digest() روی شیء). این تابع از یک پیاده‌سازی بهینه‌شده C در CPython استفاده می‌کند و از سربار تخصیص شیء اجتناب می‌کند، که آن را در حلقه‌های پرتکرار به طور قابل اندازه‌گیری سریع‌تر می‌کند.

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() آن نیاز دارید، یا .hex() را روی نتیجه bytes زنجیر کنید.

توجه:hmac.digest() از فراخوانی‌های تدریجی .update() پشتیبانی نمی‌کند. اگر یک فایل بزرگ را به صورت تکه‌تکه می‌خوانید و باید محتوا را HMAC کنید، از hmac.new() استفاده کنید و .update(chunk) را در یک حلقه صدا بزنید.

تأیید امضای HMAC از وب‌هوک و پاسخ API

رایج‌ترین کاربرد HMAC در Python تأیید امضاهای وب‌هوک است. هر ارائه‌دهنده اصلی (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() دو رشته یا دنباله bytes را با زمان ثابت مقایسه می‌کند. مقایسه معمولی با == در اولین بایت نامطابق اتصال کوتاه می‌کند. یک مهاجم می‌تواند زمان پاسخ را در تعداد زیادی درخواست اندازه‌گیری کند و به تدریج امضای مورد انتظار را بایت به بایت بازسازی کند. مقایسه با زمان ثابت این کانال جانبی را از بین می‌برد.

تأیید وب‌هوک GitHub

فرمت وب‌هوک GitHub الگوی کامل را نشان می‌دهد. یک هدر X-Hub-Signature-256 ارسال می‌کند که حاوی sha256= به دنبال HMAC-SHA256 هگز-رمزگذاری‌شده بدنه خام درخواست است که با رمز وب‌هوکی که در تنظیمات مخزن پیکربندی کرده‌اید امضا شده. تفاوت کلیدی از تأیید وب‌هوک عمومی این است که باید پیشوند sha256= را قبل از مقایسه حذف کنید، و باید bytes خام بدنه درخواست را بخوانید — ابتدا JSON را پارس کردن نمایش bytes را تغییر داده و تأیید را خراب می‌کند.

Python 3.7+ — تأیید X-Hub-Signature-256 GitHub
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 رایج‌ترین دلیل خطاهای عدم تطابق امضا است.

احراز هویت درخواست API با HMAC

برخی API‌ها از کلاینت می‌خواهند که هر درخواست را با HMAC امضا کند. رشته امضاشده معمولاً شامل متد HTTP، مسیر، مُهر زمانی، و بدنه درخواست است. این الگویی است که من برای احراز هویت سرویس‌به‌سرویس داخلی استفاده می‌کنم.

Python 3.7+ — امضای درخواست‌های API با HMAC-SHA256
import hmac
import hashlib
import time
import json

def sign_request(secret: bytes, method: str, path: str, body: str) -> dict:
    """تولید امضای HMAC-SHA256 برای یک درخواست API."""
    timestamp = str(int(time.time()))

    # رشته امضا را بسازید — متد + مسیر + مُهر زمانی + بدنه
    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..."}

امضای درخواست‌های HTTP با کتابخانه requests

Python 3.7+ — درخواست‌های HMAC-امضاشده با کتابخانه requests
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() بعد از جداکننده‌ها فاصله اضافه می‌کند که نمایش bytes را تغییر داده و اگر سرور به شکل متفاوتی سریال‌سازی کند، تأیید امضا را خراب می‌کند. JSON فشرده به شما یک فرم استاندارد می‌دهد.

تولید HMAC از خط فرمان

گاهی نیاز دارید بدون نوشتن اسکریپت یک HMAC محاسبه کنید. پرچم -c در Python و openssl هر دو این کار را از ترمینال انجام می‌دهند.

bash — HMAC-SHA256 از طریق یک‌خطی Python
python3 -c "
import hmac, hashlib
print(hmac.new(b'my_secret', b'message_to_sign', hashlib.sha256).hexdigest())
"
# خروجی: رشته هگز ۶۴ کاراکتری
bash — HMAC-SHA256 از طریق openssl (برای مقایسه)
echo -n "message_to_sign" | openssl dgst -sha256 -hmac "my_secret"
# SHA2-256(stdin)= 7d11...

# یک فایل را از طریق HMAC openssl ارسال کنید
openssl dgst -sha256 -hmac "my_secret" < payload.json
bash — HMAC از کلید متغیر محیطی
# کلید را در متغیر محیطی ذخیره کنید تا در تاریخچه پوسته نمایش داده نشود
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 به اندازه کافی سریع است. اگر از کتابخانه cryptography برای TLS یا مدیریت گواهینامه‌ها استفاده می‌کنید، این کتابخانه نیز HMAC پشتیبانی‌شده توسط OpenSSL ارائه می‌دهد. تفاوت عملی اصلی با stdlib رابط .verify() مبتنی بر استثنا است که در زیر توضیح داده شده — در صورت عدم تطابق استثنا ایجاد می‌کند به جای اینکه boolean‌ای که ممکن است فراموش کنید بررسی کنید را برگرداند.

bash — نصب cryptography
pip install cryptography
Python 3.7+ — HMAC از طریق کتابخانه cryptography
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 ایجاد می‌کند

متد .verify() کتابخانه cryptography بسیار مفید است: در صورت عدم تطابق استثنا ایجاد می‌کند به جای اینکه boolean برگرداند. این کار بی‌توجهی به خطای تأیید را سخت‌تر می‌کند. تابع hmac.compare_digest() در کتابخانه استاندارد True/ False برمی‌گرداند که اگر توسعه‌دهنده فراموش کند مقدار بازگشتی را بررسی کند می‌تواند بی‌صدا نادیده گرفته شود.

خروجی ترمینال با رنگ‌بندی نحوی

اگر در حال اشکال‌زدایی امضاهای HMAC در ترمینال هستید و خروجی رنگی می‌خواهید، rich این کار را به خوبی انجام می‌دهد.

bash — نصب rich
pip install rich
Python 3.7+ — خروجی HMAC رنگی با rich
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 فقط برای نمایش ترمینال است. هنگام نوشتن امضاهای HMAC در فایل‌ها، هدرهای HTTP، یا سیستم‌های تجمیع لاگ از آن استفاده نکنید — کدهای escape ANSI خروجی را خراب می‌کنند.

کار با فایل‌های بزرگ — HMAC تدریجی

برای فایل‌های بیش از ۵۰ مگابایت، بارگذاری همه چیز در حافظه فقط برای محاسبه HMAC اتلاف منابع است. متد .update() روی شیء HMAC به شما اجازه می‌دهد داده را به صورت تکه‌تکه بدهید. این میزان مصرف حافظه را بدون توجه به اندازه فایل ثابت نگه می‌دارد.

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()

# امضای یک خروجی پایگاه داده ۲ گیگابایتی
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)

# تأیید یک artifact دانلودشده
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'}")
توجه:هنگامی که فایل از ۵۰-۱۰۰ مگابایت تجاوز می‌کند یا هنگام پردازش آپلودها در یک وب‌سرور که حافظه به ازای هر درخواست اهمیت دارد، به HMAC تکه‌ای روی بیاورید. رویکرد .update() صرف‌نظر از اندازه فایل از حافظه ثابتی به اندازه chunk_size استفاده می‌کند. من به طور پیش‌فرض از تکه‌های ۶۴ کیلوبایتی استفاده می‌کنم — به اندازه کافی بزرگ برای جبران سربار syscall، به اندازه کافی کوچک برای ماندن در کش L2 اکثر سخت‌افزارها.

تولید کلید HMAC امن از نظر رمزنگاری در Python

یک کلید ضعیف یا قابل پیش‌بینی کل ساختار HMAC را تضعیف می‌کند. ماژول secrets (Python 3.6+) bytes تصادفی قوی از نظر رمزنگاری فراهم می‌کند. برای HMAC-SHA256، از کلید ۳۲ بایتی استفاده کنید. برای HMAC-SHA512، از ۶۴ بایت استفاده کنید. این اندازه‌ها با اندازه بلوک داخلی الگوریتم‌های هش مربوطه مطابقت دارند که طول کلید بهینه طبق RFC 2104 است.

Python 3.7+ — تولید کلید HMAC با secrets
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()}")
# رشته هگز ۱۲۸ کاراکتری

# Base64 ایمن برای URL — فشرده، مناسب برای هدرهای HTTP
import base64
b64_key = base64.urlsafe_b64encode(sha256_key).decode("ascii")
print(f"Base64 key: {b64_key}")
# مثلاً "o_G5wE59L4obPF1-nwortG2ODwobPExdXnqLnA0dLi8="
هشدار:هرگز از random.random() یا random.randbytes() از ماژول random برای کلیدهای HMAC استفاده نکنید. ماژول پیش‌فرض random از PRNG Mersenne Twister استفاده می‌کند که پس از مشاهده ۶۲۴ خروجی قابل پیش‌بینی است. همیشه از secrets.token_bytes() برای تصادفی‌سازی حساس به امنیت استفاده کنید.

طول کلید و الزامات RFC 2104

RFC 2104 مشخص می‌کند که کلید HMAC می‌تواند هر طولی داشته باشد، اما کلیدی با حداقل L بایت را توصیه می‌کند — که L طول خروجی تابع هش زیرین است. برای HMAC-SHA256، این ۳۲ بایت (۲۵۶ بیت) است. کلیدهای کوتاه‌تر از L بیت حاشیه امنیتی را به تناسب کاهش می‌دهند. کلیدهای بلندتر از اندازه بلوک هش (۶۴ بایت برای SHA-256، ۱۲۸ بایت برای SHA-512) ابتدا به اندازه بلوک هش می‌شوند، بنابراین استفاده از کلیدهای بلندتر از اندازه بلوک هیچ مزیتی ندارد. برای HMAC-SHA256 از ۳۲ بایت و برای HMAC-SHA512 از ۶۴ بایت استفاده کنید.

ذخیره‌سازی امن کلید و چرخش آن

هرگز کلیدهای HMAC را در کد منبع هاردکد نکنید. رویکرد استاندارد برای استقرارهای تولیدی این است که کلید را از یک متغیر محیطی در زمان راه‌اندازی بارگذاری کنید: os.environ["HMAC_SECRET"].encode(). برای محیط‌های با اطمینان بالاتر، کلیدها را در یک سیستم مدیریت اسرار مانند AWS Secrets Manager، HashiCorp Vault، یا GCP Secret Manager ذخیره کنید و در زمان اجرا بازیابی کنید. این سیستم‌ها گزارش‌های حسابرسی، کنترل‌های دسترسی، و چرخش خودکار بدون نیاز به استقرار کد را فراهم می‌کنند.

از ابتدا برای چرخش کلید برنامه‌ریزی کنید. وقتی یک کلید چرخانده می‌شود، یک پنجره زمانی وجود دارد که درخواست‌های در حال انجام با کلید قدیمی امضا شده‌اند و در مقابل کلید جدید تأیید نخواهند شد. راه‌حل استاندارد یک دوره همپوشانی کوتاه است: برای مدت کوتاهی (دقیقه تا ساعت) امضاهای هر دو کلید قدیمی و جدید را بپذیرید، سپس کلید قدیمی را بازنشسته کنید. اگر یک کلید به خطر افتاد — در لاگ‌ها نمایش داده شد، در یک commit git فاش شد، یا در یک حادثه افشا شد — فوراً آن را بچرخانید و تمام امضاهای تولیدشده با کلید در معرض خطر را غیرقابل اعتماد تلقی کنید. هر نتیجه تأیید کش‌شده را دوباره تأیید کنید و مصرف‌کنندگان پایین‌دستی را از تغییر کلید خبر کنید.

استفاده از bytearray و memoryview با hmac.new()

تابع hmac.new() هر شیء bytes-like را برای پارامترهای key و msg می‌پذیرد. این یعنی می‌توانید bytes، bytearray، یا memoryview را مستقیماً بدون کپی یا تبدیل ارسال کنید. این در دو سناریو بیشترین اهمیت را دارد: پیاده‌سازی‌های پروتکل شبکه که socket.recv_into() داده را در یک بافر bytearray از پیش تخصیص‌یافته می‌نویسد، و سیستم‌های پرتوان که اجتناب از کپی‌های میانی فشار GC را کاهش می‌دهد. یک برش memoryview بدون کپی است: یک پنجره به بافر اصلی را بدون تخصیص حافظه جدید نشان می‌دهد. در ده‌ها هزار پیام در ثانیه، حذف این تخصیص‌ها تفاوت قابل اندازه‌گیری در تأخیر و توان خروجی ایجاد می‌کند.

Python 3.7+ — bytearray و memoryview با HMAC
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"

# HMAC فقط ۲۰ بایت اول بدون کپی
view = memoryview(large_buffer)[:20]
sig = hmac.new(key, view, hashlib.sha256).hexdigest()
print(f"Sensor signature: {sig[:32]}...")

اشتباهات رایج

دو اشتباه اول را در تقریباً هر بررسی کد مربوط به هندلرهای وب‌هوک می‌بینم. تحت فشار زمانی راحت وارد می‌شوند و بدون دانستن چه چیزی را باید دنبال کرد سخت تشخیص داده می‌شوند.

مقایسه امضاهای HMAC با == به جای hmac.compare_digest()

مشکل: عملگر == در اولین بایت نامطابق اتصال کوتاه می‌کند و اطلاعات زمان‌بندی را فاش می‌کند که به مهاجم اجازه می‌دهد امضای مورد انتظار را به تدریج بازسازی کند.

راه‌حل: همیشه از hmac.compare_digest() برای مقایسه امضا استفاده کنید — بدون توجه به محل عدم تطابق با زمان ثابت اجرا می‌شود.

After · Python
Before · Python
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)
received_sig = request.headers["X-Signature"]
expected_sig = hmac.new(key, body, hashlib.sha256).hexdigest()

if received_sig == expected_sig:  # آسیب‌پذیر به حمله زمان‌بندی
    process_webhook(body)
ارسال str به جای bytes به hmac.new()

مشکل: hmac.new() به اشیاء bytes-like نیاز دارد. ارسال str در Python TypeError ایجاد می‌کند: "key: expected bytes or bytearray, but got 'str'".

راه‌حل: قبل از ارسال کلیدها و پیام‌های رشته‌ای به hmac.new()، .encode() را روی آن‌ها فراخوانی کنید.

After · Python
Before · Python
key = "my_api_secret"
msg = '{"event":"test"}'
sig = hmac.new(key.encode(), msg.encode(), hashlib.sha256)
key = "my_api_secret"  # str، نه bytes
msg = '{"event":"test"}'  # str، نه bytes
sig = hmac.new(key, msg, hashlib.sha256)  # TypeError!
فراموش کردن digestmod (Python 3.4+)

مشکل: فراخوانی hmac.new(key, msg) بدون آرگومان سوم TypeError ایجاد می‌کند. قبل از Python 3.4 به طور پیش‌فرض MD5 بود، اما پیش‌فرض به دلایل امنیتی حذف شد.

راه‌حل: همیشه الگوریتم را به صراحت مشخص کنید: hashlib.sha256، hashlib.sha512، یا هر چیزی که پروتکل شما نیاز دارد.

After · Python
Before · Python
# همیشه الگوریتم هش را مشخص کنید
sig = hmac.new(key, msg, hashlib.sha256).hexdigest()
# digestmod مفقود است — در Python 3.4+ TypeError ایجاد می‌کند
sig = hmac.new(key, msg).hexdigest()
استفاده از .hexdigest() وقتی ارائه‌دهنده Base64 انتظار دارد

مشکل: بسیاری از ارائه‌دهندگان وب‌هوک (Stripe، Shopify) امضاهای Base64 ارسال می‌کنند، نه هگز. مقایسه یک رشته هگز با یک مقدار Base64 همیشه شکست می‌خورد و باعث رد شدن تمام وب‌هوک‌ها می‌شود.

راه‌حل: مستندات ارائه‌دهنده را برای فرمت امضا بررسی کنید. اگر از Base64 استفاده می‌کنند، bytes خام .digest() را رمزگذاری کنید، نه رشته .hexdigest() را.

After · Python
Before · Python
import base64
# فرمت ارائه‌دهنده را مطابقت دهید: bytes خام → Base64
raw = hmac.new(key, body, hashlib.sha256).digest()
expected = base64.b64encode(raw).decode("ascii")
# "o/G5wE59..."  — با هدر مطابقت دارد
# ارائه‌دهنده Base64 ارسال می‌کند، اما ما هگز محاسبه می‌کنیم — هرگز مطابقت ندارد
expected = hmac.new(key, body, hashlib.sha256).hexdigest()
# "a3f1b9c0..."  vs  "o/G5wE59..."  — همیشه عدم تطابق

stdlib hmac در مقابل cryptography — مقایسه سریع

متد
الگوریتم
خروجی
پردازش جریانی
انواع سفارشی
نیاز به نصب
hmac.new() + hexdigest()
هر hashlib
رشته هگز
✓ از طریق .update()
N/A
خیر (stdlib)
hmac.new() + digest()
هر hashlib
bytes خام
✓ از طریق .update()
N/A
خیر (stdlib)
hmac.digest()
هر hashlib
bytes خام
✗ (یک‌مرحله‌ای)
N/A
خیر (stdlib، نسخه ۳.۷+)
hashlib.sha256 (هش ساده)
فقط SHA-256
هگز یا bytes
✓ از طریق .update()
N/A
خیر (stdlib)
cryptography (HMAC)
هر الگوریتم
bytes خام
✓ از طریق .update()
N/A
pip install
pyca/cryptography + CMAC
AES-CMAC
bytes خام
✓ از طریق .update()
N/A
pip install

از ماژول stdlib hmac برای تأیید وب‌هوک، امضای API، و عملیات HMAC عمومی استفاده کنید — هیچ وابستگی‌ای نیاز ندارد و هر الگوریتم استاندارد را پوشش می‌دهد. از hmac.digest() برای عملیات دسته‌ای که سرعت یک‌مرحله‌ای اهمیت دارد استفاده کنید. تنها زمانی به کتابخانه cryptography روی بیاورید که از قبل برای عملیات دیگر (TLS، X.509، رمزگذاری متقارن) به آن وابسته هستید و رابط .verify() مبتنی بر استثنا را می‌خواهید. برای بررسی سریع امضا بدون نوشتن Python، از ابزار مولد HMAC استفاده کنید تا کلید و پیام را جای‌گذاری کنید و نتیجه را فوری دریافت کنید.

سوالات متداول

تفاوت hmac.new() و hmac.digest() در Python چیست؟

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()

چطور می‌توان یک امضای HMAC را در Python تأیید کرد؟

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)

آیا HMAC-SHA256 در Python همان هش 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()  # نیاز به کلید دارد

آیا می‌توان از HMAC-SHA1 در Python 3 استفاده کرد؟

بله، hashlib.sha1 را به عنوان آرگومان digestmod ارسال کنید. HMAC-SHA1 در Python 3 همچنان کار می‌کند و ماژول hmac هیچ هشدار منسوخی برای آن ندارد. با این حال، SHA-1 برای پروژه‌های جدید ضعیف در نظر گرفته می‌شود — مقاومت برخورد آن زیر ۸۰ بیت است و NIST در سال ۲۰۱۵ آن را برای اکثر کاربردهای امضای دیجیتال منسوخ اعلام کرد. دلیل اصلی استفاده از HMAC-SHA1 امروزه سازگاری با پروتکل‌های موجودی است که آن را الزامی می‌دانند، مانند OAuth 1.0a یا سیستم‌های قدیمی وب‌هوک. وقتی هر دو طرف یکپارچه‌سازی را کنترل می‌کنید، برای تمام کارهای جدید 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()

چطور می‌توان یک کلید HMAC امن در Python تولید کرد؟

از secrets.token_bytes() از کتابخانه استاندارد استفاده کنید. برای HMAC-SHA256، کلید ۳۲ بایتی توصیه استاندارد است چون با اندازه بلوک هش مطابقت دارد. برای HMAC-SHA512، از ۶۴ بایت استفاده کنید. از random.random() یا os.urandom() برای تولید کلید در کد برنامه استفاده نکنید — ماژول secrets از Python 3.6 ماژول صحیح برای تصادفی‌سازی حساس به امنیت است.

Python
import secrets

hmac_sha256_key = secrets.token_bytes(32)  # ۲۵۶ بیت
hmac_sha512_key = secrets.token_bytes(64)  # ۵۱۲ بیت

# به صورت هگز برای فایل‌های پیکربندی ذخیره کنید
print(hmac_sha256_key.hex())
# مثلاً "a3f1b9c04e..."

چرا hmac.new() در Python 3 به digestmod نیاز دارد؟

قبل از Python 3.4، digestmod به طور پیش‌فرض MD5 بود که از نظر رمزنگاری شکسته شده — MD5 دارای حملات برخورد شناخته‌شده است و هرگز نباید در کد حساس به امنیت جدید استفاده شود. نگهدارندگان Python پیش‌فرض را حذف کردند تا انتخاب صریح الگوریتم را الزامی کنند و از ارسال ناخواسته MAC مبتنی بر MD5 جلوگیری شود. اگر hmac.new(key, msg) را بدون digestmod فراخوانی کنید، 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)

برای بررسی سریع HMAC بدون راه‌اندازی یک اسکریپت Python، کلید و پیام را در مولد آنلاین HMAC جای‌گذاری کنید — از 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.