JSON Web Keys

A JSON Web Key (JWK) provides a standard method for representing a cryptographic key using JSON (JavaScript Object Notation). In the case of Hosted Login, these web keys are used to verify the signature on JSON Web Tokens (i.e., identity tokens). As a general rule, you don’t have to worry much about you JSON web keys: when you subscribe to Hosted Login, Akamai Identity Cloud personnel will create your web keys and and publish them for you. You can view these keys at any time by accessing your JWK endpoint; that endpoint will have a URL similar to this:

https://v1.api.us.janrain.com/00000000-0000-0000-0000-000000000000/login/jwk

Note. As we mentioned, the keys found on your JWK endpoint can only be used for verifying signatures. That’s why there are no security concerns about making them publicly available: these keys are supposed to be publicly available.

As published on the JWK page, a hosted login web key looks something like this:

{
    "use":"sig",
    "kty":"RSA",
    "kid":"51300370a8e1ac0a14a59cdd9c881d3f24c01f78",
    "alg":"RS256",
    "n":"w9OLNr_6sIuqr8OO3nPzorbv8tkmXC-m0k0O3W6gdk1QipvJ2pZkRSzD_iIWnEvYV11RuOBSAb7e_nU7mwNnxX6mORyJIEwnHKucBwaHQhuo56uVUjNTsRI6OuLB6REwxLM0ePPQPJNaXncWzt83oYdHU10VPmp5x0Sj-GjTvMpm2Y4I14KnFUXMEvIC-e5lf2P7q6KMXNw3PchEvmO5fVCgXf5-FgzDzEyn0qXrerdui4lGUtzcREPFksPNLNMlqp0XL5Kz1QLLkKDtR3dVjEtViEYJ6extcI-xFEV785hO4Ok36N99ht41EZk8ibrflNnYkJIEXAw_LKkmtxyZKw",
    "e":"AQAB"
}

The preceding key properties (such as use and kty) are explained in the following sections.

use

Identifies whether a public key is used for: 

  • Encrypting data (enc)
  • Verifying the signature on data (sig)

For hosted login, the use will always be set to sig; that’s because these keys are only used for verifying signatures on identity tokens.

kty

The "kty" (key type) parameter identifies the cryptographic algorithm family used with the key; the two most-common values are RSA (Rivest–Shamir–Adleman, the default value for hosted login) and EC (Elliptic Curve Cryptography).  kty values are case-sensitive and must be included in all JSON Web Keys.

kid

Identifier for a specific JSON Web Key; for Hosted Login, the kid (key identifier) these keys are used to sign JWT tokens. Key identifiers are only required if you have multiple keys within your JSON Web Key Set; this enables you to distinguish between individual keys in the key set. If you only have one such key, there’s no need for a key identifier because there aren’t any other keys in the key set.

Despite the fact that these values are used to identify individual keys, kid values do not have to be unique. Instead, two keys can have the same kid as long as they differ in other ways (such as key use or key type). 

alg

Identifies the cryptographic algorithm used to sign the token: a token signature is not valid if the alg value does not represent a supported algorithm. By default, Hosted Login uses RS256(RSA Digital Signature Algorithm with SHA-256) as its encryption algorithm. This is a public key/private key system in which public keys are generated using the modulus and the exponent.

Similar to key identifiers, alg values are case-sensitive.

n

Along with the exponent (e), the modulus is used to generate public key values.  

e

Along with the modulus (n), the exponent is used to generate public key values. The exponent, which is stored as a Base64urlUInt-encoded value, is typically set to 65537 (AQAB when Base64urlUInt-encoded).

Retrieving Web Keys by Making an API Call

Information about your JSON Web Keys can also be returned by calling the /{customer_id}/login/jwk endpoint. For example, this Curl command returns JSON Web Key information for the customer with the customer ID 00000000-0000-0000-0000-000000000000:

curl https://v1.api.us.janrain.com/00000000-0000-0000-0000-000000000000/login/jwk

In turn, you should get back something similar to this (note: color coding has been added to help distinguish the individual keys):

