P.S. A benefit of the PasswordService is that you can change the hashing parameters (algorithm name, iterations, etc) _without_ breaking existing hashed passwords. It automatically works for newly hashed passwords as well as older ones already stored w/ different parameters.
This is not possible when using an AES encryption *unless* your CredentialsMatcher implementation also knows what decryption key to use during an match comparison attempt (e.g. it knows to use decryption key X for dates Jan 1 - Jan 31, decryption key Y for dates Feb 1 - Feb 29, etc.). If you ever change the key (which is a good practice for proper security), your password comparisons will all break unless you have this key-per-range technique working as well. Best, Les On Wed, Mar 13, 2013 at 5:01 PM, Les Hazlewood <[email protected]> wrote: > On Wed, Mar 13, 2013 at 4:33 PM, NabbleReallySucks > <[email protected]> wrote: >> So I am using AesCipherService to encrypt passwords when a user registers. In >> it, I generate a Key/salt and use it to encrypt. I then convert to base 64 >> and store it in the database. >> >> Works great. But I can't see how to hook it up when we try to login. So >> right now credentials won't match. >> >> I set my Realms credentials matcher to >> >> <bean id="hashMatcher" >> class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> >> <property name="hashAlgorithmName" value="SHA-256"/> >> <property name="hashIterations" value="1024"/> >> <property name="storedCredentialsHexEncoded" value="false"/> >> </bean> >> >> Should it instead be >> >> <bean id="hashMatcher" >> class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> >> <property name="hashAlgorithmName" value="AES"/> >> <property name="storedCredentialsHexEncoded" value="false"/> >> </bean> >> >> And would it need hashIterations to be set, and the uses salt boolean be >> set? > > The HashedCredentialsMatcher is used only for Hashing algorithms (also > called Message Digest algorithms), like SHA-2 (SHA-256, SHA-384, > SHA-512, etc), MD5, etc. AES is a block cipher algorithm and is not > considered a hashing algorithm, so you can't use the > HashedCredentialsMatcher here. > > I'm not entirely sure of your security requirements, but if you use > Shiro's PasswordService and PasswordMatcher, you'll have much easier > results. For example: > > <bean id="credentialsMatcher" > class="org.apache.shiro.authc.credential.PasswordMatcher"> > <property name="passwordService" ref="passwordService"/> > </bean> > <bean id="passwordService" > class="org.apache.shiro.authc.credential.DefaultPasswordService"> > <property name="hashService"> > <bean class="org.apache.shiro.crypto.hash.DefaultHashService"> > <property name="generatePublicSalt" value="true"/> <!-- > ALWAYS true for user passwords --> > <property name="hashAlgorithmName" value="SHA-512"/> > <property name="hashIterations" value="500000"/> <!-- 500,000 --> > </bean> > </property> > </bean> > <bean id="myRealm" class="..."> > <property name="credentialsMatcher" ref="credentialsMatcher"/> > ... > </bean> > > You can then use the PasswordService in your app: > > PasswordService svc = getBean("passwordService"); > > String hashed = svc.encryptPassword(rawPassword); > > //store in database: > user.setPassword(hashed); > user.save(); > > For all subsequent authentication attempts, Shiro will use the > PasswordMatcher to check the hashed value in the database. > > That is all that is required. > > However, if you want to AES encrypt the hashed value before it goes to > the database, that's fine, but you'll need to write your own > CredentialsMatcher that knows how to decrypt the encrypted value > first. > > For example, you might have a CredentialsMatcher that: > > 1. decrypts the db value > 2. uses the decrypted value and delegates to a PasswordMatcher > instance for the rest of the work (i.e. the decrypted value is the > hashed password). > > Again, I don't know your security requirements, but most applications > don't need the extra encryption before storage - the hash is already a > one-way conversion that can't be reversed (but could be theoretically > brute-forced if the database values were ever available to an attacker > - implying they had direct access to the database - but that would > take a really long time for pretty much any attacker that isn't a > nation state). > > HTH, > > Les
