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 <mkien...@gmail.com> 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 <and...@objectstyle.org> 
> wrote:
>>
>>
>> On Mar 13, 2014, at 11:06 AM, Aristedes Maniatis <a...@maniatis.org> wrote:
>>
>>> On 13/03/2014 6:31pm, Andrus Adamchik wrote:
>>>>
>>>> On Mar 13, 2014, at 10:05 AM, Aristedes Maniatis <a...@maniatis.org> 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

Reply via email to