Password end-to-end encryption configuration with AWS KMS in the Loginapp REST API

This article explains how to configure password end-to-end encryption (E2EE) in the Loginapp REST API. It uses the Username Password Authentication Step as an example.

For consistent E2EE, all password-related steps in all flows have to be configured with E2EE!

About the configuration examples

In the following example configurations, a Username Password Authentication Step (typically the first password-related authentication step) is configured with end-to-end password encryption.

  • Procedure summary:
  • In the Username Password Authentication Step, a Default End-To-End Encryption Password Repository is configured instead of the originally configured password repository plugin. It decrypts the password and passes the plain password to the originally used password repository.
  • Inside the Default End-To-End Encryption Password Repository the configuration is as follows:
    • Set the decryption type and with it configure the cryptographic keys.
    • Configure the originally used password repository.

Prerequisites

  • An IAM Authentication Flow with a Username Password Authentication Step (but without E2EE) is already configured for the target application.
  • For configuration with AWS KMS the service must already be configured in AWS and access credentials must be available. See AWS KMS support for password encryption.

Configuring the password step

To enable password end-to-end encryption in a Username Password Authentication Step, proceed as follows:

  1. Go to:
    Loginapp >> Applications and Authentication >> affected application >> Authentication Flow
  2. In property Steps edit the Username Password Authentication Step plugin.
  3. In property Password Repository :
    1. Note down the type and identifier of the password repository (Default Password Repository, External Database Password Repository, or alike) configuration for later reuse in step 4 of these instructions.
    2. To replace the current password repository, create and edit the Default End-To-End Encryption Password Repository plugin.
  4. At this point, we start configuring a new E2EE password repository plugin that can be reused for other password-related steps.
  5. In property Internal Password Repository, add the password repository from step 3a to restore the original password repository settings.
  6. In property Password Decryption, create and edit an AWS KMS Password Decryption plugin to set the type of password decryption. Remember that password encryption is done by JavaScript code in the end user's browser if using the Loginapp UI.

Configuration step 3b can be repeated on other step plugins that let the user enter a password.

Configuring the key store plugin with an AWS KMS

To integrate with AWS KMS, Airlock IAM needs to be configured with the service endpoint of AWS KMS and the key identifiers to be used for E2EE.

  1. In property AWS KMS Settings, create and edit an AWS Key Management Service.
  2. In property Service Access create an AWS Default Service Access plugin.
  3. In property Authentication Method create and configure an AWS Default Authentication plugin.
  4. In property Symmetric Key ARN configure the Amazon Ressource Name of the desired symmetric key.
  5. In property RSA Asymmetric Key ARN configure the Amazon Resource Name of the desired asymmetric key. This is only required if database encryption is enabled.
  6. In property RSA Algorithm select the desired encryption algorithm.
  7. At this point, third-party clients that support AWS KMS encryption can communicate with the Loginapp REST API. Airlock IAM calls the AWS KMS service to receive the decrypted password.

Optional: Password hash migration

When changing an existing Airlock IAM deployment to use AWS KMS, Airlock IAM does support migration from an existing password-hashing solution to AWS KMS. The usage of this feature is explained using a Username and Password Authentication step configured in the authentication flow of the Default Application:

  1. Go to:
    Loginapp >> Application and Authentication >> Default Application >> Authentication Flow >> Steps >> Username Password Authentication Step >> Password Repository >> Internal Password Repository
  2. In section Basic Settings configure and edit the property Hash Function with a Password Hash Configuration plugin.
    • Configure and edit the property Password Hash with an AWS KMS Password Hash plugin.
      • Configure the property Hash Function with the desired hash function.
      • Configure the property AWS KMS Settings by selecting the previously configured AWS Key Management Service plugin.
    • Configure and edit the property Encoder with a Base64 Password Hash Encoder plugin.
  3. In section Advanced Settings configure the property Legacy Hash Function with the previously used hash function.
  4. The Password Hash Configuration plugin is required to compensate for the lack of encoding done in the AWS KMS Password Hash plugin. The encoding is needed to store the hash value in the IAM database.

