Class JCECipherFactory

  • All Implemented Interfaces:
    CipherFactory

    final class JCECipherFactory
    extends java.lang.Object
    implements CipherFactory
    This CipherFactory creates new JCECipherProvider.
    See Also:
    CipherFactory
    • Constructor Summary

      Constructors 
      Constructor Description
      JCECipherFactory​(boolean create, java.util.Properties props, boolean newAttributes)  
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      java.lang.String changeBootPassword​(java.lang.String changeString, java.util.Properties properties, CipherProvider verify)  
      CipherProvider createNewCipher​(int mode)
      Returns a CipherProvider which is the encryption or decryption engine.
      private CipherProvider createNewCipher​(int mode, javax.crypto.SecretKey secretKey, byte[] iv)  
      private byte[] decryptKey​(java.lang.String encryptedKey, int encodedKeyCharLength, byte[] bootPassword)
      Decrypt the secretKey with the user key .
      private int digest​(byte[] input)  
      private JCECipherFactory.EncryptedKeyResult encryptKey​(byte[] secretKey, byte[] bootPassword)
      Encrypt the secretKey with the boot password.
      private byte[] generateIV​(byte[] secretKey)
      Generate an IV using the input secretKey that can be used by JCECipherProvider to encrypt or decrypt.
      private javax.crypto.SecretKey generateKey​(byte[] secretKey)
      Generate a Key object using the input secretKey that can be used by JCECipherProvider to encrypt or decrypt.
      private byte[] generateUniqueBytes()  
      private byte[] getDatabaseSecretKey​(java.util.Properties properties, byte[] bootPassword, java.lang.String errorState)
      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.
      private byte[] getMD5Checksum​(byte[] data)
      Use MD5 MessageDigest algorithm to generate checksum
      private byte[] getMuckFromBootPassword​(byte[] bootPassword, int encodedKeyByteLength)  
      java.security.SecureRandom getSecureRandom()  
      private byte[] handleBootPassword​(boolean create, java.util.Properties properties, boolean newPasswd)  
      private void init​(boolean create, java.util.Properties properties, boolean newAttrs)  
      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
      private StorageRandomAccessFile privAccessFile​(StorageFactory storageFactory, java.lang.String fileName, java.lang.String filePerms)
      access a file for either read/write
      private java.io.InputStream privAccessGetInputStream​(StorageFactory storageFactory, java.lang.String fileName)
      access a InputStream for a given file for reading.
      (package private) static java.lang.String providerErrorName​(java.lang.String cps)  
      void saveProperties​(java.util.Properties properties)  
      private java.lang.String saveSecretKey​(byte[] secretKey, byte[] bootPassword)  
      void verifyKey​(boolean create, StorageFactory sf, java.util.Properties properties)
      The database can be encrypted with an encryption key given in connection url.
      private void vetCipherProviders​(CipherProvider decrypter, CipherProvider encrypter, java.lang.String sqlState)
      Verify that a decrypter matches an encrypter.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • DEFAULT_ALGORITHM

        private static final java.lang.String DEFAULT_ALGORITHM
        See Also:
        Constant Field Values
      • 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:
        CipherProvider, Constant Field Values
      • keyLengthBits

        private int keyLengthBits
      • encodedKeyLength

        private int encodedKeyLength
      • cryptoAlgorithm

        private java.lang.String cryptoAlgorithm
      • cryptoAlgorithmShort

        private java.lang.String cryptoAlgorithmShort
      • cryptoProvider

        private java.lang.String cryptoProvider
      • cryptoProviderShort

        private java.lang.String cryptoProviderShort
      • messageDigest

        private java.security.MessageDigest messageDigest
      • mainSecretKey

        private javax.crypto.SecretKey mainSecretKey
      • mainIV

        private byte[] mainIV
      • persistentProperties

        private java.util.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:
        Constant Field Values
    • Method Detail

      • providerErrorName

        static java.lang.String providerErrorName​(java.lang.String cps)
      • 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​(java.lang.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 javax.crypto.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)
      • 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
      • handleBootPassword

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

        public void saveProperties​(java.util.Properties properties)
        Specified by:
        saveProperties in interface CipherFactory
      • getDatabaseSecretKey

        private byte[] getDatabaseSecretKey​(java.util.Properties properties,
                                            byte[] bootPassword,
                                            java.lang.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
      • vetCipherProviders

        private void vetCipherProviders​(CipherProvider decrypter,
                                        CipherProvider encrypter,
                                        java.lang.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,
                              java.util.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,
                                                       java.lang.String fileName,
                                                       java.lang.String filePerms)
                                                throws java.io.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:
        java.io.IOException - Any exception during accessing the file for read/write
      • privAccessGetInputStream

        private java.io.InputStream privAccessGetInputStream​(StorageFactory storageFactory,
                                                             java.lang.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:
        java.io.IOException - Any exception during accessing the file for read
        StandardException