Hi Tauren,

Please see inline:

> looked for documentation and samples, but haven't really found many
> resources on using Shiro's cryptography features.

Yep, this is the biggest remaining hole in our documentation.  We've
worked hard on filling in the gaps thus far - but that needs to be
flushed out.

> I have a feeling I could be using the Cryptography features much more
> effectively. For instance, when a new user signs up, I do the following:
>     member.setPassword(new Sha256Hash(dto.getPassword()).toHex());

You absolutely want to be using a salt when hashing passwords, which
will make rainbow attacks virtually impossible.  I highly recommend
multiple iterations (built in to Shiro's hash concept from inception).
 See my link [1] below for more.

> I require that all passwords are at least 8 characters long and include
> characters from at least three of the following four categories: lowercase
> letters, uppercase letters, numbers, and symbols. After reading the
> following article, I'm worried about just how easy it would be to crack
> these password hashes:
>     http://codahale.com/how-to-safely-store-a-password/
> I seem to recall some talk of performing multiple hashes on things to secure
> them better? Any links to this resource?

The article is mostly correct, but unfortunately the author delivered
it with a bit of sensationalism and FUD.  His points are true under a
really big assumption:

That the saved passwords and password salts are easily accessible to
the attacker.  This means that the attacker has broken through your
firewalls and other network security layers, through or around your
app (hopefully secured by Shiro!) and database connection, etc and has
a ton of computing power ready to churn all of your data.  While this
is a real possibility for security unconscious organizations, it is
managed fairly well by most competent organizations.  IMO the biggest
risk for this type of attack is not computational but social (e.g.
social engineering - getting access to a developer or system engineer
password when that person has the keys to the kingdom).

Basically, at the end of the day, if you use a sufficiently powerful
hash algorithm (SHA-256 or SHA-512), use a salt, _and_ use a large
number of hash iterations, you'll be doing what that article
advocates.  The key is not that bcrypt is some super fancy hashing
algorithm, but that it is slow.  Speed is the key - the slower the
hash operation, the longer it takes the attacker to thwart a system.
While it doesn't sound like a big deal, it provides orders of
magnitude more protection if a compute cluster is trying to thrash
your data concurrently.

This is why Shiro's Hash concept has had the 'iterations' property
since it was created - using a Shiro Hash (with a salt and
iterations), you'd be doing exactly as that blog advocates.

> Also, I have some sensitive data (credit card, SSN, etc.) that I want to
> encrypt before storing in the database.

Shiro's CipherService will be a huge help in this case.  Using the JDK
default block cipher (AES, Blowfish, etc) config is just plain
insecure - they don't use things like InitializationVectors by
default.  The CipherService implementations will do a lot of this
stuff for you out of the box.

The safest thing to do in this case to the best of my knowledge is to
have a rolling key mechanism:  use AES 256 encryption (requires the
JCE Unlimited Strength policy files to be installed) using Shiro's
AesCipherService.  Every n period of time (hours, days, etc),
un-encrypt what you currently have with the existing AES 256 key,
generate a new AES 256 key, and re-encrypt the data and save it.  This
ensures that there is a known (and limited) window of time for which
the key is valid.

Rolling keys reduce the ability of any previous key accessors (even
employees) to access the data at a future time.  I know of a more than
a few companies that require rolling key policies for sensitive data,
and it is especially smart to do with super sensitive information (HR
records, credit cards, etc).  I would think a typical web app store
front could have n equal to 1 or 2 days or even up to a week.  However
if the number of records is low (only a few million or less), then the
computation is cheap/fast and having n equal 1 day (or even less) is a
pretty good practice IMO.

> I'm considering adding BouncyCastle
> to my application, but perhaps I can use existing Shiro features.

Yep, BouncyCastle is a complementing mechanism to Shiro - not a
competitor.  Because Shiro sits on top of standard Java cryptography
classes, and BouncyCastle can be a JCE provider, Shiro will
effectively 'sit on top of' BouncyCastle quite nicely.  This isn't
really necessary in my opinion though - AES 256-bit encryption with
Initialization Vectors is approaching military-grade encryption
(without the physical security part since Shiro is all software based)
and is already available in the JDK by default.  You just need to
ensure you've installed the JCE Unlimited Strength policy files.

Here are some links that might be of help:

[1] A previous discussion of password hashing techniques/reasoning:
http://www.mail-archive.com/[email protected]/msg00256.html
[2] A presentation I gave to the San Francisco JUG on Shiro:
http://www.youtube.com/watch?v=5ZepGFzYHpE  Jump to the 45:52 mark for
the Cryptography part of the presentation.

HTH!

Best,

-- 
Les Hazlewood
Founder, Katasoft, Inc.
Application Security Products & Professional Apache Shiro Support and Training:
http://www.katasoft.com

Reply via email to