Class JCECipherFactory
java.lang.Object
org.apache.derby.impl.services.jce.JCECipherFactory
- All Implemented Interfaces:
CipherFactory
This CipherFactory creates new JCECipherProvider.
- See Also:
-
Nested Class Summary
Nested Classes -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final String
private static final int
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 processprivate static final int
private String
private String
private String
private String
private static final String
private static final String
private static final String
private int
private int
private byte[]
private SecretKey
private static final String
private MessageDigest
private Properties
private static final String
private static final int
Amount of data that is used for verification of external encryption key This does not include the MD5 checksum bytesFields inherited from interface org.apache.derby.iapi.services.crypto.CipherFactory
DECRYPT, ENCRYPT, MIN_BOOTPASS_LENGTH
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionchangeBootPassword
(String changeString, Properties properties, CipherProvider verify) createNewCipher
(int mode) Returns a CipherProvider which is the encryption or decryption engine.private CipherProvider
createNewCipher
(int mode, SecretKey secretKey, byte[] iv) private byte[]
decryptKey
(String encryptedKey, int encodedKeyCharLength, byte[] bootPassword) Decrypt the secretKey with the user key .private int
digest
(byte[] input) 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 SecretKey
generateKey
(byte[] secretKey) Generate a Key object using the input secretKey that can be used by JCECipherProvider to encrypt or decrypt.private byte[]
private byte[]
getDatabaseSecretKey
(Properties properties, byte[] bootPassword, 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 checksumprivate byte[]
getMuckFromBootPassword
(byte[] bootPassword, int encodedKeyByteLength) private byte[]
handleBootPassword
(boolean create, Properties properties, boolean newPasswd) private void
init
(boolean create, 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 alignprivate StorageRandomAccessFile
privAccessFile
(StorageFactory storageFactory, String fileName, String filePerms) access a file for either read/writeprivate InputStream
privAccessGetInputStream
(StorageFactory storageFactory, String fileName) access a InputStream for a given file for reading.(package private) static String
providerErrorName
(String cps) void
saveProperties
(Properties properties) private String
saveSecretKey
(byte[] secretKey, byte[] bootPassword) void
verifyKey
(boolean create, StorageFactory sf, Properties properties) The database can be encrypted with an encryption key given in connection url.private void
vetCipherProviders
(CipherProvider decrypter, CipherProvider encrypter, String sqlState) Verify that a decrypter matches an encrypter.
-
Field Details
-
MESSAGE_DIGEST
- See Also:
-
DEFAULT_ALGORITHM
- See Also:
-
DES
- See Also:
-
DESede
- See Also:
-
TripleDES
- See Also:
-
AES
- See Also:
-
BLOCK_LENGTH
private static final int BLOCK_LENGTH- See Also:
-
AES_IV_LENGTH
private static final int AES_IV_LENGTHAES 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
-
cryptoAlgorithmShort
-
cryptoProvider
-
cryptoProviderShort
-
messageDigest
-
mainSecretKey
-
mainIV
private byte[] mainIV -
persistentProperties
-
VERIFYKEY_DATALEN
private static final int VERIFYKEY_DATALENAmount of data that is used for verification of external encryption key This does not include the MD5 checksum bytes- See Also:
-
-
Constructor Details
-
JCECipherFactory
JCECipherFactory(boolean create, Properties props, boolean newAttributes) throws StandardException - Throws:
StandardException
-
-
Method Details
-
providerErrorName
-
generateUniqueBytes
- 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 alignmentblockSizeAlign
- 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
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
- Specified by:
getSecureRandom
in interfaceCipherFactory
-
createNewCipher
Description copied from interface:CipherFactory
Returns a CipherProvider which is the encryption or decryption engine.- Specified by:
createNewCipher
in interfaceCipherFactory
- 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
- Throws:
StandardException
-
handleBootPassword
private byte[] handleBootPassword(boolean create, Properties properties, boolean newPasswd) throws StandardException - Throws:
StandardException
-
saveProperties
- Specified by:
saveProperties
in interfaceCipherFactory
-
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 keybootPassword
- boot password used to connect to the encrypted databaseerrorState
- 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
- Throws:
StandardException
-
changeBootPassword
public String changeBootPassword(String changeString, Properties properties, CipherProvider verify) throws StandardException - Specified by:
changeBootPassword
in interfaceCipherFactory
- 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 interfaceCipherFactory
- Parameters:
create
- true means database is being created, whereas false implies that the database has already been createdsf
- storageFactory is used to access any stored data that might be needed for verification process of the encryption keyproperties
- properties at time of database connection as well as those in service.properties- Throws:
StandardException
-
getMD5Checksum
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 accessfileName
- name of the file to create and open for write The file will be created directly under the database root directoryfilePerms
- 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 accessfileName
- 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 readStandardException
-