Server JWK set
The Connect2id server needs to be supplied with a set of cryptographic keys to secure the tokens and other objects that it issues:
-
Token signing keys – Public / private key pairs for signing the issued tokens (may reside in a PKCS#11 compliant HSM):
- RSA key pair with a size of 1024 or 2048 bits (2048 is recommended).
- EC key pair with P-256 curve.
- EC key pair with P-384 curve.
- EC key pair with P-521 curve.
Each key must specify a unique key ID (“kid”) and its use must be set to “sig” (signature). The public keys will be published at a discoverable URL so that clients can download them in order to validate the tokens.
-
Access token encryption key – An optional AES key for applying encryption over the signed access tokens (JWT), in order to provide confidentiality of the token content while in transit. This AES key must be shared securely and out-of-band with all servers which are expected to consume encrypted access tokens. This key must also specify a unique key ID (“kid”). Its use must be set to “enc” (encryption). The supported AES key sizes are 128, 192 and 256 bits.
If access tokens are not going to be encrypted this key can be omitted.
-
Secret HMAC key – A secret 256-bit key for applying HMAC-SHA-256 protection to the issued session identifiers and identifier-based access tokens. This key must have a key ID (“kid”) set to “hmac” and its use must be set to “sig” (signature).
-
Secret user ID encryption key – A secret 256-bit key for encrypting pairwise subject identifiers with AES in SIV mode. This key must have a key ID (“kid”) set to “subject-encrypt” and its use must be set to “enc” (encryption).
JWK set configuration
The server keys are stored in JSON Web Key Set (JWK set) format in the following file:
WEB-INF/jwkSet.json
The JWK set can be alternatively passed via a jose.jwkSet Java system property. The property value is the JSON representation of the JWK set. The JSON string can be additionally BASE64URL-encoded, to not have to deal with escaping special characters in the shell:
-Djose.jwkSet=eyAia2V5cyIgOiBbIHsgImt0eSIgOiAiUlNBIiwNCiAgICAgICAgICAgICAgIC...
The external configuration guide has tips for setting system properties from environment variables, local files and other locations.
Important
Before you put a Connect server in production you must generate a new JWK set and put it in place of the sample JWK set that comes with the original installation package.
The private and secret keys must be kept secure at all times, and must never be disclosed to other parties!
How to generate a new JWK set
We suggest you use our JWK generator for that (download link), by invoking it with the following parameters:
java -jar jwkset-gen.jar jwkSet.json
Sample console output:
JWK set generator for Connect2id server v6.x+
[1] Generated new signing RSA key with ID CXup
[2] Generated new signing EC P-256 key with ID yGvt
[3] Generated new signing EC P-384 key with ID 9nHY
[4] Generated new signing EC P-521 key with ID tVzS
[5] Generated new encryption AES key with ID 5C93
[6] Generated new HMAC SHA key with ID hmac
[7] Generated new pairwise subject AES SIV encryption key with ID subject-encrypt
Replace the sample WEB-INF/jwkSet.json
file, then restart the server.
The Connect2id server performs a check of the JWK set during startup. If a key is found to be missing or non-compliant, the server will log an error message and abort on the spot.
JWK roll-over
To facilitate rollover of the keys used to sign or encrypt the issued tokens, generate a new JWK for each key type, with a new unique identifier (“kid”), and prefix the JWK to the existing JWK set.
The Connect2id server picks the first suitable JWK in the set when it needs to sign or encrypt a token. The remaining public keys in the set will still be published (so clients can still access them to validate tokens secured with an outdated key), but will otherwise not be used by the server.
{
"keys": [
{ ... place new key here ... },
{ ... old key ... },
{ ... old key ... }
]
}
Important: The HMAC-SHA key (kid : hmac
) and the subject encryption key
(kid : subject-encrypt
) must not be updated!
The easiest way to generate a new signing and encryption JWKs and prefix it to an existing JWK set file is to use the JWK generator. The first argument is the existing JWK set file, tne second one the new file with the updated JWK set:
java -jar jwkset-gen.jar jwkSet.json updatedJWKSet.json
Sample console output:
JWK set generator for Connect2id server v6.x+
[1] Generated new signing RSA key with ID 8tMP
[2] Generated new signing EC P-256 key with ID tXLR
[3] Generated new signing EC P-384 key with ID 5qoz
[4] Generated new signing EC P-521 key with ID DiUS
[5] Generated new encryption AES key with ID 97L9
[6] Prefixed newly generated keys to existing JWK set
To roll-over to the new keys, replace the old WEB-INF/jwkSet.json
file, then
restart the server.
Sample JWK set
{ "keys" : [ { "kty" : "RSA",
"use" : "sig",
"kid" : "CXup",
"n" : "hrwD-lc-IwzwidCANmy4qsiZk11yp9kHykOuP0yOnwi36VomYTQVEzZXgh2sDJpGgAutdQudgwLoV8tVSsTG9SQHgJjH9Pd_9V4Ab6PANyZNG6DSeiq1QfiFlEP6Obt0JbRB3W7X2vkxOVaNoWrYskZodxU2V0ogeVL_LkcCGAyNu2jdx3j0DjJatNVk7ystNxb9RfHhJGgpiIkO5S3QiSIVhbBKaJHcZHPF1vq9g0JMGuUCI-OTSVg6XBkTLEGw1C_R73WD_oVEBfdXbXnLukoLHBS11p3OxU7f4rfxA_f_72_UwmWGJnsqS3iahbms3FkvqoL9x_Vj3GhuJSf97Q",
"e" : "AQAB",
"d" : "bmpuqB4PIhJcndRs_i0jOXKjyQzwBXXq2GuWxPEsgFBYx7fFdCuGifQiytMeSEW2OQFY6W7XaqJbXneYMmoI0qTwMQcD91FNX_vlR5he0dNlpZqqYsvVN3c_oT4ENoPUr4GF6L4Jz74gBOlVsE8rvw3MVqrfmbF543ONBJPUt3d1TjKwaZQlgPji-ycGg_P7K-dKxpyfQsC8xMmVmiAF4QQtnUa9vMgiChiO8-6VzGm2yWWyIUVRLxSohrbSNFhqF2zeWXePAw0_nzeZh3IDIMS5ABo92Pry4N3X-X7v_7nf8MGngK4duQ_1UkkLk-3u0I3tk_glsarDN0tYhzPwAQ" },
{ "kty" : "EC",
"crv" : "P-256",
"use" : "sig",
"kid" : "yGvt",
"d" : "XnnhYQD6olmXKNQ2mBQ-ZOHEMUpYENnvGDNU3z9VVZ0",
"x" : "pvgdqM3RCshljmuCF1D2Ez1w5ei5k7-bpimWLPNeEHI",
"y" : "JSmUhbUTqiFclVLEdw6dz038F7Whw4URobjXbAReDuM" },
{ "kty" : "EC",
"crv" : "P-384",
"use" : "sig",
"kid" : "9nHY",
"d" : "3zS7ECyMqZlENI9Xk6TqptEbZtoso3LmO4Hc9zs-VytU3Sgd8yHw2uUePAkGv_Fu",
"x" : "JPKhjhE0Bj579Mgj3Cn3ERGA8fKVYoGOaV9BPKhtnEobphf8w4GSeigMesL-038W",
"y" : "UbJa1QRX7fo9LxSlh7FOH5ABT5lEtiQeQUcX9BW0bpJFlEVGqwec80tYLdOIl59M" },
{ "kty" : "EC",
"crv" : "P-521",
"use" : "sig",
"kid" : "tVzS",
"x" : "AZgkRHlIyNQJlPIwTWdHqouw41k9dS3GJO04BDEnJnd_Dd1owlCn9SMXA-JuXINn4slwbG4wcECbctXb2cvdGtmn",
"y" : "AdBC6N9lpupzfzcIY3JLIuc8y8MnzV-ItmzHQcC5lYWMTbuM9NU_FlvINeVo8g6i4YZms2xFB-B0VVdaoF9kUswC",
"d" : "AAnqLI9s0-hKAXtp0mXQHKoPBMDsnhgeh6HQP-1ScEVMl9-7WcJm2m_msXPyfT0O9Xbh4UDn9wdAi9bqt_4qEEjy" },
{ "kty" : "oct",
"use" : "enc",
"kid" : "5C93",
"k" : "E4hXEaCzx3TSPM1-hcr1VBtZOH6nGfO5MkvSUF1gb1A" },
{ "kty" : "oct",
"use" : "sig",
"kid" : "hmac",
"k" : "m5JZeVoU9lBV6y-d2jNelbjrxwosYjrSGg4STHLLm4g" },
{ "kty" : "oct",
"use" : "enc",
"kid" : "subject-encrypt",
"k" : "QA4js08rUQsZfEoEoxu6LGgJgbHdmPG08XCKYSJTNJ0" } ] }
Using a Hardware Security Module (HSM) for signing tokens
Connect2id server v6.3 introduces support for PKCS#11 compliant HSMs for signing the issued ID and self-contained (JWT) access tokens.
Note that the final JWK set used by the Connect2id server can be composed of HSM-based keys and plain file-based keys.
HSM configuration
To enable HSM support edit the configuration properties in the following file:
WEB-INF/jose.properties
pkcs11.enable
Enables / disables PKCS#11 HSM support. HSM support is normally disabled, to
enable it set the property to true
.
pkcs11.enable = false
pkcs11.configFile
The location of the Sun PKCS#11 provider configuration:
pkcs11.configFile = /WEB-INF/hsm.cfg
This configuration specifies the driver to load for the HSM device, a slot number for it (as multiple HSM devices may be attached), plus additional attributes. These are explained in the Sun PKCS#11 provider documentation. The manual of your HSM device should also provide information.
Sample hsm.cfg
:
name = NitroKeyHSM
library = /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
slotListIndex = 1
attributes(*,CKO_PRIVATE_KEY,CKK_RSA) = {
CKA_SIGN = true
}
pkcs11.password
The password (PIN) required to unlock the HSM.
pkcs11.password = 648219
Any configuration file property can be overridden via a Java system property, e.g. by setting the optional -D argument at JVM startup:
-Dpkcs11.password=123456
Generating keys on the HSM
The HSM must be provisioned with the required keys before it can be used by the Connect2id server.
-
For signing tokens with an RSA key, provision one or more RSA keys on the HSM. The RSA keys must be 1024 or 2048 bits long.
-
For signing tokens with an EC key, provision one or more EC keys with curve P-256 (for JWS algorithm ES256), P-384 (for ES384) and / or P-521 (for ES512). Note that some HSM devices have limited EC support, so make sure you check this with the manufacturer.
-
Each private key must be given a unique alias (identifier).
-
Each private key must be paired with an X.509 certificate. The certificate can be self-signed, or signed by a CA. Its not-before and not-after attributes delimit the time during which the private key will be used for signing by the Connect2id server. When the certificate of the currently selected private key expires, the Connect2id server will automatically roll over to the next available valid key. If no such key is found on the HSM, the Connect2id server will log an error, and continue signing tokens with an existing key (to prevent service downtime).
ERROR [SE2000] Couldn't find signing PKCS#11 key with a X.509 certificate that is valid at this time instant, using first available key. Consider adding new key(s) to the PKCS#11 store!
-
The certificate validity windows for each key type should overlap by a little, so the Connect2id server can smoothly roll over from an expiring key to the next, and no
SE2000
errors get logged. -
The public RSA and EC keys from the HSM will be published in JWK format by the Connect2id server. Their X.509 certificates will not be included in the JWK
x5c
parameter. -
Make sure the HSM can maintain an RSA or EC signing rate that matches the usage requirements of the IdP service.
Debugging HSM issues
The Connect2id server logs the loading of the HSM device and which keys in it are selected for signing. Keys that don’t match the server requirements, in terms of key type, use or size, will be omitted.
INFO MAIN - [SE0001] JOSE configuration: PKCS#11 enabled: true
INFO MAIN - [SE0002] JOSE configuration: PKCS#11 configuration file: /WEB-INF/hsm.cfg
INFO MAIN - [SE0003] JOSE configuration: PKCS#11 password: true
INFO MAIN - [SE1001] Loaded JWK set file with 7 keys: /WEB-INF/jwkSet.json
INFO MAIN - [SE1006] Loaded PKCS#11 provider SunPKCS11-NitroKeyHSM
INFO MAIN - [SE1007] Loaded PKCS#11 key store with 2 entries
INFO MAIN - [SE1009] Extracted JWK set with 2 keys from PKCS#11 key store SunPKCS11-NitroKeyHSM
DEBUG MAIN - [SE1010] Assuming signature key use for RSA PKCS#11 JWK with ID 1
DEBUG MAIN - [SE1010] Assuming signature key use for RSA PKCS#11 JWK with ID 2
INFO MAIN - [SE1008] Loaded JWK set:
INFO MAIN - [SE3000] [1] JWK type=RSA id=1 private=true use=sig size=2048 pkcs#11=true nbf=2017-01-30T11:47:41Z exp=2017-02-28T11:47:41Z
INFO MAIN - [SE3000] [2] JWK type=RSA id=2 private=true use=sig size=2048 pkcs#11=true nbf=2017-01-30T11:51:23Z exp=2017-02-28T11:51:23Z
INFO MAIN - [SE3000] [3] JWK type=RSA id=CXup private=true use=sig size=2048 pkcs#11=false
INFO MAIN - [SE3000] [4] JWK type=EC id=yGvt private=true use=sig size=256 pkcs#11=false
INFO MAIN - [SE3000] [5] JWK type=EC id=9nHY private=true use=sig size=384 pkcs#11=false
INFO MAIN - [SE3000] [6] JWK type=EC id=tVzS private=true use=sig size=521 pkcs#11=false
INFO MAIN - [SE3000] [7] JWK type=oct id=5C93 use=enc size=128 pkcs#11=false
INFO MAIN - [SE3000] [8] JWK type=oct id=hmac use=sig size=256 pkcs#11=false
INFO MAIN - [SE3000] [9] JWK type=oct id=subject-encrypt use=enc size=256 pkcs#11=false
Assistance
If you need help with setting up your JWK set, get in touch with Connect2id support.