Class JCECipherFactory
- java.lang.Object
-
- org.apache.derby.impl.services.jce.JCECipherFactory
-
- All Implemented Interfaces:
CipherFactory
final class JCECipherFactory extends java.lang.Object implements CipherFactory
This CipherFactory creates new JCECipherProvider.- See Also:
CipherFactory
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private static class
JCECipherFactory.EncryptedKeyResult
-
Field Summary
Fields Modifier and Type Field Description private static java.lang.String
AES
private static 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 processprivate static int
BLOCK_LENGTH
private java.lang.String
cryptoAlgorithm
private java.lang.String
cryptoAlgorithmShort
private java.lang.String
cryptoProvider
private java.lang.String
cryptoProviderShort
private static java.lang.String
DEFAULT_ALGORITHM
private static java.lang.String
DES
private static java.lang.String
DESede
private int
encodedKeyLength
private int
keyLengthBits
private byte[]
mainIV
private javax.crypto.SecretKey
mainSecretKey
private static java.lang.String
MESSAGE_DIGEST
private java.security.MessageDigest
messageDigest
private java.util.Properties
persistentProperties
private static java.lang.String
TripleDES
private static int
VERIFYKEY_DATALEN
Amount of data that is used for verification of external encryption key This does not include the MD5 checksum bytes-
Fields inherited from interface org.apache.derby.iapi.services.crypto.CipherFactory
DECRYPT, ENCRYPT, MIN_BOOTPASS_LENGTH
-
-
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 checksumprivate 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 alignprivate StorageRandomAccessFile
privAccessFile(StorageFactory storageFactory, java.lang.String fileName, java.lang.String filePerms)
access a file for either read/writeprivate 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.
-
-
-
Field Detail
-
MESSAGE_DIGEST
private static final java.lang.String MESSAGE_DIGEST
- See Also:
- Constant Field Values
-
DEFAULT_ALGORITHM
private static final java.lang.String DEFAULT_ALGORITHM
- See Also:
- Constant Field Values
-
DES
private static final java.lang.String DES
- See Also:
- Constant Field Values
-
DESede
private static final java.lang.String DESede
- See Also:
- Constant Field Values
-
TripleDES
private static final java.lang.String TripleDES
- See Also:
- Constant Field Values
-
AES
private static final java.lang.String AES
- See Also:
- Constant Field Values
-
BLOCK_LENGTH
private static final int BLOCK_LENGTH
- 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
-
-
Constructor Detail
-
JCECipherFactory
JCECipherFactory(boolean create, java.util.Properties props, boolean newAttributes) throws StandardException
- Throws:
StandardException
-
-
Method Detail
-
providerErrorName
static java.lang.String providerErrorName(java.lang.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 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(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)
-
getSecureRandom
public java.security.SecureRandom getSecureRandom()
- Specified by:
getSecureRandom
in interfaceCipherFactory
-
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 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, javax.crypto.SecretKey secretKey, byte[] iv) throws StandardException
- Throws:
StandardException
-
init
private void init(boolean create, java.util.Properties properties, boolean newAttrs) throws StandardException
- Throws:
StandardException
-
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 interfaceCipherFactory
-
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 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
private java.lang.String saveSecretKey(byte[] secretKey, byte[] bootPassword) throws StandardException
- Throws:
StandardException
-
changeBootPassword
public java.lang.String changeBootPassword(java.lang.String changeString, java.util.Properties properties, CipherProvider verify) throws StandardException
- Specified by:
changeBootPassword
in interfaceCipherFactory
- 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 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
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 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:
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 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:
java.io.IOException
- Any exception during accessing the file for readStandardException
-
-