JSON Web Signature (JWS) and JWS Detached for a five-year-old.

Tomasz Zwierzchoń
The Startup
Published in
3 min readJul 5, 2019

Working for some time with JSON Web Signature (JWS) I came to the conclusion that many developers do not understand what it is and how it works.

JSON Web Signature (JWS) represents content secured with digital signatures or Message Authentication Codes (MACs) using JSON-based data structures.

There are two defined serializations for JWSs: a compact (described in this article) and a JSON.

The compact serialised JWS is a string containing three parts (in order) joined with a dot (“.”):

  • Header,
  • Payload,
  • Signature.

Example of the compact serialised JWS string: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjIyMTgyMzkwMjIsIm5hbWUiOiJUb21hc3ogWndpZXJ6Y2hvxYQifQ.t3VhQ7QsILDuV_HNFSMI-Fb2FoT7fuzalpS5AH8A9c0
Each part is BASE64URL encoded.

The Header describe the digital signature or message authentication code (MAC) applied to the the Payload and optionally additional properties of the JWS.

Header part before encoding is a JSON structure (example below):

{
"alg": "HS256",
"typ": "JWT"
}

The Header parameter names (object keys) within the Header must be unique. There are registered Header parameter names:

  • “alg” (required) — algorithm, which identifies the cryptographic
    algorithm used to secure the JWS;
    It can be set to ‘none’, which indicates that the Signature must be an empty string!
  • “jku” — (optional) JWK Set URL is a URI that refers to a resource for a set of JSON-encoded public keys, one of which corresponds to the key used to digitally sign the JWS;
  • “jwk” — (optional) JSON Web Key is the public key that corresponds to the private key used to digitally sign the JWS. This public key is represented as a JSON Web Key [JWK];
  • “kid” — (optional) key ID is a hint indicating which key was used to secure the JWS. It can be used to inform recipient that key is changed;
  • “x5u” — (optional) X.509 URL is a URI that points to a resource for the X.509 public key certificate or certificate chain corresponding to the private key used to digitally sign the JWS;
  • “x5c” — (optional) X.509 certificate chain contains the X.509 public key certificate or certificate chain corresponding to the private key used to digitally sign the JWS;
  • “x5t” — (optional) X.509 certificate SHA-1 thumbprint (fingerprint) is a
    base64url-encoded SHA-1 thumbprint (a.k.a. digest) of the DER
    encoding of the X.509 public certificate [RFC5280] corresponding to the private key used to digitally sign the JWS;
  • “x5t#S256” — (optional) X.509 certificate SHA-256 thumbprint (fingerprint) is a base64url-encoded SHA-256 thumbprint (a.k.a. digest)
    of the DER encoding of the X.509 public certificate corresponding
    to the private key used to digitally sign the JWS;
  • “typ” — (optional) type is used by JWS applications to declare the media type of the complete JWS;
  • “cty” — (optional) content type is used by JWS applications
    to declare the media type of the Payload.

In our example header, we can see that JWS type is JSON Web Token (JWT) and that Payload is secured by HS256 (HMAC with SHA-256) cryptographic algorithm.

The payload can be any content. It can be JSON but it is not needed.

The signature is computed in the manner defined for the particular algorithm being used (and declared in the Header) from ASCII(BASE64URL(UTF8(JWS Protected Header)) || ‘.’ ||BASE64URL(JWS Payload)).

Important note: Do not confuse BASE64URL with BASE64!
In BASE64URL:

  • all trailing ‘=’ are removed
  • ‘+’ is replaced by ‘-’
  • ‘/’ is replaced by ‘_’.

JWS Detached is a variation of JWS that allows you to sign content (body) of HTTP request or response without its modification.

The HTTP header “x-jws signature” is added, which contains data allowing to check whether the message has not been changed on way from the sender to the recipient.

JWS Detached generation algorithm is very simple:
a) Generate a standard JWS using compact serialization using HTTP body as a payload,
b) Turn the middle part (Payload) into an empty string,
c) Put final string in the HTTP header “x-jws signature”

Example of the JWS Detached string: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..t3VhQ7QsILDuV_HNFSMI-Fb2FoT7fuzalpS5AH8A9c0

Validation HTTP message with JWS Detached is simple too:
a) Get the HTTP header “x-jws signature”,
b) Get BASE64URL HTTP body
c) Put generate string b) into the Payload section
d) Validate JWS

JWS is often found in tandem with JSON Web Token (JWT), JSON Web Encryption (JWE) or JSON Object Signing and Encryption (JOSE). Many similar shortcuts may lead to confusion.

--

--

Tomasz Zwierzchoń
The Startup

Skilled team leader and trainer. I excel at translating between business and technical languages. I am well-versed in agile methodologies, BDD, and TDD.