Class EncryptedFieldConverter

java.lang.Object
com.broadleafcommerce.auth.client.provider.jpa.converter.EncryptedFieldConverter
All Implemented Interfaces:
jakarta.persistence.AttributeConverter<String,String>

public class EncryptedFieldConverter extends Object implements jakarta.persistence.AttributeConverter<String,String>
Converter used to encrypt a string when persisted and decrypt it when read.
Author:
Nathan Moore (nathandmoore), Cade Rea (cade-rea)
  • Field Details

  • Constructor Details

    • EncryptedFieldConverter

      public EncryptedFieldConverter(SecretKey authClientPersistenceKey)
  • Method Details

    • convertToDatabaseColumn

      public String convertToDatabaseColumn(String attribute)

      Encrypts the given attribute using the AES/GCM/NoPadding transformation. The encrypted byte array is then concatenated with the IV and a "BLC cipher version" tag.

      The "BLC cipher version" is used by this class when decrypting to determine which transformation to use. It is added (unencrypted) to the beginning of the encrypted byte array. During decryption, if there is no version tag, the AES/ECB transformation is used for backward-compatability with data saved by older Authentication Service versions.

      Specified by:
      convertToDatabaseColumn in interface jakarta.persistence.AttributeConverter<String,String>
      Parameters:
      attribute - The attribute to encrypt.
      Returns:
      A base-64 encoded String of the form "cipherVersion|IV|ciphertext".
    • convertToEntityAttribute

      public String convertToEntityAttribute(String dbData)

      Decrypts an encrypted String.

      This will check the beginning of the data for a "BLC cipher version". If found, it will use the appropriate decryption transformation. If not found, it will use the legacy AES/ECB transformation for backward-compatability with data saved by older Authentication Service versions.

      Specified by:
      convertToEntityAttribute in interface jakarta.persistence.AttributeConverter<String,String>
      Parameters:
      dbData - The base-64 encoded String read from the database.
      Returns:
      The decrypted attribute String.
    • getCipherVersion

      protected String getCipherVersion(byte[] versionAndIvAndCiphertext)
      Returns the cipher version from the beginning of the byte array.
      Parameters:
      versionAndIvAndCiphertext - The base-64 decoded version of the data to decrypt.
      Returns:
      The String value of the first 3 bytes of the array.
    • gcmDecrypt

      protected String gcmDecrypt(byte[] versionAndIvAndCiphertext)
      Decrypt the byte array with the AES/GCM/NoPadding transformation.
      Parameters:
      versionAndIvAndCiphertext - The byte array to decrypt. Should be of the form "cipherVersion|IV|ciphertext".
      Returns:
      A String of the decrypted ciphertext.
    • getGcmParameterSpecForEncrypt

      protected GCMParameterSpec getGcmParameterSpecForEncrypt()
      Get a GCMParameterSpec for encrypting.
      Returns:
      A GCMParameterSpec for encrypting.
    • getGcmParameterSpecForDecrypt

      protected GCMParameterSpec getGcmParameterSpecForDecrypt(byte[] decodedEncryptedIvMessage)
      Get a GCMParameterSpec for decrypting.
      Parameters:
      decodedEncryptedIvMessage - The byte array to decrypt. Should be of the form "cipherVersion|IV|ciphertext".
      Returns:
      A GCMParameterSpec for decrypting.
    • encryptInternal

      protected byte[] encryptInternal(byte[] attributeBytes, GCMParameterSpec gcmParameterSpec)
      Encrypt the given byte array. Pass the given GCMParameterSpec to the Cipher.
      Parameters:
      attributeBytes - The attribute (as a byte array) to encrypt.
      gcmParameterSpec - Holds parameters needed by the Cipher for the GCM transformation.
      Returns:
      An encrypted byte array. The Java implementation of AES/GCM/NoPadding appends the GCM authentication tag to the end of the encrypted bytes, like "ciphertext|GCMTag".
    • decryptInternal

      protected byte[] decryptInternal(byte[] decodedEncryptedIvMessage, GCMParameterSpec gcmParameterSpec)
      Decrypt the given byte array. Pass the given GCMParameterSpec to the Cipher. In addition to decryption, the AES/GCM/NoPadding transformation also verifies authenticity.
      Parameters:
      decodedEncryptedIvMessage - The byte array to decrypt. Should be of the form "cipherVersion|IV|ciphertext". The blc cipher version tag, IV tag, and GCM authentication tag are not returned.
      gcmParameterSpec - Holds parameters needed by the Cipher for the GCM transformation.
      Returns:
      A byte array of the decrypted cipher text.
    • getCipher

      protected Cipher getCipher(int encryptMode, GCMParameterSpec gcmParameterSpec)
      Get a Cipher to perform AES/GCM/NoPadding transformations.
      Parameters:
      encryptMode - Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODE
      gcmParameterSpec - Holds parameters needed by the Cipher for the GCM transformation.
      Returns:
      A Cipher to perform AES/GCM/NoPadding transformations.
    • createIV

      protected byte[] createIV()
      Create an initialization vector to be used as a nonce during encryption.
      Returns:
      A random 12 byte array
    • prependVersionAndIv

      protected byte[] prependVersionAndIv(GCMParameterSpec gcmParameterSpec, byte[] encryptedAttribute)
      Prepend the blc cipher version and IV to the encrypted text. This data will be needed during decryption. Coupling the IV and the ciphertext is common and acceptable; we also include the blc version tag.
      Parameters:
      gcmParameterSpec - Holds parameters needed by the Cipher for the GCM transformation.
      encryptedAttribute - The encrypted attribute.
      Returns:
      A byte array of the form "cipherVersion|IV|ciphertext".
    • getBlcCipherVersionTag

      protected byte[] getBlcCipherVersionTag()
      Get a byte array of BLC_CIPHER_VERSION_1 in UTF-8.
      Returns:
      A byte array of BLC_CIPHER_VERSION_1 in UTF-8.
    • legacyDecrypt

      protected String legacyDecrypt(String dbData)
      Decrypt attributes encrypted with a pre-1.7.1 version of AuthenticationServices. AES with ECB was used until 1.7.1.
      Parameters:
      dbData - The base-64 encoded String read from the database.
      Returns:
      The decrypted attribute String.
    • getAuthClientPersistenceKey

      protected SecretKey getAuthClientPersistenceKey()
    • getAlgorithm

      protected String getAlgorithm()
    • getTransformation

      protected String getTransformation()
    • getIvLength

      protected int getIvLength()
    • getGcmTagLength

      protected int getGcmTagLength()
    • getBlcCryptVersionTagLength

      protected int getBlcCryptVersionTagLength()
    • getSecureRandom

      protected SecureRandom getSecureRandom()