Υπογραφή και επαλήθευση των αιτήσεων
Η υπογραφή της αίτησης αποδεικνύει την αυθεντικότητα του αποστολέα και την ακεραιότητα του περιεχομένου. Σε αντίθεση με το TLS (που προστατεύει το κανάλι), μια εφαρμοσμένη υπογραφή καθιστά κάθε μήνυμα επαληθεύσιμο και ανθεκτικό στον διαμεσολαβητή, την κρύπτη και την καθυστερημένη παράδοση.
Στόχοι:1. Αυθεντικότητα (που έστειλε) και ακεραιότητα (δεν άλλαξε).
2. Μοναδικότητα (προστασία από επαναλήψεις).
3. Αποσύνδεση από τις μεταφορές (εργασίες πάνω από HTTP, ουρές αναμονής, webhooks).
4. Ακουστικότητα (αναπαραγώγιμος έλεγχος μετά από μήνες).
1) Μοντέλο απειλής (ελάχιστο)
Αντικατάσταση αμαξώματος/κεφαλών κατά μήκος της διαδρομής.
Επανάληψη (επανάληψη νόμιμης αίτησης).
Υποβάθμιση/λεζάντα ταινίας.
Κλοπή μυστικών ενσωμάτωσης.
Μη συγχρονισμένο ρολόι (ρολόι) και μεγάλες ουρές αναμονής.
2) Επιλογή πρωτόγονου
HMAC (συμμετρία): απλό και γρήγορο, το κλειδί αποθηκεύεται και στις δύο πλευρές. Κατάλληλο για webhooks B2B και εσωτερικούς API.
RSA/ECDSA (ασυμμετρία): ιδιωτικό κλειδί από τον αποστολέα, δημόσιο κλειδί από τον παραλήπτη. Κατάλληλο για ανοικτές ενοποιήσεις και όταν είναι σημαντικό να μην μοιραζόμαστε ένα μυστικό.
mTLS: η αμοιβαία εξακρίβωση ταυτότητας του επιπέδου μεταφοράς συχνά συνδυάζεται με την υπογραφή NMAC/φορέα.
JWT/JWS: βολικό για τις μάρκες κομιστή και τις αυτάρκεις σφραγίδες· για την υπογραφή του σώματος, είναι προτιμότερο να χρησιμοποιούνται υπογραφές μηνυμάτων Canonicalization + JWS αποσπασμένων/HTTP.
Υπογραφές μηνυμάτων HTTP (υπογραφή επιλεγμένων μερών της αίτησης): σύγχρονη προσέγγιση για REST.
Σύσταση: για webhooks - HMAC + χρονοσφραγίδα + μη ce + κανονικοποίηση σώματος; για δημόσιες υπογραφές μηνυμάτων API - HTTP ή JWS· σε υψηλούς κινδύνους - προσθήκη mTLS.
3) Κανονικοποίηση (τι ακριβώς υπογράφουμε)
Πρέπει να υπογράψετε μια καθορισμένη συμβολοσειρά που θα είναι εξίσου ανακτήσιμη και από τα δύο μέρη.
Σύνθεση αναφοράς:
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)
Κανόνες:
- Ομαλοποίηση της διαδρομής και της σειράς των παραμέτρων ερωτήσεων.
- Χώροι/unicode/περίπτωση - σταθεροποίηση (για παράδειγμα, κεφαλίδες κάτω περίπτωσης, κοπή).
- Μεγάλα σώματα - hash (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)"
Όπου το 'παιδί '/' kooId' σας επιτρέπει να επιλέξετε ένα κλειδί από το μητρώο (βλέπε περιστροφή).
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, )' σε γρήγορο KV (παράθυρο παράδοσης TTL).
6) Αντι-αναπαραγωγή και παράθυρα
Χρονοσφραγίδα + Nonce: απόρριψη αιτήσεων παλαιότερων από '± Δ' (π.χ. 5 λεπτά) και μη επανατοποθετήσεις σε αυτό το παράθυρο.
Για webhooks: χρησιμοποιήστε ένα σταθερό 'event _ id' και ένα inbox table - αυτό είναι πιο αξιόπιστο από απλά nonce.
Η εκ νέου παράδοση (retrays) θα πρέπει να χρησιμοποιεί τα ίδια ts/nonce/event_id, όχι να παράγει νέα.
7) Πολυπληθείς και περιφέρειες
Πλήκτρα αποθήκευσης ανά ενοικιαστή/περιφέρεια: «παιδί = <ενοικιαστής>: <περιφέρεια>: <κλειδί _ id>».
χωριστές μυστικές ομάδες και όρια· παρατηρούν την κατοικία των δεδομένων.
Στους τίτλους/κανονικοποίηση, αναφέρετε «X-Tenant» και η περιοχή είναι μέρος του πλαισίου που ελέγχεται.
8) Βασική διαχείριση και εναλλαγή
Μητρώο κλειδιών (KMS/Vault): 'παιδί', τύπος, αλγόριθμος, κατάσταση ('ενεργός', 'υποτιμώντας', 'συνταξιούχος'), 'έγκυρος _ από/έγκυρος _ σε'.
Διπλό μυστικό: κρατήστε το τρέχον και το επόμενο κλειδί ταυτόχρονα (ο δέκτης δέχεται και τα δύο).
Εναλλαγή σε ένα χρονοδιάγραμμα και σε ένα γεγονός (συμβιβασμός).
Πληκτρολόγηση (εάν είναι δυνατόν) και περιορισμός της πρόσβασης σε βασικά υλικά.
Καταχωρήσεις πρόσβασης σε κλειδιά και ενέργειες μαζί τους.
9) Συνδυασμός με mTLS και OAuth
Το mTLS ελέγχει το κανάλι και το «ποιος είστε» σε επίπεδο πιστοποιητικού.
Η υπογραφή προστατεύει το μήνυμα (χρήσιμο μέσω πληρεξουσίων/κρυψώνων/ουρών αναμονής).
Το OAuth/JWT συμπληρώνει την ταυτοποίηση/εξουσιοδότηση, αλλά από μόνο του δεν εγγυάται την ακεραιότητα του σώματος (εκτός αν υπογραφεί στην κανονικοποίηση).
Βέλτιστες πρακτικές: mTLS + υπογραφή σώματος (Digest) + HMAC/ECDSA + σύντομη "t - interval.
10) Σφάλματα και κωδικοί απόκρισης
Το '401 SIGNATURE_INVALID' είναι μια άκυρη υπογραφή/αλγόριθμος.
Το '401 KEY_REVOKED' -' παιδί 'είναι άκυρο/εκπνέει.
'400 TIMESTAMP_OUT_OF_RANGE' - ρολόι/παράθυρο.
'409 NONCE_REPLAYED' - Ανιχνεύθηκε ο Ρέντο.
'400 DIGEST_MISMATCH' - το σώμα άλλαξε.
Το '415 UNSUPPORTED_ALGORITHM' είναι ένα ανεπίλυτο' alg '.
'429 TOO_MANY_ATTEMPTS' - πλήκτρο/στραγγαλισμός ενοικιαστή.
Κλώτσησε την ακριβή αιτία στο μηχάνημα αναγνώσιμο 'error _ code'; δεν επιστρέφουν μυστικά/κανονικοποίηση «όπως είναι».
11) Παρατηρησιμότητα και λογιστικός έλεγχος
Μετρήσεις:- 'verify _ p95 _ m ,' verify _ error _ rate ',' digest _ mismatch _ rate ',' replay _ blocked _ rate ',' alg _ usage {hmac, ecdsa} ',' rock _ skew _ ms '.
- Logs (δομικά): «παιδί», «alg», «ενοικιαστής», «περιφέρεια», «ts», «nonce», «digest _ hash», «απόφαση», «λόγος».
- Εντοπισμός: υπογραφή χαρακτηριστικών. παιδί ',' υπογραφή. alg ',' υπογραφή. .
- Έλεγχος: αμετάβλητο ημερολόγιο εναλλαγής, σημαίες χρήσης κλειδιών και ανοχής.
12) Επιδόσεις
Χασίς το σώμα με ροή (μην το κρατάς στη μνήμη σου).
Κρατήστε τα δημόσια κλειδιά από το «παιδί» με σύντομο TTL και αναπηρία ανά εκδήλωση.
Στην άκρη/πύλη, διενεργούνται προκαταρκτικοί έλεγχοι (ts/nonce/format).
HMAC ταχύτερα από το ECDSA· Το ECDSA είναι πιο βολικό για εξωτερικές ενοποιήσεις και «μη κοινά» κλειδιά.
13) Δοκιμές
Σύνολα στοιχείων: τα ίδια αιτήματα → την ίδια κανονικοποίηση/υπογραφή. οι βρώμικοι χώροι/σειρά ερωτήσεων/κεφαλίδες → είναι σταθεροί.
Αρνητικό: μη έγκυρο 'παιδί/alg', τροποποιημένο σώμα/ξενιστής, μη επαναλαμβανόμενο, απαρχαιωμένο ts, ρολόι skew.
Οποιαδήποτε ισοδύναμα ερωτήματα παράγουν μία μόνο κανονική συμβολοσειρά.
Interop: διασταυρούμενοι έλεγχοι (Go/Java/Node/Python).
Χάος: καθυστερήσεις, υποχωρήσεις, αλλαγές κλειδιών.
14) Βιβλία παιχνιδιών (runbooks)
1. ΥΠΟΓΡΑΦΗ _ ΑΚΥΡΩΣΗΣ 'spike
Ελέγξτε την περιστροφή κλειδιού, την εσφαλμένη ευθυγράμμιση ρολογιού, τις αλλαγές στην κανονικοποίηση στον αποστολέα.
Επιτρέψτε προσωρινά την «διπλή αποδοχή» για το παλιό «παιδί», ενημερώστε τον σύντροφο.
2. «ΕΠΑΝΑΛΑΜΒΑΝΟΜΕΝΗ» ανάπτυξη
Αυξήστε το TTL αποθήκευσης, ελέγξτε τους επανεκπαιδευτές στον αποστολέα, ελέγξτε το ρολόι skew.
Παράκαμψη καταχρηστικής IP/ASN στην άκρη.
3. 'DIGEST _ MISMATCH' μαζικά
Έλεγχος κεφαλίδων διαμεσολαβητή/συμπίεσης/επαναγραφής. να διορθώσει την έκδοση της κανονικοποίησης.
Απενεργοποίηση εισβολέων σώματος/κεφαλίδας.
4. Βασικός συμβιβασμός
Αμέσως ανακαλέστε το 'παιδί', μεταφράστε το 'επόμενο _ παιδί', αναγεννήστε όλα τα μυστικά/μάρκες, πρόσβαση στον έλεγχο.
15) Τυπικά σφάλματα
Υπογραφή «μέρους σώματος» ή JSON χωρίς καθορισμό της τάξης → ευπάθειας στη μετατροπή πεδίου.
Η απουσία ενός πληρεξούσιου 'Digest' μπορεί να αλλάξει το σώμα απαρατήρητο.
Ένα μακρύ παράθυρο 'ts' χωρίς nonce είναι → ανοικτό για αναπαραγωγή.
Διατήρηση μυστικών στις περιβαλλοντικές μεταβλητές χωρίς KMS/θησαυροφυλάκιο.
Σύγκριση υπογραφής όχι σταθερού χρόνου.
Αγνόηση 'host '/' path' στην κανονικοποίηση → προς τα εμπρός επίθεση.
Αναμίξτε «παιδιά» διαφορετικούς ενοικιαστές και περιφέρειες.
16) Κατάλογος επιλογών πριν από την πώληση
- Καθορισμένη μορφή κανονικοποίησης (μέθοδος, διαδρομή + ερώτηση, τύπος περιεχομένου, Digest, ts, nonce, ξενιστής, ενοικιαστής).
- Εφαρμόστηκε HMAC/ECDSA με 'παιδί', μητρώο κλειδί και διπλό μυστικό.
- Περιλαμβάνονται η αντι-αναπαραγωγή (nonce + ts) και η αποθήκευση inbox/event_id για webhooks.
- Ρυθμισμένοι κωδικοί σφάλματος/πολιτική επανασυσκευασίας και στραγγαλισμός ανά ενοικιαστή/κλειδί.
- Παρατηρησιμότητα: επαλήθευση μετρήσεων, αρχείων καταγραφής, ιχνοστοιχείων, ειδοποιήσεων για εκρήξεις.
- Η βασική περιστροφή είναι αυτοματοποιημένη. Τα δικαιώματα ελέγχου και πρόσβασης είναι περιορισμένα.
- Κιτ δοκιμών για την κανονικοποίηση και τη συμβατότητα μεταξύ των γλωσσών.
- Τεκμηρίωση για ενσωματωτές με παράδειγμα σε 3-4 γλώσσες και διορθώσεις.
- Το mTLS είναι ενεργοποιημένο για ευαίσθητες ενοποιήσεις. Η JWT χρησιμοποιείται μόνο ως προσθήκη, όχι ως αντικατάσταση για την υπογραφή του σώματος.
Συμπέρασμα
Η υπογραφή και επαλήθευση των αιτημάτων δεν είναι «μια κεφαλίδα», αλλά μια πειθαρχία: σαφής κανονικοποίηση, σύντομα παράθυρα του χρόνου, αντι-αναπαραγωγή, περιστροφή κλειδί, και παρατηρησιμότητα. Κατασκευή ενός ενιαίου προτύπου για όλες τις ενοποιήσεις (API και webhooks), χρήση του «παιδιού »/KMS, αποδοχή δύο κλειδιών κατά τη διάρκεια της περιστροφής, και το περίγραμμά σας θα γίνει ανθεκτικό στο spoofing, προβλέψιμο και εύκολο στον έλεγχο.