You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2017/03/04 17:18:47 UTC

svn commit: r1785509 - in /directory/shared/trunk: ./ ldap/model/ ldap/model/src/main/java/org/apache/directory/api/ldap/model/constants/ ldap/model/src/main/java/org/apache/directory/api/ldap/model/password/ ldap/model/src/test/java/org/apache/directo...

Author: elecharny
Date: Sat Mar  4 17:18:47 2017
New Revision: 1785509

URL: http://svn.apache.org/viewvc?rev=1785509&view=rev
Log:
Applied patch provided by Thilo-Alexander (DIRSERVER-2180), but using teh OSGi aware lib from de.svenkubiak

Modified:
    directory/shared/trunk/ldap/model/pom.xml
    directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/constants/LdapSecurityConstants.java
    directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/password/PasswordUtil.java
    directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/password/PasswordUtilTest.java
    directory/shared/trunk/pom.xml

Modified: directory/shared/trunk/ldap/model/pom.xml
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/model/pom.xml?rev=1785509&r1=1785508&r2=1785509&view=diff
==============================================================================
--- directory/shared/trunk/ldap/model/pom.xml (original)
+++ directory/shared/trunk/ldap/model/pom.xml Sat Mar  4 17:18:47 2017
@@ -92,6 +92,11 @@
     </dependency>
 
     <dependency>
+      <groupId>de.svenkubiak</groupId>
+      <artifactId>jBCrypt</artifactId>
+    </dependency>
+
+    <dependency>
       <groupId>findbugs</groupId>
       <artifactId>annotations</artifactId>
       <scope>provided</scope>

Modified: directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/constants/LdapSecurityConstants.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/constants/LdapSecurityConstants.java?rev=1785509&r1=1785508&r2=1785509&view=diff
==============================================================================
--- directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/constants/LdapSecurityConstants.java (original)
+++ directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/constants/LdapSecurityConstants.java Sat Mar  4 17:18:47 2017
@@ -68,6 +68,9 @@ public enum LdapSecurityConstants
     
     /** The crypt (SHA-512) encryption method */
     HASH_METHOD_CRYPT_SHA512("CRYPT-SHA-512", "SHA-512", "crypt", "$6$"),
+    
+    /** The BCrypt encryption method */
+    HASH_METHOD_CRYPT_BCRYPT("CRYPT-BCRYPT", "BCRYPT", "crypt", "$2a$"),
 
     /** The PBKDF2-based encryption method */
     HASH_METHOD_PKCS5S2("PKCS5S2", "PBKDF2WithHmacSHA1", "PKCS5S2");
@@ -211,6 +214,11 @@ public enum LdapSecurityConstants
             return HASH_METHOD_CRYPT_SHA512;
         }
 
+        if ( matches( algorithm, HASH_METHOD_CRYPT_BCRYPT ) )
+        {
+            return HASH_METHOD_CRYPT_BCRYPT;
+        }
+
         if ( matches( algorithm, HASH_METHOD_SHA256 ) )
         {
             return HASH_METHOD_SHA256;

Modified: directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/password/PasswordUtil.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/password/PasswordUtil.java?rev=1785509&r1=1785508&r2=1785509&view=diff
==============================================================================
--- directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/password/PasswordUtil.java (original)
+++ directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/password/PasswordUtil.java Sat Mar  4 17:18:47 2017
@@ -38,6 +38,7 @@ import org.apache.directory.api.util.Bas
 import org.apache.directory.api.util.DateUtils;
 import org.apache.directory.api.util.Strings;
 
+import org.mindrot.jbcrypt.BCrypt;
 
 /**
  * A utility class containing methods related to processing passwords.
@@ -77,6 +78,8 @@ public final class PasswordUtil
     /** The CRYPT (SHA-512) hash length */
     public static final int CRYPT_SHA512_LENGTH = 86;
 
+    /** The CRYPT (BCrypt) hash length */
+    public static final int CRYPT_BCRYPT_LENGTH = 31;
 
     private static final byte[] CRYPT_SALT_CHARS = Strings
         .getBytesUtf8( "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" );
@@ -127,11 +130,17 @@ public final class PasswordUtil
                 String algorithm = Strings.toLowerCaseAscii( Strings.utf8ToString( credentials, 1, pos - 1 ) );
 
                 // support for crypt additional encryption algorithms (e.g. {crypt}$1$salt$ez2vlPGdaLYkJam5pWs/Y1)
-                // currently only one-digit IDs are defined thus this quick check
                 if ( credentials.length > pos + 3 && credentials[pos + 1] == '$'
-                    && Character.isDigit( credentials[pos + 2] ) && credentials[pos + 3] == '$' )
+                    && Character.isDigit( credentials[pos + 2] ) )
                 {
-                    algorithm += Strings.utf8ToString( credentials, pos + 1, 3 );
+                    if ( credentials[pos + 3] == '$' )
+                    {
+                        algorithm += Strings.utf8ToString( credentials, pos + 1, 3 );
+                    }
+                    else if ( credentials.length > pos + 4 && credentials[pos + 4] == '$' )
+                    {
+                        algorithm += Strings.utf8ToString( credentials, pos + 1, 4 );
+                    }
                 }
 
                 return LdapSecurityConstants.getAlgorithm( algorithm );
