Last night I gave a presentation to the Groovy Users of Minnesota (GUM) group on the Grails Jasypt Encryption Plugin. It was well received and I was happy with the number of people that showed up on a hot summer night.
A pdf of the presentation as well as the sample source code that I used during the presentation can be found on bitbucket.
Thanks to everyone who showed up, GUM is a great group to present to, lots of good questions.
[...] This post was mentioned on Twitter by Colin Harrington, Ted Naleid. Ted Naleid said: just posted the presentation from my talk at GUM last night on the grails jasypt encryption plugin http://bit.ly/aMsX4Q [...]
Hi Ted,
My name is Daniel Fernández and I am the author of the Jasypt library.
I just wanted to thank you for your nice work with the Grails Jasypt plugin and this presentation. Although I am not a user of Grails myself, I really appreciate users expanding jasypt’s capabilities and spreading the word about it. Thanks for that.
Just one point, about the “cannot use WHERE” thing: in fact you can query encrypted fields using WHERE clauses, but you need to set a fixed salt generator for that. There is a point at the FAQ [ http://www.jasypt.org/faq.html ] about that, but for some reason I wrote it hibernate-oriented and in a somewhat obscure manner, so it may be difficult to find for some users — I’ll certainly have to rewrite that question…
Anyway, thanks again, and keep up the good work!
Regards,
Daniel.
Thanks for the plugin! Do you have support for Web PBE Configuration (http://www.jasypt.org/webconfiguration.html) which would avoid having to store the password in a config file?
@Daniel – thanks for the clarification about WHERE clauses. I actually talked about using a fixed salt during the presentation as a potential workaround for getting some finders working again (though as you mention on your FAQ, case insensitive and LIKE clauses still wouldn’t work). The reduced security of fixed salts currently outweigh the loss of dynamic finders for how I’m using the plugin today, but there are a number of use cases where it’d be useful to have.
@Roshan – it doesn’t currently support Web PBE Configuration – I was comfortable with using external configuration files that aren’t in the war (the bitbucket wiki page goes into how to set this up).
If there’s demand for either fixed salts or Web PBE Config, I’d consider adding them to the plugin.
Nice work, Ted. We need something like this for a Grails 1.2.1 app, so I took a look at the source. It wasn’t obvious to me why the plugin would not work on earlier versions of Grails. Other than you were using the latest version, does anything come to mind?
+1 for the Web PBE Configuration feature.
Also, for regulatory requirements you’d need to change the encryption key on a periodic basis, so the functionality for decrypting with the old key and encrypting with the new one would be needed sooner or later.
@Sunny There isn’t anything in the plugin that I’m aware of that’d prevent it from working on an earlier version of grails, I just haven’t tested it on anything pre 1.3.
Your suggestion to enable the changing of the password is a good one, though in practice, I think it would still be a little painful. I’m thinking that there would be 2 encryptors in play and that we’d have to spin through the various domain objects and update them each in succession. Doing this on a live database would be problematic though it wouldn’t be as bad if this was the only thing running (though it’d take quite a which to run on a big db).
Ted, I pulled the source and changed the compatibility to Grails 1.2.1 and tested:
def grailsVersion = “1.2.1 > *”
The plugin builds and works fine with although I do get this during the package-plugin step
WARNING: There was an error loading the BuildConfig: No signature of method: org.codehaus.groovy.grails.resolve.IvyDependencyManager.grailsCentral() is applicable for argument types: () values: []
So the next time you do a build to may want to consider dropping the Grails requirement down to 1.2.1. Thanks
Ted, for this to be production ready the password must be changeable. Also, the web PBE config is a good thing to have. I guess I’m going to use the jasypt java libs directly since I don’t know enough about grails plugins to modify your code.
@Jon – Thanks for the feedback. I agree that additional steps need to be in place along with the encryption plugin to have a production ready security setup. We have a process to rencrypt the db fields outside of the plugin and also have another method to take the place of web PBE.
I’ll happily accept patches to the plugin if someone wants to take the time to implement these, but they don’t have high value for me.
Ted, would it be possible for you to publish/send your source code to rencrypt the db fields and/or the web PBE alternative? We can take a crack at it.
@Sunny, the code isn’t currently in a state near what I can send but I can outline the high level steps of what I did (they aren’t that hard to implement).
I currently run it in a grails console, so that I have access to my domain objects and the grails artefacts/properties. I get a reference to the existing encryptor with the old encryption key from GORM:
I then create a new encryptor with the new encryption key manually (this is sort of ugly manual instantiation using jasypt, part of what’s not ready for primetime).
It iterates through the domain artefacts and finds those fields that are backed by the encryption. It then spins through all of those domains and uses the hibernate connection to execute SQL (not HQL) against the table to get the encrypted values (look at DefaultGrailsDomainClass and GrailsDomainClassProperty to see how to look at a class and it’s mappings and db field names).
I then use the old encryptor to decrypt and the new encryptor to reencrypt and reinsert the newly encrypted value.
This works for us, but there are a number of edge cases/issues with this approach that might affect how other people use their code (ex: if you’re encrypting anything that’s a foreign key).
This also isn’t super speedy as you might imagine and for really large databases, you’d likely want to split this work up and parallelize it.
Regarding web PBE, that doesn’t work in our deployment model as we’re on EC2 with multiple application servers that are autoscaled up/down depending on traffic. Having to have a real person enter the key in a web console to bring another app server into the pool isn’t feasable. Our database server is completely separate from our app servers so the key is on a different box, protected by different credentials/ssh keys and in a different security zone. There are some additional precautions we have, but these are the high level reasons why web PBE doesn’t work for us (and why it’s not really worth my time to implement it).
As I mentioned above, if people want to submit patches to the grails jasypt to implement either of these functions, I’d be happy to accept them, I just don’t have time to work on them myself now.