Class JCECipherFactory

java.lang.Object
org.apache.derby.impl.services.jce.JCECipherFactory
All Implemented Interfaces:
CipherFactory

final class JCECipherFactory extends Object implements CipherFactory
This CipherFactory creates new JCECipherProvider.
See Also:
  • Field Details

    • MESSAGE_DIGEST

      private static final String MESSAGE_DIGEST
      See Also:
    • DEFAULT_ALGORITHM

      private static final String DEFAULT_ALGORITHM
      See Also:
    • DES

      private static final String DES
      See Also:
    • DESede

      private static final String DESede
      See Also:
    • TripleDES

      private static final String TripleDES
      See Also:
    • AES

      private static final String AES
      See Also:
    • BLOCK_LENGTH

      private static final int BLOCK_LENGTH
      See Also:
    • AES_IV_LENGTH

      private static final int AES_IV_LENGTH
      AES encryption takes in an default Initialization vector length (IV) length of 16 bytes This is needed to generate an IV to use for encryption and decryption process
      See Also:
    • keyLengthBits

      private int keyLengthBits
    • encodedKeyLength

      private int encodedKeyLength
    • cryptoAlgorithm

      private String cryptoAlgorithm
    • cryptoAlgorithmShort

      private String cryptoAlgorithmShort
    • cryptoProvider

      private String cryptoProvider
    • cryptoProviderShort

      private String cryptoProviderShort
    • messageDigest

      private MessageDigest messageDigest
    • mainSecretKey

      private SecretKey mainSecretKey
    • mainIV

      private byte[] mainIV
    • persistentProperties

      private Properties persistentProperties
    • VERIFYKEY_DATALEN

      private static final int VERIFYKEY_DATALEN
      Amount of data that is used for verification of external encryption key This does not include the MD5 checksum bytes
      See Also:
  • Constructor Details

  • Method Details

    • providerErrorName

      static String providerErrorName(String cps)
    • generateUniqueBytes

      private byte[] generateUniqueBytes() throws StandardException
      Throws:
      StandardException
    • encryptKey

      private JCECipherFactory.EncryptedKeyResult encryptKey(byte[] secretKey, byte[] bootPassword) throws StandardException
      Encrypt the secretKey with the boot password. This includes the following steps, getting muck from the boot password and then using this to generate a key, generating an appropriate IV using the muck using the key and IV thus generated to create the appropriate cipher provider and encrypting the secretKey
      Returns:
      hexadecimal string of the encrypted secretKey
      Throws:
      StandardException - Standard Derby error policy
    • padKey

      private byte[] padKey(byte[] secretKey, int blockSizeAlign)
      For block ciphers, and algorithms using the NoPadding scheme, the data that has to be encrypted needs to be a multiple of the expected block size for the cipher Pad the key with appropriate padding to make it blockSize align
      Parameters:
      secretKey - the data that needs blocksize alignment
      blockSizeAlign - secretKey needs to be blocksize aligned
      Returns:
      a byte array with the contents of secretKey along with padded bytes in the end to make it blockSize aligned
    • decryptKey

      private byte[] decryptKey(String encryptedKey, int encodedKeyCharLength, byte[] bootPassword) throws StandardException
      Decrypt the secretKey with the user key . This includes the following steps, retrieve the encryptedKey, generate the muck from the boot password and generate an appropriate IV using the muck,and using the key and IV decrypt the encryptedKey
      Returns:
      decrypted key
      Throws:
      StandardException - Standard Derby error policy
    • getMuckFromBootPassword

      private byte[] getMuckFromBootPassword(byte[] bootPassword, int encodedKeyByteLength)
    • generateKey

      private SecretKey generateKey(byte[] secretKey) throws StandardException
      Generate a Key object using the input secretKey that can be used by JCECipherProvider to encrypt or decrypt.
      Throws:
      StandardException - Standard Derby Error Policy
    • generateIV

      private byte[] generateIV(byte[] secretKey)
      Generate an IV using the input secretKey that can be used by JCECipherProvider to encrypt or decrypt.
    • digest

      private int digest(byte[] input)
    • getSecureRandom

      public SecureRandom getSecureRandom()
      Specified by:
      getSecureRandom in interface CipherFactory
    • createNewCipher

      public CipherProvider createNewCipher(int mode) throws StandardException
      Description copied from interface: CipherFactory
      Returns a CipherProvider which is the encryption or decryption engine.
      Specified by:
      createNewCipher in interface CipherFactory
      Parameters:
      mode - is either ENCRYPT or DECRYPT. The CipherProvider can only do encryption or decryption but not both.
      Throws:
      StandardException - Standard Derby Error Policy
    • createNewCipher

      private CipherProvider createNewCipher(int mode, SecretKey secretKey, byte[] iv) throws StandardException
      Throws:
      StandardException
    • init

      private void init(boolean create, Properties properties, boolean newAttrs) throws StandardException
      Throws:
      StandardException
    • handleBootPassword

      private byte[] handleBootPassword(boolean create, Properties properties, boolean newPasswd) throws StandardException
      Throws:
      StandardException
    • saveProperties

      public void saveProperties(Properties properties)
      Specified by:
      saveProperties in interface CipherFactory
    • getDatabaseSecretKey

      private byte[] getDatabaseSecretKey(Properties properties, byte[] bootPassword, String errorState) throws StandardException
      get the secretkey used for encryption and decryption when boot password mechanism is used for encryption Steps include retrieve the stored key, decrypt the stored key and verify if the correct boot password was passed There is a possibility that the decrypted key includes the original key and padded bytes in order to have been block size aligned during encryption phase. Hence extract the original key
      Parameters:
      properties - properties to retrieve the encrypted key
      bootPassword - boot password used to connect to the encrypted database
      errorState - errorstate to account for any errors during retrieval /creation of the secretKey
      Returns:
      the original unencrypted key bytes to use for encryption and decrytion
      Throws:
      StandardException
    • saveSecretKey

      private String saveSecretKey(byte[] secretKey, byte[] bootPassword) throws StandardException
      Throws:
      StandardException
    • changeBootPassword

      public String changeBootPassword(String changeString, Properties properties, CipherProvider verify) throws StandardException
      Specified by:
      changeBootPassword in interface CipherFactory
      Throws:
      StandardException
    • vetCipherProviders

      private void vetCipherProviders(CipherProvider decrypter, CipherProvider encrypter, String sqlState) throws StandardException

      Verify that a decrypter matches an encrypter. Raises an exception if they don't. The verification is performed by encrypting a block of text and checking that it decrypts to the same block.

      Throws:
      StandardException
    • verifyKey

      public void verifyKey(boolean create, StorageFactory sf, Properties properties) throws StandardException
      The database can be encrypted with an encryption key given in connection url. For security reasons, this key is not made persistent in the database. But it is necessary to verify the encryption key when booting the database if it is similar to the one used when creating the database This needs to happen before we access the data/logs to avoid the risk of corrupting the database because of a wrong encryption key. This method performs the steps necessary to verify the encryption key if an external encryption key is given. At database creation, 4k of random data is generated using SecureRandom and MD5 is used to compute the checksum for the random data thus generated. This 4k page of random data is then encrypted using the encryption key. The checksum of unencrypted data and encrypted data is made persistent in the database in file by name given by Attribute.CRYPTO_EXTERNAL_KEY_VERIFYFILE (verifyKey.dat). This file exists directly under the database root directory. When trying to boot an existing encrypted database, the given encryption key is used to decrypt the data in the verifyKey.dat and the checksum is calculated and compared against the original stored checksum. If these checksums dont match an exception is thrown. Please note, this process of verifying the key does not provide any added security but only is intended to allow to fail gracefully if a wrong encryption key is used StandardException is thrown if there are any problems during the process of verification of the encryption key or if there is any mismatch of the encryption key.
      Specified by:
      verifyKey in interface CipherFactory
      Parameters:
      create - true means database is being created, whereas false implies that the database has already been created
      sf - storageFactory is used to access any stored data that might be needed for verification process of the encryption key
      properties - properties at time of database connection as well as those in service.properties
      Throws:
      StandardException
    • getMD5Checksum

      private byte[] getMD5Checksum(byte[] data) throws StandardException
      Use MD5 MessageDigest algorithm to generate checksum
      Parameters:
      data - data to be used to compute the hash value
      Returns:
      returns the hash value computed using the data
      Throws:
      StandardException
    • privAccessFile

      private StorageRandomAccessFile privAccessFile(StorageFactory storageFactory, String fileName, String filePerms) throws IOException
      access a file for either read/write
      Parameters:
      storageFactory - factory used for io access
      fileName - name of the file to create and open for write The file will be created directly under the database root directory
      filePerms - file permissions, if "rw" open file with read and write permissions if "r" , open file with read permissions
      Returns:
      StorageRandomAccessFile returns file with fileName for writing
      Throws:
      IOException - Any exception during accessing the file for read/write
    • privAccessGetInputStream

      private InputStream privAccessGetInputStream(StorageFactory storageFactory, String fileName) throws StandardException
      access a InputStream for a given file for reading.
      Parameters:
      storageFactory - factory used for io access
      fileName - name of the file to open as a stream for reading
      Returns:
      InputStream returns the stream for the file with fileName for reading
      Throws:
      IOException - Any exception during accessing the file for read
      StandardException