@@ -208,7 +217,11 @@ public final class PasswordUtil
             case HASH_METHOD_CRYPT_SHA512:
                 salt = generateCryptSalt( 8 );
                 break;
-
+                
+            case HASH_METHOD_CRYPT_BCRYPT:
+                salt = Strings.getBytesUtf8( BCrypt.gensalt() );
+                break;
+    
             default:
                 salt = null;
         }
@@ -218,7 +231,8 @@ public final class PasswordUtil
 
         sb.append( '{' ).append( Strings.upperCase( algorithm.getPrefix() ) ).append( '}' );
 
-        if ( algorithm == LdapSecurityConstants.HASH_METHOD_CRYPT )
+        if ( algorithm == LdapSecurityConstants.HASH_METHOD_CRYPT
+            || algorithm == LdapSecurityConstants.HASH_METHOD_CRYPT_BCRYPT )
         {
             sb.append( Strings.utf8ToString( salt ) );
             sb.append( Strings.utf8ToString( hashedPassword ) );
@@ -315,7 +329,7 @@ public final class PasswordUtil
             // be able to encrypt the submitted user password in the next step
             PasswordDetails passwordDetails = PasswordUtil.splitCredentials( storedCredentials );
 
-            // Reuse the saltedPassword informations to construct the encrypted
+            // Reuse the saltedPassword information to construct the encrypted
             // password given by the user.
             byte[] userPassword = PasswordUtil.encryptPassword( receivedCredentials, passwordDetails.getAlgorithm(),
                 passwordDetails.getSalt() );
@@ -412,6 +426,10 @@ public final class PasswordUtil
                     algorithm.getSubPrefix() + Strings.utf8ToString( salt ) );
                 String crypted2 = saltWithCrypted2.substring( saltWithCrypted2.lastIndexOf( '$' ) + 1 );
                 return Strings.getBytesUtf8( crypted2 );
+
+            case HASH_METHOD_CRYPT_BCRYPT:
+                String crypted3 = BCrypt.hashpw( Strings.utf8ToString( credentials ), Strings.utf8ToString( salt ) );
+                return Strings.getBytesUtf8( crypted3.substring( crypted3.length() - 31 ) );
                 
             case HASH_METHOD_PKCS5S2:
                 return generatePbkdf2Hash( credentials, algorithm, salt );
@@ -515,6 +533,11 @@ public final class PasswordUtil
                 split( credentials, algoLength, salt, password );
                 return new PasswordDetails( algorithm, salt, password );
 
+            case HASH_METHOD_CRYPT_BCRYPT:
+                    salt = Arrays.copyOfRange( credentials, algoLength, credentials.length - 31 );
+                    password = Arrays.copyOfRange( credentials, credentials.length - 31, credentials.length );
+                    
+                    return new PasswordDetails( algorithm, salt, password );
             case HASH_METHOD_CRYPT_MD5:
             case HASH_METHOD_CRYPT_SHA256:
             case HASH_METHOD_CRYPT_SHA512:
@@ -602,8 +625,8 @@ public final class PasswordUtil
      * 
      * Note: this has been implemented to generate hashes compatible with what JIRA generates.
      *       See the <a href="http://pythonhosted.org/passlib/lib/passlib.hash.atlassian_pbkdf2_sha1.html">JIRA's passlib</a>
+     * @param credentials the credentials
      * @param algorithm the algorithm to use
-     * @param password the credentials
      * @param salt the optional salt
      * @return the digested credentials
      */

