You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shiro.apache.org by Andreas Reichel <an...@manticore-projects.com> on 2016/03/25 04:52:52 UTC

Implementation of SaltStyle.CRYPT

Dear All,

we would like to adopt Shiro and to use the JDBC Realm.
Our database schema however uses the CRYPT like password hash with no
separate SALT column. We found SaltStyle.CRYPT unimplemented, so please
find a small patch attached.


Any issues, please let us know.
Cheers
Andreas

From 3cbc5b40c095872b80f52323c2585ea46e58067e Mon Sep 17 00:00:00 2001
From: Andreas Reichel <an...@manticore-projects.com>
Date: Mar 25, 2016 10:48:43 AM

Implement SaltStyle.CRYPT

diff --git
a/core/src/main/java/org/apache/shiro/realm/jdbc/JdbcRealm.java
b/core/src/main/java/org/apache/shiro/realm/jdbc/JdbcRealm.java
index 646875c..c34a5fe 100644
--- a/core/src/main/java/org/apache/shiro/realm/jdbc/JdbcRealm.java
+++ b/core/src/main/java/org/apache/shiro/realm/jdbc/JdbcRealm.java
@@ -38,6 +38,11 @@
 import java.util.Collection;
 import java.util.LinkedHashSet;
 import java.util.Set;
