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