Privacy Policy
© 2025 linux101.dev

JSON Web Signature (JWS)

JSON Web Signature (JWS) is a compact, URL-safe means of representing claims to be digitally signed or integrity protected using JSON-based data structures.

Roles in JWS

  • Claimant: The entity making the claims.
  • Verifier: The entity verifying the claims.

How JWS Works

JWS allows you to create a digital signature for your JSON data, ensuring its integrity and authenticity.

JWS Structure

Each part of the JWS is base64url encoded and separated by periods (.). The general structure is as follows:

Header.Payload.Signature
  • Header: Contains metadata about the token, including the signing algorithm in a JSON object. Besides being base64url encoded, it is also publicly accessible.
  • Payload: The actual data being transmitted, which is typically a JSON object. Payload can be publicly accessible but may also be encrypted (in such case we're dealing with a JWE - JSON Web Encryption).
  • Signature: A cryptographic signature created by signing the header and payload with a secret key. The signing input is a hash of the header and payload combined e.g. HashFunction(Base64Url(Header).Base64Url(Payload))

Steps to create a JWS

Let's say we want to create a JWS for a simple JSON object containing a message.

The message we would like to sign is:

{
  "msg": "Hello World"
}

1. Create the Header:

According to RFT 7515, the header for our JWS must include an alg (algorithm) field.

{
  "alg": "HS256"
}

The alg field specifies two functions. The function used to hash the signing input and the function used to sign the JWS. HS256 means we will be using HMAC to create a signature and SHA-256 to hash the signing input. RFT 7515 specifies also other algorithms that will be listed in the following sections.

2. Create the Payload:

The payload is the actual data we want to transmit. In our case, it's the message mentioned earlier:

{
  "msg": "Hello World"
}

3. Base64url Encode the Header and Payload:

Next, we need to base64url encode both the header and payload.

Base64Url(Header) = eyJhbGciOiAiSFMyNTYifQ
Base64Url(Payload) = eyJtc2ciOiAiSGVsbG8gV29ybGQifQ

Note: Base64url encoding is similar to base64 encoding, but it replaces '+' with '-' and '/' with '_', and it omits padding characters ('='). Its goal is to transform non-printable bytes into a printable format and make the encoded output URL-safe.

4. Create the Signing Input:

The signing input is created by concatenating the base64url encoded header and payload with a period (.) in between.

Signing Input = Base64Url(Header).Base64Url(Payload)
Signing Input = eyJhbGciOiAiSFMyNTYifQ.eyJtc2ciOiAiSGVsbG8gV29ybGQifQ

5. Create the Signature:

Now, we need to create the signature by signing the signing input with a secret key using the specified algorithm (HS256 in our case).

SecretKey = your-256-bit-secret
HashedInput = SHA256(Signing Input)
HashedInput = 11de0915b2122ebacde13d5b3b07cd3ea5415666e0dc9a08f2093e1dd1b38e43

Signature = HMAC(HashedInput, SecretKey)
Signature = 1cf745646ce9c7cd6031fb670e960228ef97756ab612ea9f99acf3b803132936
Base64Url(Signature) = MWNmNzQ1NjQ2Y2U5YzdjZDYwMzFmYjY3MGU5NjAyMjhlZjk3NzU2YWI2MTJlYTlmOTlhY2YzYjgwMzEzMjkzNg

6. Construct the JWS:

Finally, we can construct the JWS by concatenating the base64url encoded header, payload, and signature with periods (.) in between.

JWS = Base64Url(Header).Base64Url(Payload).Base64Url(Signature)
JWS = eyJhbGciOiAiSFMyNTYifQ.eyJtc2ciOiAiSGVsbG8gV29ybGQifQ.MWNmNzQ1NjQ2Y2U5YzdjZDYwMzFmYjY3MGU5NjAyMjhlZjk3NzU2YWI2MTJlYTlmOTlhY2YzYjgwMzEzMjkzNg

Verifying a JWS

To verify a JWS, the verifier needs to perform the following steps:

  • Split the JWS into its three components: header, payload, and signature.
  • Base64url decode the header and payload.
  • Recreate the signing input by concatenating the base64url encoded header and payload with a period (.) in between.
  • Hash the signing input using the same hash function specified in the "alg" field of the header.
  • Use the same secret key to create a new signature from the hashed signing input.
  • Compare the newly created signature with the signature from the JWS. If they match, the JWS is valid and has not been tampered with.

Types of signature algorithms

There are two main types of signature algorithms used in JWS:

  • Symmetric Algorithms: These algorithms use the same secret key for both signing and verification. Examples include HMAC with SHA-256 (HS256), HMAC with SHA-384 (HS384), and HMAC with SHA-512 (HS512).
  • Asymmetric Algorithms: These algorithms use a pair of keys: a private key for signing and a public key for verification. Examples include RSA with SHA-256 (RS256), RSA with SHA-384 (RS384), RSA with SHA-512 (RS512), ECDSA with P-256 and SHA-256 (ES256), ECDSA with P-384 and SHA-384 (ES384), and ECDSA with P-521 and SHA-512 (ES512).

Symmetric algorithms are generally faster and easier to implement, but they require both parties to securely share the secret key. Due to that they are usually used for session management. Server typically store the secret key securely and use it to sign and verify tokens.

Asymmetric algorithms, on the other hand, provide a higher level of security by using a pair of keys, but they are more computationally intensive. Asymmetric algorithms are usually used in server-to-server communication.

RFC 7515 defines the JWS specification and the various algorithms that can be used. Examples include:

  • HS256: HMAC using SHA-256 hash algorithm.
  • HS384: HMAC using SHA-384 hash algorithm.
  • HS512: HMAC using SHA-512 hash algorithm.
  • RS256: RSASSA-PKCS1-v1_5 using SHA-256 hash algorithm.
  • RS384: RSASSA-PKCS1-v1_5 using SHA-384 hash algorithm.
  • RS512: RSASSA-PKCS1-v1_5 using SHA-512 hash algorithm.
  • ES256: ECDSA using P-256 curve and SHA-256 hash algorithm.
  • ES384: ECDSA using P-384 curve and SHA-384 hash algorithm.
  • ES512: ECDSA using P-521 curve and SHA-512 hash algorithm.
  • PS256: RSASSA-PSS using SHA-256 hash algorithm and MGF1 with SHA-256.
  • PS384: RSASSA-PSS using SHA-384 hash algorithm and MGF1 with SHA-384.
  • PS512: RSASSA-PSS using SHA-512 hash algorithm and MGF1 with SHA-512.

Conclusion

JSON Web Signature (JWS) is a powerful tool for ensuring the integrity and authenticity of JSON data. By following the steps outlined above, you can create and verify JWS tokens to securely transmit information between parties.