Deterministic encryption with AES SIV and where it's indispensable
When it comes to symmetric block ciphers, there are several modes of operation. These differ in how the ciphertext that exceed the block size of the cipher is formed. With AES, for example, the block size is 128 bits. Without going into too much detail, it's important to know that you can't simply concatenate the ciphertexts produced by a block cipher without leaking plaintext data.
Most modes of operation rely on a so-called initialization vector or IV, which is a fixed-size byte input that (as opposed to the encryption key) doesn't need to be secret but is required to decrypt a ciphertext. There are different ways to generate such an IV. The most common are simply random IVs. However, randomness means that encrypting the same cleartext twice will result in two different ciphertexts. For many applications this is a desirable property, as an attacker wouldn't be able to determine whether two ciphertexts correspond to the same cleartext. However, for certain scenarios we strictly want a given cleartext to always encrypt to the same ciphertext. In this case we speak of deterministic encryption.
One mode of operation that allows such deterministic encryption is the SIV mode, specified in RFC 5297. SIV stands for synthetic initialization vector and works by deterministically deriving an IV from the input during encryption. The IV is then prepended to the ciphertext. During decryption it can then be used to validate the cleartext and therefore notice whether the ciphertext has been tampered with. This property makes it a so-called authenticated encryption algorithm.
One field of application of this algorithm is deterministic filename encryption, as used in the Cryptomator cloud encryption utility. Since Cryptomator is an open source project which has its encryption code published as separate libraries, other software can easily integrate it. Connect2id employed the AES SIV implementation in the OpenID Connect SDK to generate deterministic encrypted (pairwise) user identifiers, for increasing privacy in single sign-on.
Example user ID encryption with AES SIV:
user ID: alice
encrypted: Osy9fFgs2PRJAk9JE0-4d3kIvxMFOLpoyX_yVZZmkG4r
The open source nature of the Cryptomator AES SIV library allows for security audits to be performed. One was undertaken by Tim McLean on behalf of Connect2id and its finds were published on the project page. All found issues have been successfully resolved in close collaboration with the Cryptomator team.
The Cryptomator AES SIV library for Java can be found on GitHub:
Connect2id server 7.18.1 maintenance release
This is a maintenance release of the Connect2id server which fixes three issues in the code and the configuration. Two of those issues were introduced in v7.18, so you are encouraged to ignore it and update to this release instead.
You can find more information about the fixed issues in the released notes below.
Download
To download a ZIP package of Connect2id server 7.18.1:
https://connect2id.com/assets/products/server/download/7.18.1/Connect2id-server.zip
SHA-256: a871d49f2d27ec4bd913c492948c284553f2b66eade5215cf4a2bd762c7ff91c
As WAR package only:
https://connect2id.com/assets/products/server/download/7.18.1/c2id.war
SHA-256: fa844422babde8bf3dd4880eb785bc25550eefef8a7a541feeca5530e7900d31
Questions?
Contact Connect2id support.
Release notes
7.18.1 (2019-11-30)
Resolved issues
Fixes a bug introduced in 7.18 on fixing issue oauth-oidc-sdk/277 which caused client GET and PUT registration responses to return HTTP status code 201 instead of 200 on success (issues oauth-oidc-sdk/282, server/501).
A relying party initiated logout request with a post-logout redirection URI must produce an error on a missing ID token hint instead of not honouring the requested redirection (issue server/500).
Restores the uppercase name of JGROUPSPING table in
default-jgroups-jdbc_ping-mysql.xml
anddefault-jgroups-jdbc_ping-postgres95.xml
, changed to lowercase in v7.18. Also sets the name to uppercase for the newdefault-jgroups-jdbc_ping-sqlserver.xml
introduced in v7.18 (issue server/502).Updates the default JDBC URL for MySQL databases in
/WEB-INF/infinispan-*-mysql.xml
anddefault-jgroups-jdbc_ping-mysql.xml
with the more correctmysql
database identifier instead ofmariadb
. This is done to prevent potential issues if client protocol compatibility between MySQL and MariaDB breaks at some point in future. JDBC URLs for MariaDB should use themariadb
identifier. For more information see https://mariadb.com/kb/en/library/about-mariadb-connector-j/#connection-strings (issue server/499).
Dependency changes
- Upgrades to com.nimbusds:oauth2-oidc-sdk:6.18.2
Connect2id server 7.18 has Microsoft SQL Server support, new stateless clustering mode
November's 7.18 release of the OpenID Connect / OAuth 2.0 server focuses on updating backend database support and clustering.
Microsoft SQL server is now among the supported relational databases, alongside MySQL, PostgreSQL and H2. You can use SQL server v2016, v2017 and the newest v2019. The configuration guide for SQL Server explains the JDBC, username and password settings.
Connect2id server 7.18 also introduces a new stateless clustering mode where the server's entire data -- long-lived objects (such as client registrations) as well as short-lived objects (sessions) -- is persisted to the main database (MySQL, PostreSQL or SQL Server). This mode is intended as a simpler to deploy and manage alternative to the existing stateless cluster mode which requires a separate Redis database to cache data and store short-lived objects.
If you need assistance selecting an optimal clustering mode for your identity provider and token service don't hesitate to contact our technical support.
You can find more information about the new release in the notes below.
Download
To download a ZIP package of Connect2id server 7.18:
https://connect2id.com/assets/products/server/download/7.18/Connect2id-server.zip
SHA-256: b97c51c89be16ef295aa853f76cf4cf8765aa629044a8188c57c1c45170c6b49
As WAR package only:
https://connect2id.com/assets/products/server/download/7.18/c2id.war
SHA-256: 10e19f691fa148eb94ebe9b06667d30196632be81753bfeb19aae35e7409ec69
Questions?
Contact Connect2id support.
Release notes
7.18 (2019-11-25)
General
Adds support for persisting Connect2id server data to a Microsoft SQL Server 2016+ database. Available in the standard and multi-tenant Connect2id server editions.
Adds new stateless cluster mode where the entire Connect2id server data is persisted to an SQL database (MySQL, PostreSQL or SQL Server). Intended as a lightweight, simpler to deploy and manage alternative to the existing stateless cluster mode where the short-lived data (cached client JWK sets, sessions, etc) is stored in a Redis database. Available in the standard and multi-tenant Connect2id server editions.
Configuration
/WEB-INF/infinispan-*-sqlserver.xml
New Infinispan configurations for persisting Connect2id server data to a Microsoft SQL Server database. Supported database versions are 2016 and later. The database can be created with the traditional SQL Server UCS-2 (UTF-16) encoding or with the UTF-8 encoding, which is supported since version 2019.
Java system properties to configure the database connection:
dataSource.url -- Sets the JDBC URL to specify the database host, port, name and other options. The default value is
jdbc:sqlserver://localhost:1433;databaseName=c2id;applicationName=c2id;
dataSource.user -- Sets the username. The default value is
c2id
.dataSource.password -- Sets the user password.
Support for SQL Server is available in the standard and multi-tenant Connect2id server editions.
/WEB-INF/infinispan-stateless-{mysql|postgres95|sqlserver}.xml
Adds new stateless cluster mode where long-lived as well as cached and short-lived Connect2id server data is persisted to an SQL database. Intended as a lightweight, simpler to deploy and manage alternative to the existing stateless cluster mode where the short-lived data is stored in a Redis database. Available in the standard and multi-tenant Connect2id server editions.
Resolved issues
The client registration endpoint must return HTTP status code 201 instead of 200 on a successful POST (issue oauth-oidc-sdk/277).
Logs any unchecked exceptions when parsing token requests at the
/token
endpoint (OP6208) (issue server/484).Logs any unchecked exceptions at the
/jwks.json
endpoint (OP3000) (issue server/486).Adds tenant ID legal character check (allow alphanumeric, dash, underscore) to tenants web API POST operation (issue server/496).
Documents HikariCP configuration properties in the Infinispan configuration files with an SQL database (issue server/495).
Dependency changes
Upgrades to com.nimbusds:oauth2-oidc-sdk:6.18.1
Updates to com.nimbusds:tenant-manager:4.3
Updates to com.nimbusds:tenant-registry:5.1
Updates to com.nimbusds:oauth2-authz-store:13.9
Updates to com.nimbusds:oidc-session-store:13.3
Upgrades to com.nimbusds:infinispan-cachestore-sql:4.0.6
Upgrades to org.jooq.pro:jooq:3.12.2
Adds new dependency com.microsoft.sqlserver:mssql-jdbc:7.4.1.jre11
Pushed authorisation requests (PAR) in the OAuth 2.0 SDK
The brand new Pushed Authorisation Requests (PAR) draft is now supported in v6.17 of the OAuth 2.0 / OpenID Connect SDK. PAR is a simple mean to up the security of authorisation requests, by making them integrity protected and confidential, and if the OAuth client has credentials - also authenticated.
The security of regular authZ requests
With regular OAuth 2.0 the client passes the request parameters encoded into the redirection URL that sends the user's browser (agent) for login and consent to the authorisation server.
GET /authz?response_type=code
&client_id=123
&state=ri4saex8
&scope=upload_doc
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: c2id.com
Because the URL is submitted via the browser, the query parameters are exposed to the user and can potentially be tampered with. Applications therefore cannot rely on the authorisation request being authenticated, integrity protected or confidential. Do we have a solution for applications which require these security properties?
Securing authZ requests with JWT
The OAuth 2.0 extension for JWT-secured authorisation requests (JAR) allows the parameters to be authenticated and integrity protected by means of JWS. If JWE is applied to the digitally signed or HMAC-protected JWT, the request parameters become confidential. JAR has been a feature of OpenID Connect and is readily supported by the Connect2id server.
In order to secure authorisation requests with JAR the client needs to perform JOSE cryptography at the application layer. This is relatively easy with libraries such as Nimbus JOSE+JWT, but still, few developers take advantage of the extra security of JAR, unless the application is required to conform to a hardened OAuth 2.0 profile, such as FAPI.
PAR security works without application layer cryptography
The new PAR spec allows OAuth clients to submit their authorisation requests in a way that guarantees their integrity and confidentiality, without the need to deal with cryptography at the application layer. It also works for public clients without credentials.
PAR's solution is simple - a new endpoint at the authorisation server where clients can POST their authorisation request directly. If the client is confidential it will be required to authenticate as it does at the token endpoint.
Example HTTP POST of an authorisation request where the client authenticates
with its client_secret
:
POST /par HTTP/1.1
Host: c2id.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3
response_type=code
&client_id=123
&state=ri4saex8
&scope=upload_doc
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
For a successful POST the server will return a handle, in the form of a URI, typically a URN, which is valid for some limited time and may be single use.
HTTP/1.1 201 Created
Cache-Control: no-cache, no-store
Content-Type: application/json
{
"request_uri": "urn:ietf:params:oauth:request_uri:tioteej8",
"expires_in": 60
}
The OAuth client then makes the actual authorisation request, passing the URI
handle in the request_uri
parameter. No other query parameters are needed!
GET /authz?request_uri=urn%3Aietf%3Aparams%3Aoauth%3Arequest_uri%3Atioteej8 HTTP/1.1
Host: c2id.com
The rest of the flow continues as usual for the requested response type.
No URL limits on the authZ request
PAR also removes potential size limitations on the authorisation request, to accommodate browsers which doesn't support long URLs.
PAR meshes nicely with JAR
The PAR endpoint accepts JARs submitted via the request
parameter. An
application which requires non-repudiation of the authorisation request can
submit a signed JWT containing the parameters. On success the server will
return the URI handle for the request_uri
on the next step.
POST /par HTTP/1.1
Host: c2id.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3
request=eyJhbGciOiJSUzI1NiIsImtpZCI6ImsyYmRjIn0.ewogICAgImlzcyI6IC
JzNkJoZFJrcXQzIiwKICAgICJhdWQiOiAiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5j
b20iLAogICAgInJlc3BvbnNlX3R5cGUiOiAiY29kZSBpZF90b2tlbiIsCiAgICAiY2
xpZW50X2lkIjogInM2QmhkUmtxdDMiLAogICAgInJlZGlyZWN0X3VyaSI6ICJodHRw
czovL2NsaWVudC5leGFtcGxlLm9yZy9jYiIsCiAgICAic2NvcGUiOiAib3BlbmlkIi
wKICAgICJzdGF0ZSI6ICJhZjBpZmpzbGRraiIsCiAgICAibm9uY2UiOiAibi0wUzZf
V3pBMk1qIiwKICAgICJtYXhfYWdlIjogODY0MDAKfQ.Nsxa_18VUElVaPjqW_ToI1y
rEJ67BgKb5xsuZRVqzGkfKrOIX7BCx0biSxYGmjK9KJPctH1OC0iQJwXu5YVY-vnW0
_PLJb1C2HG-ztVzcnKZC2gE4i0vgQcpkUOCpW3SEYXnyWnKzuKzqSb1wAZALo5f89B
_p6QA6j6JwBSRvdVsDPdulW8lKxGTbH82czCaQ50rLAg3EYLYaCb4ik4I1zGXE4fvi
m9FIMs8OCMmzwIB5S-ujFfzwFjoyuPEV4hJnoVUmXR_W9typPf846lGwA8h9G9oNTI
uX8Ft2jfpnZdFmLg3_wr3Wa5q3a-lfbgF3S9H_8nN3j1i7tLR_5Nz-g
Making a PAR request with the OAuth 2.0 SDK
The OAuth 2.0 / OpenID Connect SDK was updated with new classes to support PAR:
Example usage:
// The PAR endpoint, obtained from AS metadata
URI endpoint = URI.create("https://c2id.com/par");
// Construct an OAuth 2.0 authorisation request as usual
AuthorizationRequest authzRequest = new AuthorizationRequest.Builder(
new ResponseType("code"), clientID)
.redirectURI(URI.create("https://example.com/cb"))
.scope(new Scope("upload_doc"))
.state(new State())
.build();
// The client authenticates the same way as it's supposed at the
// token endpoint
ClientID clientID = new ClientID("123");
Secret clientSecret = new Secret("chele3faiYieNg4taoy8ingai3eili3b");
ClientAuthentication clientAuth = new ClientSecretBasic(clientID, clientSecret);
// Create the PAR request and POST it
HTTPRequest httpRequest = new PushedAuthorizationRequest(
endpoint, clientAuth, authzRequest)
.toHTTPRequest();
HTTPResponse httpResponse = httpRequest.send();
// Process the PAR response
PushedAuthorizationResponse response = PushedAuthorizationResponse.parse(httpResponse);
if (! response.indicatesSuccess()) {
System.err.println("PAR request failed: " + response.getErrorObject().getHTTPStatusCode());
System.err.println("Optional error code: " + response.getErrorObject().getCode());
return;
}
PushedAuthorizationSuccessResponse successResponse = response.toSuccessResponse();
System.out.println("Request URI: " + successResponse.getRequestURI());
System.out.println("Request URI expires in: " + successResponse.getLifetime() + " seconds");
// Construct the authZ request for the browser, with request_uri as
// the sole parameter
URI redirectURI = new AuthorizationRequest.Builder(requestURI)
.endpointURI(URI.create("https://c2id.com/authz"))
.build()
.toURI()
OAuth 2.0 SDK release notes
version 6.17 (2019-10-25)
- Adds support for OAuth 2.0 Pushed Authorization Requests (draft-lodderstedt-oauth-par-00), see PushedAuthorizationRequest, PushedAuthorizationResponse, PushedAuthorizationSuccessResponse, PushedAuthorizationSuccessResponse and AuthorizationServerEndpointMetadata classes.
- Deprecates RequestObjectPOST classes.
- Updates ErrorObject to support URL-encoded parameters.
- Adds new AuthenticationRequestDetector utility.
Updates token validation in Nimbus JOSE+JWT 8
Version 8 of the Nimbus JOSE+JWT library updates the token validation framework.
When creating a JOSEProcessor or JWTProcessor they can now be configured to accept only tokens with a given typ (type) header parameter. Use of this header parameter is recommended to prevent accidental or malicious passing of a JWS or JWE of another type which happens to rely on identical claims.
For this reason the new JWT Profile for OAuth 2.0 Access Tokens sets this header to "at+jwt".
For example:
{
"alg" : "RS256",
"typ" : "at+jwt",
"kid" : "AhXoh4fe"
}
The DefaultJWTClaimsVerifier was also updated, to enable configuration of exact audience and other claim matching, lists of JWT claim names that must be present and claims which presence is prohibited.
Here are some sample validation rules for an access token:
- Expected audience (
aud
):https://demo.c2id.com/userinfo
- Exact match claims:
iss = https://demo.c2id.com
- Names of claims that must be present:
sub
,cid
,exp
,scp
- Names of prohibited claims:
nonce
Example token claims:
{
"iss" : "https://demo.c2id.com",
"aud" : "https://demo.c2id.com/userinfo"
"sub" : "alice",
"cid" : "000123",
"exp" : 1460345736,
"scp" : ["openid","email","profile"],
"clm" : ["!5v8H"],
"uip" : {"groups":["admin","audit"]}
}
Use of the new features is explained in the updated article for validating JWT-encoded access tokens.
Release notes
version 8.0 (2019-10-15)
- Adds new JOSEObjectTypeVerifier interface for verifying the "typ" (type) header parameter of processed JOSE objects. A configurable DefaultJOSEObjectTypeVerifier is provided.
- Updates the ConfigurableJOSEProcessor interface with methods for setting a JWS and a JWE JOSEObjectTypeVerifier (API breaking change).
- Updates the DefaultJOSEProcessor and DefaultJWTProcessor classes to support JWS and JWE "typ" (type) header parameter verification via the new JOSEObjectTypeVerifier interface.
- Makes JOSEObject.hashCode() and JOSEObject.equals() case insensitive.
- Removes exception caching in DefaultJOSEProcessor and DefaultJWTProcessor (iss #229).
- JWK.parseFromPEMEncodedObjects should throw a JOSEException on a missing PEM-encoded public key required to construct the JWK (iss #331).
version 8.1 (2019-10-15)
- Extends DefaultJWTClaimsVerifier with configurable checks for "iat", "exp", "nbf", "iss" and "aud".
version 8.2 (2019-10-17)
- Redesigns DefaultJWTClaimsVerifier to support complex audience checks, arbitrary exact claim matching, presence and prohibited checks.