Follow up tasks

As stated in the intro part of this section, E2EE must be configured consistently for all password-related steps linked to the corresponding target application(s) to ensure that passwords are never transmitted unencrypted. This applies not only to authentication flows but also to other Airlock IAM flow types where password steps are configured.

  • For example in:
  • Authentication flows: password check, mandatory and voluntary password change.
  • Public self-services: password reset.
  • Self-registration flows: when setting an initial password.
  • Protected self-services: voluntary password change.

Requirements for custom Loginapp clients

The system encrypting the password (i.e. the client) must do this in such a way that the decrypting code in Airlock IAM can decrypt it and that the supplied data can be processed in AWS KMS.

The client will receive these additional attributes as part of REST responses if the next step supports end-to-end encryption (e.g. password check). The client must use this information when preparing the E2EE request.

The REST Documentation details which next step codes may contain this information.

"e2eEncryptionInformation": {
  "type": "KMS", // describes which E2E implementation is used - for AWS KMS, the type is always KMS
  "publicKey": "XsrV3n0bqLUah+HS6S..." // example base64 encoded public key - this key corresponds to the in IAM configured "RSA Asymmetric Key ARN" - see AWS for more information on the public key format
  "algorithm": "RSAES_OAEP_SHA_1" | "RSAES_OAEP_SHA_256", // the algorithm used depends on IAM and AWS configuration
  "nonce": "p2oE-RbbU1cpy710AeVcdImgwfIXDIg8kMtxXqq2sDw=" // random value to be used in the additional authentication data of the AES-GCM encryption
}

Expected Request Format

The expected JSON Request Body is described in the REST API documentation provided by AWS KMS. Instead of sending the plaintext password in the corresponding JSON fields, an encrypted BLOB is expected. See the following example:

POST /rest/public/authentication/password/check/

{
  "username": "bob"
  "password": "{"password":"EKuZUtS9nm/jVDxVQQ2SVeh/6Yc=","key":"uhZV5rStmYPEDGiUa6dZsYjHfPTZD9ueYNEo4zh59JhUL5biTskg7TYXz/6NU1fBgE2tVtAhRTb0OfasJfuKT97ebgt3T3AOUcV7V8G3xtZsF12pueuEsUmhqzwN9kXzDMYKX7Qbdsdx0A7klgfMuvsRwCxAV8h6S5XvHP13Sn9dcgt24a5mmXmaYATgNX1Apfj9nP/FIMUHEGrnmOvx+8R3KLjO143T+RI1jFrokANVp9iAaW2XHpX/r66cUOSHal2cfHyK80SNCWJAMkPyd9xtYMY+mvWN2vIzDXkkIbOllubpzvMqof3vXWgtsvrNaDzJFA23PkyAcX/Oe3vLAw==","iv":"7FS4pExf0SPNABE9"}"
}

IAM expects the client to encrypt the password in a defined way and provide the used encryption data in a defined format. Clients can implement the following algorithm:

  1. Generate a symmetric one-time AES-GCM 256 key and a random 12 byte IV (initialization vector) for one-time encryption
  2. Encrypt the plaintext password with the generated AES-GCM 256 key, the IV and a random nonce. Base64 encode the result and add it as password attribute to the request.
  3. Encrypt the one-time AES-GCM key with the provided RSA public key and algorithm (see e2eEncryptionInformation in REST response). Base64 encode it and add it as key attribute to the request.
  4. Base64 encode the initialization vector and add it as iv attribute to the request.

Example of the expected JSON BLOB contained in the "password" field of the password-check request:

{
  "password" // plaintext password encrypted with an AES-GCM 256 symmetric key and IV (key and IV generated on the client)
  "key" // AES-GCM 256 symmetric key encrypted with the RSA public key received from IAM in e2eEncryptionInformation
  "iv" // 12 byte initialization vector (generated on client)
}

If the REST request has multiple E2EE fields, e.g. on password change, each password needs to be encrypted individually.