Aloha Jim - nice to see you again :) > I'm reviewing the Shiro crypto API's. What an excellent and simple to use > abstraction!
Glad you like it! > Have there been any review of Shiro's crypto by a professional cryptographer > or similar resource? Have any of those reports been made public? Nothing that is formal or 'white paper'ish, although we would be hugely appreciative of any efforts that professionals might wish to undertake. Just for clarity (although you probably know this, but I want to document for posterity), Shiro does not implement any cryptography algorithms itself. As you stated, it is an abstraction - it 'sits on top' of the more complex JCE API components, implementing best practices with that API. So you can use the default JCE or plug in something like Bouncy Castle, and Shiro will work just fine, delegating to the underlying JCE architecture. > For example, one of the creators of AES told me; "When using AES in CBC mode > your IV's really should be unique per message and the IV's should stay in > secret". Far be it from me to contradict one of the AES authors ;) Shiro does almost all of that out of the box - keeping the IVs secret is not something Shiro does at the moment however due to some complexity requirements that would impose on the Shiro end-user (please feel free to add a Jira improvement issue - I'd be happy to take a look at it). That being said, Shiro's defaults for block ciphers is *much* more secure than the JDK defaults. For example, the JDK defaults to using AES in ECB mode and I believe no padding scheme, which is effectively useless. Here is an example showing why: Plaintext: http://www.slideshare.net/chunsaker/intro-to-apache-shiro/41 Ciphertext w/ JDK's defaults: http://www.slideshare.net/chunsaker/intro-to-apache-shiro/42 Ciphertext w/ Shiro's defaults: http://www.slideshare.net/chunsaker/intro-to-apache-shiro/43 The reason the JDK does this is that almost all other cipher modes of operation require an IV and the JDK's APIs are low level enough such that they can't (won't) generate an IV for you automatically. Shiro however does generate cryptographically strong random IVs and embeds them in the ciphertext output. When decrypting, the IV is 'unembedded' and then used to decrypt the ciphertext. The IV size is the same size as the block size to ensure no other block is distinguishable. Additionally, Shiro uses a proper padding scheme to ensure all output remains a multiple of the block size, to additionally help ensure patterns are hard to distinguish. So while Shiro embeds the random IVs in the message and does not keep them secret, its default approach with secure random IVs and padding schemes is *much* more secure than using the JDK's defaults. With the exception of (few) crypto experts, almost all developers I've personally come across had no idea the JDK's defaults are so insecure and had no idea they weren't using it correctly. At least Shiro gets everyone to a level of security that most wouldn't have achieved otherwise. Finally, the reason why Shiro (currently) embeds the IVs in the ciphertext instead of keeping them secret is one of infrastructural complexity that would be imposed on Shiro end users: we'd need to support a storage abstraction. While this wouldn't be hard to incorporate into Shiro (probably just a few interfaces), it would probably add more confusion to an already confusing topic. That being said, as with all things in Shiro, we can continue with our sensible defaults out-of-the-box and more advanced users can simply turn on the storage feature. Please open a Jira issue if you'd like to see this added (and as always, patches welcome! :)). > My apologies if I'm posting in the wrong place. None necessary - this is the right place :) Thanks for the great questions! Best, Les Hazlewood CTO, Stormapth @lhazlewood
