Επαλήθευση υπογραφής JSON Web Token (JWT)
- Πίνακας ελέγχου
- Τεκμηρίωση
- API
Γιατί να επαληθεύσετε την υπογραφή ενός JWT;
Ένα JSON Web Token (JWT) αναλύεται σε τρία μέρη που χωρίζονται με τελείες:
header.payload.signature. Η αποκωδικοποίηση ενός JWT είναι απλώς θέμα ανάγνωσης των δύο πρώτων
μέρη (τα οποία είναι το Base64URL). Ο καθένας μπορεί να το κάνει και ο καθένας μπορεί να τοφτιάξει
ένα JWT με το ωφέλιμο φορτίο της επιλογής σας. Αυτό που κάνει ένα JWT αξιόπιστο είναι μόνο το
υπογραφή: χωρίς επαλήθευση, η αποδοχή ενός JWT ισοδυναμεί με το να αφήσετε οποιονδήποτε να μπει στο σπίτι σας
παριστάνει ότι είναι κάποιος, χωρίς να ζητά ταυτότητα.
Αυτό το εργαλείο επαληθεύει την υπογραφή ενός JWT από ένα κλειδί. Δεν είναι ικανοποιημένος με αποκωδικοποίηση: υπολογίζει εκ νέου την υπογραφή από την κεφαλίδα, το ωφέλιμο φορτίο και το κλειδί σας και στη συνέχεια το συγκρίνει με την υπογραφή της μάρκας. Εάν τα δύο ταιριάζουν, το διακριτικό είναι αυθεντικό. Διαφορετικά ήταν πλαστό, τροποποιήθηκε ή υπογράφηκε με άλλο κλειδί.
Η επαλήθευση είναι ο ακρογωνιαίος λίθος οποιασδήποτε αρχιτεκτονικής που χρησιμοποιεί JWT
έλεγχος ταυτότητας ή εξουσιοδότηση: χωρίς έγκυρη υπογραφή, το ωφέλιμο φορτίο μπορεί να βρίσκεται.
Ένας εισβολέας που τροποποιεί το "role":"user" σε "role":"admin" δεν θα έχει
δυσκολία να το κάνετε εάν ο διακομιστής έλεγξε μόνο τη μορφή του διακριτικού και όχι την υπογραφή του.
Κοινοί αλγόριθμοι
Η προδιαγραφή JWT (RFC 7518, JSON Web Algorithms) ορίζει πολλές οικογένειες αλγορίθμων. Εδώ είναι τα πιο χρησιμοποιημένα στην παραγωγή:
- HMAC (HS256, HS384, HS512): συμμετρική υπογραφή που βασίζεται στο HMAC-SHA. Το Το ίδιο μυστικό κλειδί χρησιμοποιείται για την υπογραφή και την επαλήθευση. Απλό στη ρύθμιση, αποτελεσματικό, αλλά κάθε μέρος που είναι ικανό να επαληθεύσει το διακριτικό είναι επίσης ικανό να το εκδώσει. Προσαρμοσμένο σε σενάρια όπου ο εκδότης και ο επαληθευτής είναι η ίδια ομάδα ή τμήμα.
- RSA (RS256, RS384, RS512): ασύμμετρη υπογραφή. Τοιδιωτικό κλειδί υπογράψετε, το το δημόσιο κλειδί επαληθεύει. Ιδανικό όταν ο πομπός και Οι επαληθευτές είναι ξεχωριστές οντότητες (OAuth2, OpenID Connect, Identity Federation). Είναι ο αλγόριθμος που προτιμούν οι περισσότεροι πάροχοι δημόσιας ταυτότητας.
- ECDSA (ES256, ES384): ασύμμετρη υπογραφή σε ελλειπτικές καμπύλες. Ίδια λογική με το RSA (ιδιωτικό κλειδί για υπογραφή, δημόσιο κλειδί για επαλήθευση) αλλά με κλειδιά και πιο συμπαγείς υπογραφές για ισοδύναμο επίπεδο ασφάλειας. Όλο και περισσότερο διαδεδομένο σε σύγχρονες αρχιτεκτονικές.
Πώς να παρέχετε το κλειδί
Η μορφή του αναμενόμενου κλειδιού εξαρτάται από τον αλγόριθμο που δηλώνεται στην κεφαλίδα JWT:
- HS256, HS384, HS512: το κλειδί είναι μια μυστική συμβολοσειρά (συμβολοσειρά).
Αυτό είναι το μυστικό που κοινοποιείται στον εκδότη, που συχνά αποθηκεύεται σε μια μεταβλητή περιβάλλοντος όπως
JWT_SECRET. Χωρίς ειδική μορφοποίηση, μόνο την ακατέργαστη τιμή. - RS256, RS384, RS512: το κλειδί είναι ένα δημόσιο κλειδί RSA σε μορφή PEM,
που ξεκινά με
-----BEGIN PUBLIC KEY-----και τελειώνει με-----END PUBLIC KEY-----. Διατηρήστε τις νέες γραμμές ως έχουν, διαφορετικά OpenSSL αρνείται να το αναλύσει. - ES256, ES384: το κλειδί είναι ένα δημόσιο κλειδί ECDSA σε μορφή PEM, στην αντίστοιχη καμπύλη (P-256 για ES256, P-384 για ES384).
Παράδειγμα αναμενόμενου δημόσιου κλειδιού RSA
-----ΕΝΑΡΞΗ ΔΗΜΟΣΙΟΥ ΚΛΕΙΔΙΟΥ-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx...
...vQIDAQAB
-----END PUBLIC KEY-----
Πώς λειτουργεί η επαλήθευση;
Ο διακομιστής μας αναπαράγει ακριβώς τη λειτουργία που εκτελείται από τον πομπό:
- Διαχωρίζει το JWT σε κεφαλίδα, ωφέλιμο φορτίο και υπογραφή.
- Συνενώνει
base64url(κεφαλίδα) + "." + base64url(ωφέλιμο φορτίο). - Για το HMAC, υπολογίζει ένα HMAC-SHA-256/384/512 με το μυστικό κλειδί σας και, στη συνέχεια, συγκρίνει με το
υπογραφή που ελήφθη μέσω
hash_equals(συνεχής χρονική σύγκριση για αποφυγή επιθέσεων ώρα). - Για RSA, καλεί το
openssl_verifyμε το δημόσιο κλειδί σας σε μορφή PEM.
Θήκες χρήσης
- Εντοπισμός σφαλμάτων ελέγχου ταυτότητας API: λαμβάνετε ένα 401, ελέγξτε εάν το διακριτικό σας είναι καλά υπογεγραμμένο με το αναμενόμενο κλειδί.
- Επικύρωση διακριτικού που ελήφθη από προμηθευτή: συνεργάτης (Auth0, Keycloak, Cognito, Okta) σας στέλνει JWT που είναι υπογεγραμμένα στο RS256. θέλετε να επιβεβαιώσετε ότι προέρχονται από του με το δημόσιο κλειδί του.
- Έλεγχος ασφαλείας: επαληθεύστε ότι μια υπηρεσία τρίτου μέρους υπογράφει σωστά τα διακριτικά της με ισχυρό αλγόριθμο και όχι σε HS256 με χαμηλή μυστικότητα.
- Μη αυτόματες δοκιμές: ελέγξτε ότι ένα JWT που δημιουργείται από τον κώδικά σας περνά το επαλήθευση με το παρεχόμενο δημόσιο κλειδί.
- Γρήγορη επαλήθευση ενός ληφθέντος διακριτικού: κατά την ενσωμάτωση ενός SSO ή ενός Partner API, ελέγξτε σε λίγα δευτερόλεπτα ότι η υπογραφή/κλειδί αλυσίδα λειτουργεί προηγουμένως για να γράψετε την παραμικρή γραμμή κώδικα.
Πώς να χρησιμοποιήσετε το εργαλείο
- Επικολλήστε το πλήρες JWT (τα τρία μέρη που χωρίζονται με τελείες).
- Υποδείξτε το κλειδί που είναι προσαρμοσμένο στον αλγόριθμο κεφαλίδας:
- Για HS256, HS384 ή HS512, το κλειδί είναι η μυστική συμβολοσειρά
κοινήμε τον πομπό. Είναι μια δωρεάν συμβολοσειρά, που συχνά αποθηκεύεται σε α
μεταβλητή περιβάλλοντος όπως
JWT_SECRET. - Για RS256, RS384 ή RS512, το κλειδί είναι το δημόσιο κλειδί στη μορφή
PEM, το οποίο ξεκινά με
-----BEGIN PUBLIC KEY-----και τελειώνει με-----END PUBLIC KEY-----.
- Για HS256, HS384 ή HS512, το κλειδί είναι η μυστική συμβολοσειρά
κοινήμε τον πομπό. Είναι μια δωρεάν συμβολοσειρά, που συχνά αποθηκεύεται σε α
μεταβλητή περιβάλλοντος όπως
- Εκτελέστε τον έλεγχο. Το εργαλείο εμφανίζει την κατάσταση (έγκυρη ή μη έγκυρη) και το αποκωδικοποιημένο ωφέλιμο φορτίο.
Κοινές παγίδες προς αποφυγή
- Αλγόριθμος "κανένας": η προδιαγραφή επιτρέπει
alg: κανένα, που σημαίνει "όχι υπογραφή». Ένα κλασικό ελάττωμα συνίσταται στη δημιουργία ενός διακριτικού με αυτήν την κεφαλίδα ελπίζοντας ότι το ο διακομιστής το δέχεται. Το εργαλείο μας απορρίπτει συστηματικά διακριτικά μεalg: κανένα. - Σύγχυση HMAC εναντίον RSA (σύγχυση αλγορίθμου): ένας εισβολέας αλλάζει τον αλγόριθμο
RS256σεHS256και υπογράφει το ωφέλιμο φορτίο με το δημόσιο κλειδί RSA που χρησιμοποιείται ως μυστικό HMAC. Εάν ο διακομιστής δεν ελέγχει τον αλγόριθμο, δέχεται το διακριτικό. Πάντα κλειδώστε τον αναμενόμενο αλγόριθμο στην πλευρά του διακομιστή. - HMAC μυστικά κωδικοποιημένα: ένα μυστικό που δεσμεύεται σε ένα αποθετήριο Git αποδίδει όλη η εμπιστοσύνη στις μάρκες έχει χαθεί. Αποθηκεύστε μυστικά σε μεταβλητές περιβάλλοντος ή μια ασφαλής εφαρμογή.
- Δημόσιο κλειδί έναντι ιδιωτικού κλειδιού: για να επαληθεύσουμε ένα JWT που είναι υπογεγραμμένο σε RSA ή ECDSA, παρέχει το δημόσιο κλειδί, ποτέ το ιδιωτικό. Το ιδιωτικό χρησιμοποιείται μόνο για υπογραφή και όχι δεν πρέπει ποτέ να βγαίνει από τον πομπό.
- Η λήξη αγνοήθηκε: μια έγκυρη υπογραφή σε ένα διακριτικό που έχει λήξει δεν πρέπει
ποτέ να μην γίνεται αποδεκτή. Θυμηθείτε να ελέγξετε τα
expκαιnbf. - Μη ελεγχόμενο κοινό: ένα διακριτικό που προορίζεται για το API A δεν πρέπει να γίνει αποδεκτό
από το API B. Ελέγξτε την αξίωση
aud.
Διαχρονικές αξιώσεις: exp και nbf
Πέρα από την υπογραφή, ένα έγκυρο JWT πρέπει επίσης να σέβεται τους χρονικούς περιορισμούς του:
- λήξη (λήξη): το διακριτικό δεν είναι πλέον έγκυρο μετά από αυτήν την ημερομηνία.
- nbf (όχι πριν): το διακριτικό δεν είναι ακόμη έγκυρο πριν από αυτήν την ημερομηνία.
Το εργαλείο μας σηματοδοτεί ρητά πότε ένα διακριτικό έχει λήξει ή όχι ακόμα ισχύειακόμα και αν η υπογραφή του είναι σωστή. Αυτό είναι σημαντικό: μια έγκυρη υπογραφή στο α Το ληγμένο διακριτικό δεν πρέπει ποτέ να γίνει αποδεκτό στην παραγωγή.
Διαφορά με τον αποκωδικοποιητή JWT μας
Ο αποκωδικοποιητής JWT απλώς αποκωδικοποιεί την κεφαλίδα και ωφέλιμο φορτίο για να είναι ευανάγνωστα. Δεν εκτελεί καμία επαλήθευση υπογραφής και μη ζητάς κλειδί. Χρησιμοποιήστε το για να επιθεωρήσετε γρήγορα τα περιεχόμενα ενός διακριτικού. Χρησιμοποιήστε το Επαληθευτής JWT (αυτή η σελίδα) όποτε χρειάζεται να αποδείξετε ότι ένα διακριτικό είναι αυθεντικό. Για να δημιουργήσετε ένα υπογεγραμμένο JWT για δοκιμή, χρησιμοποιήστε το δικό μας Εργαλείο δημιουργίας JWT.
Συχνές ερωτήσεις
Γιατί RS256 αντί για HS256;
Με το HS256, ο εκδότης και ο επαληθευτής μοιράζονται το ίδιο μυστικό: τα πάντα Ο επαληθευτής μπορεί επομένως να εκδώσει διακριτικά. Είναι διαχειρίσιμο όταν ελέγχετε και τα δύο άκρα. Από ότι μιλάμε για έναν πάροχο ενιαίας ταυτότητας με πολλές καταναλωτικές υπηρεσίες, αλλάζουμε στο RS256: ο πομπός διατηρεί το ιδιωτικό κλειδί, διανέμουμε το δημόσιο κλειδί σε όλα τα API που πρέπει να ελέγξετε. Κανένα API που καταναλώνει δεν μπορεί να πλαστογραφήσει διακριτικά.
Πώς μπορώ να ανακτήσω το δημόσιο κλειδί ενός παρόχου ταυτότητας (IdP);
Τα περισσότερα IdP εκθέτουν ένα τυποποιημένο τελικό σημείο JWKS (π.χ.
https://example.com/.well-known/jwks.json). Αυτό το τελικό σημείο επιστρέφει ένα JSON που περιέχει
τα ενεργά δημόσια κλειδιά. Μπορείτε να μετατρέψετε την καταχώριση JWK που ταιριάζει με το παιδί
από την κεφαλίδα του JWT σας σε ένα κλειδί PEM μέσω της εντολής openssl ή μέσω μιας βιβλιοθήκης
JWKS από τη στοίβα σας (π.χ. jose-jwt, jwks-rsa).
Τι να κάνετε εάν η επαλήθευση αποτύχει;
Πρώτα ελέγξτε τον αλγόριθμο: ένα διακριτικό που είναι υπογεγραμμένο στο HS256 δεν μπορεί να επαληθευτεί με ένα κλειδί RSA και
αντίστροφα. Στη συνέχεια, ελέγξτε το κλειδί: ένας επιπλέον λευκός χαρακτήρας, ένας λείπει νέα γραμμή
σε κλειδί PEM ή μυστικό HMAC ελαφρώς διαφορετικό από αυτό που χρησιμοποιεί ο εκδότης
είναι αρκετά για να αποτύχει ο έλεγχος. Εάν το IdP έχει πραγματοποιήσει μια εναλλαγή κλειδιού, το δικό σας
Το παιδί μπορεί να δείχνει ένα κλειδί που δεν έχετε πλέον.
Τι είναι το JWKS;
Το JWKS (JSON Web Key Set, RFC 7517) είναι μια μορφή JSON που περιγράφει ένα σύνολο
δημόσια κλειδιά. Κάθε κλειδί αναγνωρίζεται από ένα kid (αναγνωριστικό κλειδιού) και το JWT για έλεγχο
αναφέρεται σε αυτό το παιδί στην κεφαλίδα του. Ο μηχανισμός επιτρέπει στο IdP να το περιστρέψει
κλειδιά χωρίς να σπάσουν τα πούλια: απλώς ζητούν το τελικό σημείο JWKS για να το ανακτήσουν
κλειδί που αντιστοιχεί στο kid του διακριτικού που ελήφθη.
Πώς μπορώ να δημιουργήσω ένα ζεύγος κλειδιών RSA για να υπογράψω τα JWT μου;
Με OpenSSL: openssl genrsa -out private.pem 2048 τότε
openssl rsa -in private.pem -pubout -out public.pem. Πλαϊνή πινακίδα με ιδιωτικό κλειδί
εκδότη, το δημόσιο κλειδί ελέγχει από την πλευρά του καταναλωτή. Για νέες υπηρεσίες, προτιμήστε 3072 ή
4096 bit.
Θα πρέπει το JWT να κρυπτογραφηθεί εκτός από την υπογραφή του (JWE);
Ένα υπογεγραμμένο JWT (JWS) εγγυάται την ακεραιότητα και την αυθεντικότητα, αλλά το ωφέλιμο φορτίο παραμένει αναγνώσιμο από όποιος το σηκώσει. Εάν το διακριτικό περιέχει ευαίσθητα δεδομένα (εσωτερικά αναγνωριστικά, δικαιώματα λεπτομερή, προσωπικά δεδομένα), λάβετε υπόψη τη μορφή JWE (JSON Web Encryption). το οποίο κρυπτογραφεί το ωφέλιμο φορτίο εκτός από την υπογραφή του.
Παράδειγμα αιτήματος
curl -X POST https://cdrn.fr/api/v1/tools/jwt-verifier/execute \
-H "Content-Type: application/json" \
-d '{"token":"...","key":"..."}'
Σχήμα εισόδου
| Πεδίο | Τύπος | Απαιτείται | Προεπιλογή |
|---|---|---|---|
token |
text | ✓ | – |
key |
text | ✓ | – |
Σημεία πρόσβασης
GET https://cdrn.fr/api/v1/tools- εμφανίζει όλα τα διαθέσιμα εργαλείαGET https://cdrn.fr/api/v1/tools/jwt-verifier- ανακτά το σχήμα αυτού του εργαλείουPOST https://cdrn.fr/api/v1/tools/jwt-verifier/execute- εκτελεί αυτό το εργαλείο με payload JSON