You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by Jamesb <ja...@bowkett.info> on 2011/12/01 15:02:24 UTC

hashed salted passwords and realm authentication

Hi,

I hope this is a very straightforward question to answer.  I am using the
following code to create and store my users' passwords:


            ByteSource salt = new SecureRandomNumberGenerator().nextBytes();
            SimpleHash hashedSaltedPassword = new SimpleHash("SHA-256",
password, salt);

            Properties props = new Properties();
            mRealm.addAccount(mUsername, hashedSaltedPassword.toString(),
"user");    
            props.setProperty("user."+username, hashedSaltedPassword
+","+salt+","+roles);
            //write out the properties file....

I am then using a subclass of PropertyRealm to read these
username/password/salt/roles lines in using the following code:

            String[] passwordSaltAndRolesArray = StringUtils.split(value);
            
            final String hashedSaltedPassword =
passwordSaltAndRolesArray[0];
            final String salt = passwordSaltAndRolesArray[1];
            final ByteSource saltSrc = new
SimpleByteSource(salt.getBytes());
            
            add(new SimpleAccount(username, hashedSaltedPassword, saltSrc,
getName()));

My Realm has a HashCredentialsMatcher("SHA-256") injected into it, but I
cannot authenticate any users, what am I doing wrong here?
In the realm, should I just use a SimpleCredentialsMatcher and create
Sha256Hash instances for the credentials for it to match?...However, my
understanding is that the Sha256CredentialsMatcher will encode and add the
user's salt to any offered up UsernamePasswordToken?
Is part of my problem that I'm not storing the salted hashed passwords or
salts as base64/hex?

Many thanks,

-James






--
View this message in context: http://shiro-user.582556.n2.nabble.com/hashed-salted-passwords-and-realm-authentication-tp7050618p7050618.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: hashed salted passwords and realm authentication

Posted by Jamesb <ja...@bowkett.info>.
Hi I got this working by following your advice, Les....I changed the above
code to:

            String salt = passwordSaltAndRolesArray[1];
            ByteSource saltSrc = new
SimpleByteSource(Base64.decode(salt.getBytes()));

I also had to overload the SimpleAccountRealm.addAccount method in my
SaltedPropertiesRealm to add the salt into the SimpleAccount object when
adding to the account to the realm, both on creation and when reading from
the properties file.  

This did seem uncharacteristically fiddly for Shiro, I look forward to
having a play with the PasswordService under 1.2.

Thanks for your help,

-James


--
View this message in context: http://shiro-user.582556.n2.nabble.com/hashed-salted-passwords-and-realm-authentication-tp7050618p7054633.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: hashed salted passwords and realm authentication

Posted by Jamesb <ja...@bowkett.info>.
Hi Les,

Thanks for getting back to me...I wondered if that was the problem, I'll
have a look in the morning at the api calls you mention and let you know if
it sorts it out.  One thing that occurs to me though is that the following
line:

mRealm.addAccount(mUsername, hashedSaltedPassword.toString(), "user"); 

isn't working correctly as I am not able to login using a
UsernamePasswordToken....am I passing the arguments correctly in the
addAccount method call as far as you can tell?

If I can't get this working, I'm happy to give a 1.2 snapshot build a try

Cheers,

-James

--
View this message in context: http://shiro-user.582556.n2.nabble.com/hashed-salted-passwords-and-realm-authentication-tp7050618p7052110.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: hashed salted passwords and realm authentication

Posted by Les Hazlewood <lh...@apache.org>.
Hi James,

When you're reconstituting the salt in your 2nd code block, you're
getting the raw bytes of the actual encoded salt string.  Instead, you
want to decode the string first into its original byte representation.

That is, this is what is going on:

encodedPassword.getBytes() --> raw bytes of the encoded string

This is what should happen:

decode(encodedPassword) --> actual bytes that were encoded.

In Shiro's text-based realms (IniRealm, PropertiesRealm, it knows how
to decode those strings based on whether or not a 0x ('zero' 'x')
prefixes the string.  If it does prefix (0x1234567890ABCDEF) it is a
hex-encoded value that must be decoded via Hex.decode(string). If
there is no 0x prefix, it is assumed the string is Base64 encoded and
Base64.decode would be used instead.

Finally, I should mention that this will all be _much_ easier in Shiro
1.2.  Later today I should be able to (finally) check in my work on a
new PasswordService that automates much of the entire password
workflow for Shiro-enabled application.  You might want to try a
snapshot build or build from source tomorrow to see if that makes life
easier for you.

HTH!

-- 
Les Hazlewood
CTO, Katasoft | http://www.katasoft.com | 888.391.5282
twitter: @lhazlewood | http://twitter.com/lhazlewood
katasoft blog: http://www.katasoft.com/blogs/lhazlewood
personal blog: http://leshazlewood.com

On Thu, Dec 1, 2011 at 6:02 AM, Jamesb <ja...@bowkett.info> wrote:
> Hi,
>
> I hope this is a very straightforward question to answer.  I am using the
> following code to create and store my users' passwords:
>
>
>            ByteSource salt = new SecureRandomNumberGenerator().nextBytes();
>            SimpleHash hashedSaltedPassword = new SimpleHash("SHA-256",
> password, salt);
>
>            Properties props = new Properties();
>            mRealm.addAccount(mUsername, hashedSaltedPassword.toString(),
> "user");
>            props.setProperty("user."+username, hashedSaltedPassword
> +","+salt+","+roles);
>            //write out the properties file....
>
> I am then using a subclass of PropertyRealm to read these
> username/password/salt/roles lines in using the following code:
>
>            String[] passwordSaltAndRolesArray = StringUtils.split(value);
>
>            final String hashedSaltedPassword =
> passwordSaltAndRolesArray[0];
>            final String salt = passwordSaltAndRolesArray[1];
>            final ByteSource saltSrc = new
> SimpleByteSource(salt.getBytes());
>
>            add(new SimpleAccount(username, hashedSaltedPassword, saltSrc,
> getName()));
>
> My Realm has a HashCredentialsMatcher("SHA-256") injected into it, but I
> cannot authenticate any users, what am I doing wrong here?
> In the realm, should I just use a SimpleCredentialsMatcher and create
> Sha256Hash instances for the credentials for it to match?...However, my
> understanding is that the Sha256CredentialsMatcher will encode and add the
> user's salt to any offered up UsernamePasswordToken?
> Is part of my problem that I'm not storing the salted hashed passwords or
> salts as base64/hex?
>
> Many thanks,
>
> -James
>
>
>
>
>
>
> --
> View this message in context: http://shiro-user.582556.n2.nabble.com/hashed-salted-passwords-and-realm-authentication-tp7050618p7050618.html
> Sent from the Shiro User mailing list archive at Nabble.com.