+import org.apache.shiro.authc.credential.CredentialsMatcher;
+import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
+import org.apache.shiro.crypto.hash.Md5Hash;
+import org.apache.shiro.crypto.hash.Sha256Hash;
+import org.apache.shiro.crypto.hash.Sha512Hash;
 
 
 /**
@@ -221,9 +226,50 @@
                 password = getPasswordForUser(conn, username)[0];
                 break;
             case CRYPT:
-                // TODO: separate password and hash from
getPasswordForUser[0]
-                throw new ConfigurationException("Not implemented
yet");
-                //break;
+                /*
+                http://www.slashroot.in/how-are-passwords-stored-linux
-understanding-hashing-shadow-utils
+                
+                Example: $1$Etg2ExUZ$F9NTP7omafhKIlqaBMqng1
+
+                The above shown encoded hash value can be further
classified into three different fields as below.
+                1. The first field is a numerical number that tell's
you the hashing algorithm that's being used.
+
+                $1 = MD5 hashing algorithm.
+                $2 =Blowfish Algorithm is in use.
+                $2a=eksblowfish Algorithm
+                $5 =SHA-256 Algorithm
+                $6 =SHA-512 Algorithm
+
+                2. The second field is the salt value
+                Salt value is nothing but a random data that's
generated to combine with the original password, inorder to increase
the strength of the hash..
+
+                3.The last field is the hash value of salt+user
password (we will be discussing this shortly).
+                
+                */
+                
+                String[] crypt=getPasswordForUser(conn,
username)[0].split("\\$");
+                String hashAlgorithm=crypt[0];
+                
+                //@todo: set the credential matcher hash algorithm?!
+                CredentialsMatcher credentialsMatcher =
getCredentialsMatcher();
+                if (credentialsMatcher instanceof
HashedCredentialsMatcher) {
+                    HashedCredentialsMatcher
hashedCredentialsMatcher=(HashedCredentialsMatcher) credentialsMatcher;
+                    if (hashAlgorithm.equals("$6")) 
+                        hashedCredentialsMatcher.setHashAlgorithmName(
Sha512Hash.ALGORITHM_NAME);
+                    else if (hashAlgorithm.equals("$5")) 
+                        hashedCredentialsMatcher.setHashAlgorithmName(
Sha256Hash.ALGORITHM_NAME);
+                    else if (hashAlgorithm.equals("$1")) 
+                        hashedCredentialsMatcher.setHashAlgorithmName(
Md5Hash.ALGORITHM_NAME);
+                    else if (hashAlgorithm.equals("$2")) 
+                        throw new AuthenticationException("Requested
'Blowfish' algorithm is not supported. Can not validate the token.");
+                    else if (hashAlgorithm.equals("$2a")) 
+                        throw new AuthenticationException("Requested
'eksblowfish' algorithm is not supported. Can not validate the
token.");
+                }
+                
+                salt=crypt[1];
+                password=crypt[2];
+                
+                break;
             case COLUMN:
                 String[] queryResults = getPasswordForUser(conn,
username);
                 password = queryResults[0];
@@ -265,7 +311,6 @@
         boolean returningSeparatedSalt = false;
         switch (saltStyle) {
         case NO_SALT:
-        case CRYPT:
         case EXTERNAL:
             result = new String[1];
             break;

Re: Implementation of SaltStyle.CRYPT

Posted by Brian Demers <br...@gmail.com>.
Thanks!

Can you put this in a github pull request and add test ?
(using github isn't required, but it makes chatting about the patch easier)

On Thu, Mar 24, 2016 at 11:52 PM, Andreas Reichel <
andreas@manticore-projects.com> wrote:

> Dear All,
>
> we would like to adopt Shiro and to use the JDBC Realm.
> Our database schema however uses the CRYPT like password hash with no
> separate SALT column. We found SaltStyle.CRYPT unimplemented, so please
> find a small patch attached.
>
>
> Any issues, please let us know.
> Cheers
> Andreas
>
> From 3cbc5b40c095872b80f52323c2585ea46e58067e Mon Sep 17 00:00:00 2001
> From: Andreas Reichel <an...@manticore-projects.com>
> Date: Mar 25, 2016 10:48:43 AM
>
> Implement SaltStyle.CRYPT
>
> diff --git
> a/core/src/main/java/org/apache/shiro/realm/jdbc/JdbcRealm.java
> b/core/src/main/java/org/apache/shiro/realm/jdbc/JdbcRealm.java
> index 646875c..c34a5fe 100644
> --- a/core/src/main/java/org/apache/shiro/realm/jdbc/JdbcRealm.java
> +++ b/core/src/main/java/org/apache/shiro/realm/jdbc/JdbcRealm.java
> @@ -38,6 +38,11 @@
>  import java.util.Collection;
>  import java.util.LinkedHashSet;
>  import java.util.Set;
> +import org.apache.shiro.authc.credential.CredentialsMatcher;
> +import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
> +import org.apache.shiro.crypto.hash.Md5Hash;
> +import org.apache.shiro.crypto.hash.Sha256Hash;
> +import org.apache.shiro.crypto.hash.Sha512Hash;
>
>
>  /**
> @@ -221,9 +226,50 @@
>                  password = getPasswordForUser(conn, username)[0];
>                  break;
>              case CRYPT:
> -                // TODO: separate password and hash from
> getPasswordForUser[0]
> -                throw new ConfigurationException("Not implemented
> yet");
> -                //break;
> +                /*
> +                http://www.slashroot.in/how-are-passwords-stored-linux
> -understanding-hashing-shadow-utils
> +
> +                Example: $1$Etg2ExUZ$F9NTP7omafhKIlqaBMqng1
> +
> +                The above shown encoded hash value can be further
> classified into three different fields as below.
> +                1. The first field is a numerical number that tell's
> you the hashing algorithm that's being used.
> +
> +                $1 = MD5 hashing algorithm.
> +                $2 =Blowfish Algorithm is in use.
> +                $2a=eksblowfish Algorithm
> +                $5 =SHA-256 Algorithm
> +                $6 =SHA-512 Algorithm
> +
> +                2. The second field is the salt value
> +                Salt value is nothing but a random data that's
> generated to combine with the original password, inorder to increase
> the strength of the hash..
> +
> +                3.The last field is the hash value of salt+user
> password (we will be discussing this shortly).
> +
> +                */
> +
> +                String[] crypt=getPasswordForUser(conn,
> username)[0].split("\\$");
> +                String hashAlgorithm=crypt[0];
> +
> +                //@todo: set the credential matcher hash algorithm?!
> +                CredentialsMatcher credentialsMatcher =
> getCredentialsMatcher();
> +                if (credentialsMatcher instanceof
> HashedCredentialsMatcher) {
> +                    HashedCredentialsMatcher
> hashedCredentialsMatcher=(HashedCredentialsMatcher) credentialsMatcher;
> +                    if (hashAlgorithm.equals("$6"))
> +                        hashedCredentialsMatcher.setHashAlgorithmName(
> Sha512Hash.ALGORITHM_NAME);
> +                    else if (hashAlgorithm.equals("$5"))
> +                        hashedCredentialsMatcher.setHashAlgorithmName(
> Sha256Hash.ALGORITHM_NAME);
> +                    else if (hashAlgorithm.equals("$1"))
> +                        hashedCredentialsMatcher.setHashAlgorithmName(
> Md5Hash.ALGORITHM_NAME);
> +                    else if (hashAlgorithm.equals("$2"))
> +                        throw new AuthenticationException("Requested
> 'Blowfish' algorithm is not supported. Can not validate the token.");
> +                    else if (hashAlgorithm.equals("$2a"))
> +                        throw new AuthenticationException("Requested
> 'eksblowfish' algorithm is not supported. Can not validate the
> token.");
> +                }
> +
> +                salt=crypt[1];
> +                password=crypt[2];
> +
> +                break;
>              case COLUMN:
>                  String[] queryResults = getPasswordForUser(conn,
> username);
>                  password = queryResults[0];
> @@ -265,7 +311,6 @@
>          boolean returningSeparatedSalt = false;
>          switch (saltStyle) {
>          case NO_SALT:
> -        case CRYPT:
>          case EXTERNAL:
>              result = new String[1];
>              break;