امضا و تایید درخواستها
امضای درخواست اعتبار فرستنده و یکپارچگی محتوا را ثابت می کند. بر خلاف TLS (که از کانال محافظت می کند)، یک امضای اعمال شده باعث می شود هر پیام قابل اثبات و مقاوم در برابر پروکسی، حافظه پنهان و تحویل تاخیر باشد.
اهداف:1. اصالت (چه کسی فرستاد) و صداقت (تغییر نکرد).
2. منحصر به فرد (حفاظت در برابر تکرار).
3. جدا شدن از حمل و نقل (کار می کند در بالای HTTP، صف، webhooks).
4. قابلیت شنیدن (بررسی مجدد پس از ماه).
1) مدل تهدید (حداقل)
تعویض بدنه/هدرها در طول مسیر
پخش (تکرار درخواست مشروع).
عنوان پایین/نوار.
سرقت اسرار ادغام.
ساعت غیر همزمان (انحراف ساعت) و صف های طولانی.
2) انتخاب اولیه
HMAC (تقارن): ساده و سریع، کلید در هر دو طرف ذخیره می شود. مناسب برای وب سایت های B2B و API های داخلی.
RSA/ECDSA (عدم تقارن): کلید خصوصی از فرستنده، کلید عمومی از گیرنده. مناسب برای یکپارچگی باز و زمانی که مهم است که یک راز را به اشتراک نگذارید.
mTLS: احراز هویت متقابل لایه انتقال اغلب با امضای NMAC/body ترکیب می شود.
JWT/JWS: مناسب برای نشانه های حامل و تمبر خودکفا ؛ برای امضای بدنه، بهتر است از canonicalization + JWS Detached/HTTP Message Signatures استفاده کنید.
امضای پیام HTTP (امضای بخش های انتخاب شده از درخواست): رویکرد مدرن برای REST.
توصیه: برای webhooks - HMAC + برچسب زمان + nonce + canonicalization بدن ؛ برای API عمومی - امضاهای پیام HTTP یا JWS ؛ در معرض خطرات بالا - اضافه کردن mTLS.
3) Canonicalization (دقیقا چه چیزی را امضا می کنیم)
شما باید یک رشته قطعی را امضا کنید که به طور مساوی توسط هر دو طرف قابل بازیابی است.
ترکیب مرجع:
method \n path_with_query_normalized \n content-type \n digest: SHA-256=BASE64(SHA256(body)) \n x-ts: <unix iso> \n x-nonce: <uuid> \n host \n x-tenant: <tenant_id> \n
ردیف کل:
canonical = join("\n", fields)
signature = HMAC(secret, canonical) # или ECDSA_sign(private_key, canonical)
قوانین و مقررات:
- نرمال کردن مسیر و ترتیب پارامترهای پرسوجو.
- فاصله/یونیکد/مورد - ثابت (به عنوان مثال، هدر پایین مورد، تر و تمیز).
- بدن های بزرگ - هش (Digest)، روشن نیست «همانطور که هست».
4) فرمت عنوان
مثال برای HMAC:
X-Signature-Alg: hmac-sha256
X-Signature: v1=hex(hmac),ts=1730379005,nonce=550e8400-e29b-41d4-a716-446655440000,kid=prov_42
Digest: SHA-256=BASE64(SHA256(body))
X-Tenant: brand_eu
مثال برای عدم تقارن (ECDSA P-256):
Signature: keyId="prov_42", alg="ecdsa-p256-sha256",
ts="2025-10-31T12:30:05Z", nonce="550e...", headers="(request-target) host digest x-tenant",
sig="BASE64(raw_signature)"
جایی که 'kid '/' keyId' به شما اجازه می دهد یک کلید را از رجیستری انتخاب کنید (چرخش را ببینید).
5) تأیید در پایان دریافت
شبه کد:python def verify(request):
1) Basic assert abs (now () - request. ts) <= ALLOWED_SKEW # напр., 300 с assert not replayed(request. nonce, window = TTL) # store nonce/ts in KV
2) Restore canonical canonical = build_canonical (
method=request. method,
path=normalize_path(request. path, request. query),
content_type=request. headers["content-type"],
digest=hash_body(request. body),
ts=request. ts,
nonce=request. nonce,
host=request. headers["host"],
tenant=request. headers. get("x-tenant")
)
3) Get the key key = key_registry. get(request. kid) # secret (HMAC) или public key (ECDSA)
4) Verify if request signature. alg. startswith("hmac"):
ok = hmac_compare(key. secret, canonical, request. signature)
else:
ok = asym_verify(key. public, canonical, request. signature)
5) Solution if not ok: return 401, "SIGNATURE_INVALID"
return 200, "OK"
مقایسه HMAC در زمان ثابت، ذخیره سازی 'nonce '/' (ts، event_id)' در KV سریع (پنجره تحویل ≥ TTL).
6) ضد پخش و ویندوز
برچسب زمان + Nonce: رد درخواست های قدیمی تر از '± Δ' (به عنوان مثال 5 دقیقه) و nonce در این پنجره تکرار می شود.
برای webhooks: از یک event _ id پایدار و یک جدول صندوق ورودی استفاده کنید - این قابل اعتماد تر از nonce است.
تحویل مجدد (retrays) باید از همان ts/nonce/event_id استفاده کند، نه تولید جدید.
7) چند مستاجر و مناطق
کلیدها را به ازای هر مستاجر/ناحیه ذخیره کنید: 'kid = <tenant>: <region>: <key _ id>'.
استخر های مخفی و محدودیت های جداگانه ؛ اقامت داده ها را مشاهده کنید.
در سرفصل ها/canonicalization، نشان می دهد «X-Tenant» و منطقه بخشی از زمینه بررسی شده است.
8) مدیریت کلید و چرخش
رجیستری کلید (KMS/Vault): «بچه»، نوع، الگوریتم، وضعیت («فعال»، «مستهلک»، «بازنشسته»)، «valid _ from/valid _ to».
دو راز: کلید فعلی و بعدی را همزمان نگه دارید (گیرنده هر دو را می پذیرد).
چرخش در یک برنامه و در یک رویداد (سازش).
پین کردن کلید (در صورت امکان) و محدود کردن دسترسی به مواد کلیدی.
سیاهههای مربوط از دسترسی به کلید و اقدامات با آنها.
9) ترکیب با mTLS و OAuth
mTLS کانال و «چه کسی هستید» را در سطح گواهی بررسی می کند.
امضا از پیام محافظت می کند (مفید از طریق پروکسی/کش/صف).
OAuth/JWT تأیید اعتبار/مجوز را تکمیل می کند، اما به خودی خود یکپارچگی بدن را تضمین نمی کند (مگر اینکه در canonicalization امضا شود).
بهترین شیوه: mTLS + امضای بدن (Digest) + HMAC/ECDSA + کوتاه 'ts' -بین المللی.
10) خطاها و کدهای پاسخ
"401 SIGNATURE_INVALID' یک امضا/الگوریتم نامعتبر است.
'401 KEY_REVOKED' -' kid 'نامعتبر است/منقضی شده است.
'400 TIMESTAMP_OUT_OF_RANGE' - ساعت/پنجره.
409 NONCE_REPLAYED' - Redo شناسایی شده است.
400 DIGEST_MISMATCH' - بدن تغییر کرده است.
"۴۱۵ UNSUPPORTED_ALGORITHM' یک" الگ "حل نشده است.
'429 TOO_MANY_ATTEMPTS' - کلید/مستاجر خفه کردن.
ضربه علت دقیق در ماشین قابل خواندن 'error _ code'; اسرار/canonicalization را «همانطور که هست» باز نکنید.
11) قابلیت مشاهده و حسابرسی
معیارها:- 'verify _ p95 _ ms', 'verify _ error _ rate', 'digest _ mismatch _ rate', 'replay _ blocked _ rate', 'alg _ usage {hmac, ecdsa}', 'clock _ skew _ ms'.
- سیاهههای مربوط (ساختاری): 'بچه'، 'alg'، 'مستاجر'، 'منطقه'، 'ts'، 'nonce'، 'digest _ hash'، 'تصمیم'، 'دلیل'.
- ردیابی: امضای صفات. بچه، امضا. و امضا کرد. ts_skew' است.
- حسابرسی: ورود غیر قابل تغییر از چرخش، استفاده از کلید و پرچم تحمل.
12) عملکرد
بدن را با جریان دادن هش کنید (آن را در حافظه خود نگه ندارید).
کلیدهای عمومی کش توسط «بچه» با TTL کوتاه و ناتوانی توسط رویداد.
در لبه/دروازه، بررسی های اولیه (ts/nonce/format) را انجام دهید.
HMAC سریعتر از ECDSA ؛ ECDSA برای ادغام های خارجی و کلید های «غیر مشترک» راحت تر است.
13) تست
مجموعه لوازم جانبی: همان درخواست → همان canonicalization/امضا ؛ فضاهای کثیف/پرس و جو سفارش/→ هدر پایدار هستند.
منفی: نامعتبر 'kid/alg'، بدن/میزبان اصلاح شده، تکرار nonce، منسوخ، چرخش ساعت.
Property-based: هر پرس و جوی معادل یک رشته کانونیکال تولید می کند.
Interop: چک های متقابل زبان (Go/Java/Node/Python).
هرج و مرج: تاخیر، عقب نشینی، تغییرات کلیدی در پرواز.
14) کتاب های بازی (کتاب های اجرا)
1. 'امضا _ نامعتبر' اسپایک
چرخش کلید، ناهمترازی ساعت، تغییرات کانونیزاسیون در فرستنده را بررسی کنید.
موقتاً «پذیرش دوگانه» را برای «بچه» قدیمی فعال کنید، به شریک زندگی اطلاع دهید.
2. «پخش» رشد
TTL ذخیره سازی نانس را افزایش دهید، نگهدارنده ها را در فرستنده بررسی کنید، ساعت را بررسی کنید.
نادیده گرفتن IP/ASN سوء استفاده در لبه.
3. 'DIGEST _ عدم تطابق' انبوه
بررسی پروکسی/فشرده سازی/بازنویسی هدر ؛ رفع نسخه canonicalization.
غیر فعال کردن مزاحمان بدن/هدر.
4. مصالحه کلیدی
بلافاصله «بچه» را لغو کنید، به «بچه بعدی» ترجمه کنید، تمام اسرار/نشانه ها، دسترسی حسابرسی را بازسازی کنید.
15) خطاهای معمول
امضای یک «قسمت بدن» یا JSON بدون تثبیت نظم → آسیب پذیری به جایگزینی زمینه.
عدم وجود یک «Digest» → پروکسی می تواند بدن را بدون توجه تغییر دهد.
یک پنجره طولانی «ts» بدون nonce برای پخش مجدد باز است.
اسرار را در متغیرهای محیطی بدون KMS/Vault نگه دارید.
امضا را مقایسه کنید نه زمان ثابت.
چشمپوشی از «میزبان »/« مسیر» در canonicalization → حمله رو به جلو.
«بچه» مستاجران و مناطق مختلف را مخلوط کنید.
16) چک لیست پیش فروش
- فرمت Canonicalization تعریف شده (روش، مسیر + پرس و جو، نوع محتوا، خلاصه، ts، nonce، میزبان، مستاجر).
- اجرا HMAC/ECDSA با «بچه»، رجیستری کلید و دو راز.
- شامل ضد پخش (nonce + ts) و ذخیره سازی inbox/event_id برای webhooks.
- پیکربندی کدهای خطا/سیاست retray و throttling در هر مستاجر/کلید.
- قابلیت مشاهده: تأیید معیارها، سیاههها، ردیابی، هشدارها برای انفجار.
- چرخش کلید خودکار است ؛ حقوق حسابرسی و دسترسی محدود است.
- کیت های تست سازگاری Canonicalization و بین زبانی.
- مستندات برای انتگرال با یک مثال در 3-4 زبان و رفع.
- mTLS برای یکپارچگی حساس فعال شده است. JWT فقط به عنوان یک افزودنی استفاده می شود، نه جایگزینی برای امضای بدن.
نتیجه گیری
امضا و تأیید درخواستها «یک هدر» نیست، بلکه یک رشته است: canonicalization روشن، پنجره های کوتاه زمان، ضد پخش، چرخش کلید و مشاهده پذیری. ساخت یک استاندارد واحد برای همه یکپارچگی (API ها و webhooks)، استفاده از «بچه »/KMS، قبول دو کلید در طول چرخش، و خطوط خود را تبدیل به مقاومت در برابر جعل، قابل پیش بینی و آسان برای حسابرسی.