Class EncryptedFieldConverter

  • All Implemented Interfaces:
    javax.persistence.AttributeConverter<String,​String>

    public class EncryptedFieldConverter
    extends Object
    implements javax.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)
    • Constructor Detail

      • EncryptedFieldConverter

        public EncryptedFieldConverter​(SecretKey authClientPersistenceKey)
    • Method Detail

      • 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 javax.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 javax.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".
      • 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()