{
    "keys": [
        {
            "use": "sig",
            "kty": "RSA",
            "kid": "51300370a8e1ac0a14a59cdd9c881d3f24c01f78",
            "alg": "RS256",
            "n": "w9OLNr_6sIuqr8OO3nPzorbv8tkmXC-m0k0O3W6gdk1QipvJ2pZkRSzD_iIWnEvYV11RuOBSAb7e_nU7mwNnxX6mORyJIEwnHKucBwaHQhuo56uVUjNTsRI6OuLB6REwxLM0ePPQPJNaXncWzt83oYdHU10VPmp5x0Sj-GjTvMpm2Y4I14KnFUXMEvIC-e5lf2P7q6KMXNw3PchEvmO5fVCgXf5-FgzDzEyn0qXrerdui4lGUtzcREPFksPNLNMlqp0XL5Kz1QLLkKDtR3dVjEtViEYJ6extcI-xFEV785hO4Ok36N99ht41EZk8ibrflNnYkJIEXAw_LKkmtxyZKw",
            "e": "AQAB"
        },
        {
            "use": "sig",
            "kty": "RSA",
            "kid": "f63eecd7318b6a6bcfae82f9607689756c6dd83e",
            "alg": "RS256",
            "n": "2kTH-jB0XDAb4yJy9rRMKNTNk4FEz7n3mbzj7nvupGvozyrpgHNFzSNW-Faxfo8v3cMdekd0-3S1ioNquAn9bbKZ8j2D4wK7rYtJgwOE8vnHkLUPAQuv_ymUgdgRAz7iQhsUN-vs8QLIDTddzEGnKWZASndLb-CYN_3eSWCDL7J8kQGkm9EI91OY1tKUUdIxlHpr90zAR36CFWWIJY1hpgFFnC1Po2r4nBtkBZD-SG_tmWB7fmWmF9v9MNnpmY00h3PsvUfzb6dSzLNt3H2ocSys7F5syaulRGLiKFiTalPPri_wAj-CPVfqiZuEys8PNTVd6T969PM4dIFdIsR0gw",
            "e": "AQAB"
        },
        {
            "use": "sig",
            "kty": "RSA",
            "kid": "a964a617a74b6cece03857daa1e8e144d11132a9",
            "alg": "RS256",
            "n": "7-LW8dGJKFsxU6ztkRA_qdhzvuHkoeWlRGL6ejqW9z_PxtDnQbLIpiy0vFm_DYAyNyFXt1EbuVMzESd4XRCKue4Lw2tGS_iiVQhlq7RkwAYG-hOkiiIHCcLVVCxtPm8gdmW-Cp4sdDozG0Yc99os-nyBtm2YzZ3ECAMsQsQVIjR03_JD3l1u79F4EzWcs2aBMOQ0NFDHqoQyk16Gf6Ww5QMXBtFhI508kYDMg71-0cxpssOrkztBBkxH1WPDpeliEAO91Sy1HDgXkuKdEuPkB3JxUqGXiw_UAez0a4XXBMFNkc5pV8byrKWokKmzNSgSfObqaRx13wOk5xjyVpyfHQ",
            "e": "AQAB"
        }
    ]
}

In the preceding API call, we got back three different web keys, keys that have the following key identifiers:

  • 51300370a8e1ac0a14a59cdd9c881d3f24c01f78
  • f63eecd7318b6a6bcfae82f9607689756c6dd83e
  • a964a617a74b6cece03857daa1e8e144d11132a9

JSON Web Keys in Action

Because OpenID Connect clients understand how to retrieve and decipher JSON Web Keys, you typically don’t have to deal with the process of how identity token signatures get verified: to a very large extent, they just do. If you’re interested, however, here’s a brief overview of the activities that takes place when an application needs to verify a token signature:

  1. Upon receipt of the token, the application connects to the jwk URL and retrieves the JSON Web Key Set (a web key set, as the name implies, is a collection of all the JSON web keys used in your implementation of Hosted Login). In the sample web site we looked at previously, that collection will contain three web keys, with the following kid values:
  • 51300370a8e1ac0a14a59cdd9c881d3f24c01f78
  • f63eecd7318b6a6bcfae82f9607689756c6dd83e
  • a964a617a74b6cece03857daa1e8e144d11132a9

  1. The application decodes the token header and extracts the kid (key identifier) and the alg (algorithm). For example, the token header might look like this:
     
{   
   "alg": "RS256",
   "typ": "JWT",
   "kid": "f63eecd7318b6a6bcfae82f9607689756c6dd83e"
}

In the preceding header, the kid value is f63eecd7318b6a6bcfae82f9607689756c6dd83e and the algorithm is RS256.

  1. The application searches through the JWKS to find the key that has the specified key identifier and that uses the specified algorithm :

{
     "use": "sig",
     "kty": "RSA",
     "kid": "f63eecd7318b6a6bcfae82f9607689756c6dd83e",
     "alg": "RS256",
     "n": "2kTH-jB0XDAb4yJy9rRMKNTNk4FEz7n3mbzj7nvupGvozyrpgHNFzSNW-Faxfo8v3cMdekd0-3S1ioNquAn9bbKZ8j2D4wK7rYtJgwOE8vnHkLUPAQuv_ymUgdgRAz7iQhsUN-vs8QLIDTddzEGnKWZASndLb-CYN_3eSWCDL7J8kQGkm9EI91OY1tKUUdIxlHpr90zAR36CFWWIJY1hpgFFnC1Po2r4nBtkBZD-SG_tmWB7fmWmF9v9MNnpmY00h3PsvUfzb6dSzLNt3H2ocSys7F5syaulRGLiKFiTalPPri_wAj-CPVfqiZuEys8PNTVd6T969PM4dIFdIsR0gw",
     "e": "AQAB" }

  1. The application uses that key to verify the signature.