Tokens and signatures
Digital signatures
Digital signatures are a cryptographic technique that ensures the authenticity and integrity of messages. They guarantee that:
- The message originates from a specific sender (authenticity).
- The message's content hasn't been modified from how it was written by the sender (integrity).
However, digital signatures do not encrypt the message—anyone can read its contents.
How digital signatures work
Digital signatures use public key cryptography, which involves a key pair: a private key (kept secret) and a public key (shared openly). Here's the process:
- A private key is used to create a signature:
- The message is hashed (a unique, fixed-length representation of the message).
- The hash is encrypted using the sender's private key, creating the signature.
- The message and signature are sent to the recipient.
- The recipient verifies the signature using the sender's public key by:
- Decrypting the signature to retrieve the hash.
- Independently hashing the message and comparing the two hashes. If they match, the message is authentic and has not been changed.
So for example, imagine you get a publicly readable message, like hello world
, and the message is “signed” with the signature j2e80w8dj9f8
. If you'd like to be sure that the message is genuine, and you have a copy of the sender's public key, you can use this key to decrypt the signature and make sure that it is valid. If it is, you know two things for sure: who sent the message, and that nobody intercepted the message and messed with it in the middle, since part of the verification process involves hashing the message and comparing it to the decrypted signature.
Key Terminology
- Sign: The process of generating a digital signature with a private key and attaching it to a message.
- Verify: The process of using a public key to confirm the signature's validity and the message's integrity.
Clerk leverages digital signatures in JSON Web Tokens (JWTs) to securely authenticate users.
JWTs
JSON Web Tokens (JWTs) are a lightweight format for transmitting digitally signed data over the internet. They are commonly used for authentication and information exchange.
Structure of a JWT
A JWT's format is three base64-encoded parts, separated by dots:
Here's an example of a JWT:
Let's decode and break down each part:
Header: The header specifies metadata about the token, such as the hashing algorithm used for the signature. There are several different hashing algorithms that can be used to digitally sign a JWT. This example's header tells us that the signature's hash was created using the RS256
algorithm:
Payload: The payload contains the actual information that you want to send. In Clerk's case, this includes information about the authenticated user. Read more about Clerk's session JWT payload.
Signature: The signature is created by hashing the header and payload, and then encrypting the hash with the private key.
When decoding the signature from base64, an error is thrown because the signature is not base64-encoded. This is expected behavior. The recipient must use the JWT issuer's public key and the algorithm specified in the header (e.g., RS256) to verify the signature. Clerk's SDKs all ship with a method for verifying the signature of a Clerk JWT: authenticateRequest()
. But if you'd like to verify the signature yourself, see the guide on manual JWT verification.
How Clerk uses JWTs
To learn more about how Clerk uses JWTs, read the guide on how Clerk works.
Feedback
Last updated on