Whoops. hit send too soon. Then an a superclass for all entities:
/**
* do nothing, override in subclass
*/
protected EncryptionVersionProvider getEncryptionVersionProvider()
{
throw new RuntimeException("getEncryptionVersionProvider()
must be overridden in subclass");
}
protected char[] decryptDataBlock(String encryptedData, int itemIndex)
throws EncryptionException
{
DataBlockEncryptionManager dataBlockEncryptionManager = new
DataBlockEncryptionManager(getEncryptionVersionProvider());
return dataBlockEncryptionManager.decryptDataBlock(encryptedData,
itemIndex);
}
protected String encryptDataBlock(String encryptedData, int
itemIndex, char[] newValue)
throws EncryptionException
{
DataBlockEncryptionManager dataBlockEncryptionManager = new
DataBlockEncryptionManager(getEncryptionVersionProvider());
return dataBlockEncryptionManager.encryptDataBlock(encryptedData,
itemIndex, newValue);
}
Obviously, you can do whatever you like to for
getEncryptionVersionProvider(), but we went with this to allow each
entity to have a separate encryption provider.
On Thu, Mar 13, 2014 at 8:13 AM, Mike Kienenberger <[email protected]> wrote:
> For what it's worth, I'm doing the same thing for our JPA app.
>
> I store the encryption version number (unencrypted), then an encrypted
> set of data fields.
>
> We found that trying to encrypt individual fields wasn't as helpful
> since the length and variety of individual columns tended not to be
> all that unique.
> Padding with random characters can help, but encrypting more fields
> together in a single column seemed more appropriate in our case,
> especially since you can't do any meaningful sql on the encrypted data
> anyway.
>
> Here's the api I ended up going with:
>
> class DataBlockEncryptionManager {
>
> public DataBlockEncryptionManager(EncryptionVersionProvider
> encryptionVersionProvider)
>
> /**
> * encrypt item in encrypted data block.
> *
> * @param encryptedData String containing previous encrypted
> block, null to create new block
> * @param itemIndex from 0 to last item of item to encrypt
> * @param newValue to add to block
> * @return String containing encrypted block
> * @throws EncryptionException
> */
> public String encryptDataBlock(String encryptedData, int
> itemIndex, char[] newValue);
>
> public char[] decryptDataBlock(String encryptedData, int
> itemIndex) throws EncryptionException;
>
> public interface EncryptionVersionProvider
> {
> /** Default version to use for new encryptions */
> public String getDefaultVersion();
>
> // with a few methods like these depending on our encryption
> public String _xyzEncryptionProperty_ForVersion(String version);
>
> }
>
> }
>
> then, assuming your column is named ENCRYPTED_DATA, your individual
> attributes look like this:
>
> public char[] getName() throws EncryptionException {
> return decryptDataBlock(getEncryptedData(), ITEM_INDEX__NAME);
> }
> public void setName(char[] holderFirstName) throws EncryptionException {
> String newData = encryptDataBlock(getEncryptedData(),
> ITEM_INDEX__NAME, name);
> setEncryptedData(newData);
> }
>
>
>
>
> On Thu, Mar 13, 2014 at 4:18 AM, Andrus Adamchik <[email protected]>
> wrote:
>>
>>
>> On Mar 13, 2014, at 11:06 AM, Aristedes Maniatis <[email protected]> wrote:
>>
>>> On 13/03/2014 6:31pm, Andrus Adamchik wrote:
>>>>
>>>> On Mar 13, 2014, at 10:05 AM, Aristedes Maniatis <[email protected]> wrote:
>>>
>>>>> It would be nice public relations to have "Cayenne has out-of-the-box
>>>>> crypto support" as a feature. Are you storing a key version as part of
>>>>> the encrypted data stream?
>>>>
>>>> I am still working on this piece actually. It has to be attached to the
>>>> record. The question is whether we keep it unencrypted (simplifies
>>>> management and migration between keys), or encrypt it together with the
>>>> data (more secure).
>>>
>>>
>>> I don't see any value in encrypting it. What security does that create?
>>> Also, keeping it in the same database column makes for simpler storage and
>>> robustness. Much like storing the salt with a password hash, or the hashing
>>> algorithm with the password in LDAP:
>>>
>>> 86gwfku:tgiynv45zpyqaqqpucnp3f8k8uk3dzqy
>>>
>>> {SSHA}ddrd686254iteu9gqsz4aztufkgbctuz
>>
>> yeah, perhaps you are right. Encrypting it doesn't provide better protection
>> from brute-force attacks on the key. Just some obfuscation.
>>
>> Andrus