Modified: directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/password/PasswordUtilTest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/password/PasswordUtilTest.java?rev=1785509&r1=1785508&r2=1785509&view=diff
==============================================================================
--- directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/password/PasswordUtilTest.java (original)
+++ directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/password/PasswordUtilTest.java Sat Mar  4 17:18:47 2017
@@ -22,6 +22,7 @@ package org.apache.directory.api.ldap.mo
 
 
 import static org.apache.directory.api.ldap.model.constants.LdapSecurityConstants.HASH_METHOD_CRYPT;
+import static org.apache.directory.api.ldap.model.constants.LdapSecurityConstants.HASH_METHOD_CRYPT_BCRYPT;
 import static org.apache.directory.api.ldap.model.constants.LdapSecurityConstants.HASH_METHOD_CRYPT_MD5;
 import static org.apache.directory.api.ldap.model.constants.LdapSecurityConstants.HASH_METHOD_CRYPT_SHA256;
 import static org.apache.directory.api.ldap.model.constants.LdapSecurityConstants.HASH_METHOD_CRYPT_SHA512;
@@ -36,6 +37,7 @@ import static org.apache.directory.api.l
 import static org.apache.directory.api.ldap.model.constants.LdapSecurityConstants.HASH_METHOD_SSHA256;
 import static org.apache.directory.api.ldap.model.constants.LdapSecurityConstants.HASH_METHOD_SSHA384;
 import static org.apache.directory.api.ldap.model.constants.LdapSecurityConstants.HASH_METHOD_SSHA512;
+import static org.apache.directory.api.ldap.model.password.PasswordUtil.CRYPT_BCRYPT_LENGTH;
 import static org.apache.directory.api.ldap.model.password.PasswordUtil.CRYPT_LENGTH;
 import static org.apache.directory.api.ldap.model.password.PasswordUtil.CRYPT_MD5_LENGTH;
 import static org.apache.directory.api.ldap.model.password.PasswordUtil.CRYPT_SHA256_LENGTH;
@@ -348,8 +350,26 @@ public class PasswordUtilTest
     }
 
 
-    private void testPassword( String plainText, String encrypted, LdapSecurityConstants algorithm, int passwordLength,
-        int saltLength )
+    @Test
+    public void testPasswordCRYPT2aEncrypted()
+    {
+        testPassword( "secret",
+            "{CRYPT}$2a$06$LH2xIb/TZmajuLJGDNuegeeY.SCwkg6YAVLNXTh8n4Xfb1uwmLXg6",
+            HASH_METHOD_CRYPT_BCRYPT, CRYPT_BCRYPT_LENGTH, 29 );
+    }
+
+
+    @Test
+    public void testPasswordCRYPT2aEncryptedLowercase()
+    {
+        testPassword( "secret",
+            "{crypt}$2a$06$LH2xIb/TZmajuLJGDNuegeeY.SCwkg6YAVLNXTh8n4Xfb1uwmLXg6",
+            HASH_METHOD_CRYPT_BCRYPT, CRYPT_BCRYPT_LENGTH, 29 );
+    }
+
+
+    private void testPassword(String plainText, String encrypted, LdapSecurityConstants algorithm, int passwordLength,
+                              int saltLength )
     {
         // assert findAlgorithm
         assertEquals( algorithm, PasswordUtil.findAlgorithm( Strings.getBytesUtf8( encrypted ) ) );

Modified: directory/shared/trunk/pom.xml
URL: http://svn.apache.org/viewvc/directory/shared/trunk/pom.xml?rev=1785509&r1=1785508&r2=1785509&view=diff
==============================================================================
--- directory/shared/trunk/pom.xml (original)
+++ directory/shared/trunk/pom.xml Sat Mar  4 17:18:47 2017
@@ -53,6 +53,7 @@
     <dom4j.version>1.6.1</dom4j.version>
     <findbugs.annotations.version>1.0.0</findbugs.annotations.version>
     <forbiddenapis.version>2.2</forbiddenapis.version>
+    <jbcrypt.version>0.4.1</jbcrypt.version>
     <junit.version>4.12</junit.version>
     <log4j.version>1.2.17</log4j.version>
     <logback.version>1.1.8</logback.version>
@@ -590,7 +591,13 @@
         <artifactId>junit</artifactId>
         <version>${junit.version}</version>
       </dependency>
-      
+
+      <dependency>
+        <groupId>de.svenkubiak</groupId>
+        <artifactId>jBCrypt</artifactId>
+        <version>${jbcrypt.version}</version>
+      </dependency> 
+
       <dependency>
         <groupId>xml-apis</groupId>
         <artifactId>xml-apis</artifactId>