On Fri, Apr 1, 2011 at 5:11 AM, Tauren Mills <[email protected]> wrote: > Les, > Thanks for your ideas, as always! So for password hashing, would you suggest > using something like this? > ByteSource appSalt = new SimpleByteSource(APPLICATION_SALT); > ByteSource userSalt = (new SecureRandomNumberGenerator()).nextBytes(); > ByteSource salt = new SimpleByteSource(ArrayUtils.addAll(appSalt.getBytes(), > userSalt.getBytes())); > member.setPassword(new Sha512Hash(dto.getPassword(), salt.getBytes(), > SALT_ITERATIONS).toBase64()); > member.setSalt(userSalt.toBase64()); > Note that this uses your suggestion to have both an application salt and a > user salt, but only the user salt gets saved to the database. That way a > database compromise would still not give the attacker the full salt value.
Yep, this looks great. Exactly what I do in my own apps :) Because of this, for a long time I wanted to create a PasswordService concept in Shiro (maybe something in line with https://issues.apache.org/jira/browse/SHIRO-213 - I'm not sure) that encapsulates the logic that you've just laid out and what I'm sure people replicate from app to app. I just created a new issue for it here: https://issues.apache.org/jira/browse/SHIRO-280 Feel free to vote for it if you'd like to see it implemented earlier rather than later. > Any suggestions on migrating existing simple Sha256Hash() passwords without > interrupting user logins? Perhaps have Member.password and > Member.oldPassword properties. If Member.password is NULL, then test using > the old method and update Member.password with data if old method is > successful. If Member.password exists, then test using new method as user > password has been upgraded already. Or do you have a better idea? Nope, this sounds pretty good to me as a non-invasive approach. A more direct approach might be to send 'reset password' emails and force them to reset their passwords either via a link in the email or upon the next login (you would null/remove the existing password hash to ensure it couldn't be used to compromise their account). This is definitely invasive in that it requires user interaction, but if you have any concern at all, it is the safe approach. > In regards to encrypting sensitive data, I don't yet want to get into the > complexities of rolling keys, although it sounds like a really great idea. > I'm only wanting to make sure my application is PCI compliant, it doesn't > need to provide military grade security. If I choose to not install the JCE > unlimited strength policy files, I will be limited to using AES-128 at the > maximum, right? Yep. But if you have control of the JVM, it is trivial to install the files, so I'd do it as a matter of course. But if you don't control the JVM installation, then yes, it'd be harder to support anything above 128 bit encryption. > When reading the Javadocs, it looks like the IV is prepended to the > encrypted data and stored with it. It also looks like they are comprised of > purely random data. I'm curious what your thoughts are in regards to > including an entity ID into the IV, as suggested in Method 6 in the > following link. To me it really only sounds useful if you're trying to > conserve space in the DB. > http://www.di-mgt.com.au/cryptoCreditcard.html The only need for this is to save space, which is unnecessary these days IMO. Having your IV based on anything that is not random (e.g. an entity id) weakens the IV to a certain degree. I'd just stick to Shiro's defaults of using completely random IVs and accept the extra few bytes (it's only really 16 bytes for AES - practically a negligible amount for modern systems). My opinion for this is that my application users' security is easily worth the extra disk space it might cost me, especially given the cost of cheap disks these days, as well as any larger costs (e.g. lawsuits) that might arise from doing it in a less secure manner. > Assuming I'm not going for rolling keys, would you suggest having one > application-wide key that is used to encrypt and decrypt any sensitive > values? Or would it be better to have different keys for different purposes > (one for credit cards, another for SSNs, etc.)? The more keys the better, since a compromise on one doesn't necessarily mean a compromise of another. However, if you store all of your keys in the same place, you can assume that if one is compromised, they all will be. In this case, a single key is just as effective as multiple keys. > Shiro's certainly made it dead simple to work with crypto. Is there anything > wrong with the following implementation, or anything you would do to improve > the way I'm using Shiro's crypto (note I haven't tested the following code > yet)? Looks pretty good to me! Best, -- Les Hazlewood Founder, Katasoft, Inc. Application Security Products & Professional Apache Shiro Support and Training: http://www.katasoft.com
