You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ka...@apache.org on 2013/09/17 08:15:43 UTC
svn commit: r1523919 - in /directory:
apacheds/trunk/interceptors/hash/src/main/java/org/apache/directory/server/core/hash/
shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/constants/
shared/trunk/ldap/model/src/main/java/org/a...
Author: kayyagari
Date: Tue Sep 17 06:15:42 2013
New Revision: 1523919
URL: http://svn.apache.org/r1523919
Log:
support for PKCS5S2 hashing mechanism (DIRSERVER-1898)
Added:
directory/apacheds/trunk/interceptors/hash/src/main/java/org/apache/directory/server/core/hash/Pkcs5s2PasswordHashingInterceptor.java
Modified:
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/EncryptionMethod.java
directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/password/PasswordUtil.java
Added: directory/apacheds/trunk/interceptors/hash/src/main/java/org/apache/directory/server/core/hash/Pkcs5s2PasswordHashingInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/interceptors/hash/src/main/java/org/apache/directory/server/core/hash/Pkcs5s2PasswordHashingInterceptor.java?rev=1523919&view=auto
==============================================================================
--- directory/apacheds/trunk/interceptors/hash/src/main/java/org/apache/directory/server/core/hash/Pkcs5s2PasswordHashingInterceptor.java (added)
+++ directory/apacheds/trunk/interceptors/hash/src/main/java/org/apache/directory/server/core/hash/Pkcs5s2PasswordHashingInterceptor.java Tue Sep 17 06:15:42 2013
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.directory.server.core.hash;
+
+
+import org.apache.directory.api.ldap.model.constants.LdapSecurityConstants;
+
+
+/**
+ * PasswordHashingInterceptor using PBKDF2WithHmacSHA1 encryption algorithm
+ * to generate a secret key and use its encoded value as the password hash
+ * with {PKCS5S2} prefix.
+ *
+ * See <a href="http://en.wikipedia.org/wiki/PBKDF2">PBKDF2 spec</a> for more
+ * details.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class Pkcs5s2PasswordHashingInterceptor extends PasswordHashingInterceptor
+{
+ /**
+ * Creates an instance of a Pkcs5s2PasswordHashingInterceptor
+ */
+ public Pkcs5s2PasswordHashingInterceptor()
+ {
+ super( "Pkcs5s2PasswordHashingInterceptor", LdapSecurityConstants.HASH_METHOD_PKCS5S2 );
+ }
+
+}
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=1523919&r1=1523918&r2=1523919&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 Tue Sep 17 06:15:42 2013
@@ -61,7 +61,10 @@ public enum LdapSecurityConstants
HASH_METHOD_SMD5("SMD5", "MD5", "smd5"),
/** The crypt encryption method */
- HASH_METHOD_CRYPT("CRYPT", "CRYPT", "crypt");
+ HASH_METHOD_CRYPT("CRYPT", "CRYPT", "crypt"),
+
+ /** The PBKDF2-based encryption method */
+ HASH_METHOD_PKCS5S2("PKCS5S2", "PBKDF2WithHmacSHA1", "PKCS5S2");
/* These encryption types are not yet supported
** The AES encryption method *
@@ -216,6 +219,12 @@ public enum LdapSecurityConstants
return HASH_METHOD_SSHA512;
}
+ if ( HASH_METHOD_PKCS5S2.getName().equalsIgnoreCase( algorithm )
+ || HASH_METHOD_PKCS5S2.getPrefix().equalsIgnoreCase( algorithm ) )
+ {
+ return HASH_METHOD_PKCS5S2;
+ }
+
/*
if ( ENC_METHOD_AES.getName().equalsIgnoreCase( algorithm ) )
{
Modified: directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/password/EncryptionMethod.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/password/EncryptionMethod.java?rev=1523919&r1=1523918&r2=1523919&view=diff
==============================================================================
--- directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/password/EncryptionMethod.java (original)
+++ directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/password/EncryptionMethod.java Tue Sep 17 06:15:42 2013
@@ -39,10 +39,10 @@ import org.apache.directory.api.util.Str
* {<algorithm>}<encrypted password>
* where the encrypted password format can be :
* - MD5/SHA : base64(<password>)
- * - SMD5/SSH : base64(<salted-password-digest><salt (4 or 8 bytes)>)
+ * - SMD5/SSH/PKCS5S2 : base64(<salted-password-digest><salt (4 or 8 bytes)>)
* - crypt : <salt (2 btytes)><password>
*
- * Algorithm are currently MD5, SMD5, SHA, SSHA, SHA2, SSHA-2 (except SHA-224), CRYPT and empty
+ * Algorithm are currently MD5, SMD5, SHA, SSHA, SHA2, SSHA-2 (except SHA-224), PKCS5S2, CRYPT and empty
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class EncryptionMethod
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=1523919&r1=1523918&r2=1523919&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 Tue Sep 17 06:15:42 2013
@@ -1,6 +1,6 @@
/*
- * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
+ * Licensed to the Apache Software Foundation (ASF) under one
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
@@ -22,12 +22,17 @@ package org.apache.directory.api.ldap.mo
import java.io.UnsupportedEncodingException;
+import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
+import java.security.spec.KeySpec;
import java.util.Arrays;
import java.util.Date;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+
import org.apache.directory.api.ldap.model.constants.LdapSecurityConstants;
import org.apache.directory.api.util.Base64;
import org.apache.directory.api.util.DateUtils;
@@ -58,6 +63,8 @@ public class PasswordUtil
/** The MD5 hash length */
public static final int MD5_LENGTH = 16;
+ /** The PKCS5S2 hash length */
+ public static final int PKCS5S2_LENGTH = 20;
/**
* Get the algorithm from the stored password.
@@ -142,6 +149,7 @@ public class PasswordUtil
case HASH_METHOD_SSHA384:
case HASH_METHOD_SSHA512:
case HASH_METHOD_SMD5:
+ case HASH_METHOD_PKCS5S2:
salt = new byte[8]; // we use 8 byte salt always except for "crypt" which needs 2 byte salt
new SecureRandom().nextBytes( salt );
break;
@@ -202,6 +210,7 @@ public class PasswordUtil
* <li>- SHA-2(256, 384 and 512 and their salted versions)</li>
* <li>- MD5</li>
* <li>- SMD5 (slated MD5)</li>
+ * <li>- PKCS5S2 (PBKDF2)</li>
* <li>- crypt (unix crypt)</li>
* <li>- plain text, ie no encryption.</li>
* </ul>
@@ -211,8 +220,9 @@ public class PasswordUtil
* </p>
* If the password is using SSHA, SMD5 or crypt, some 'salt' is added to the password :
* <ul>
- * <li>- length(password) - 20, starting at 21th position for SSHA</li>
+ * <li>- length(password) - 20, starting at 21st position for SSHA</li>
* <li>- length(password) - 16, starting at 16th position for SMD5</li>
+ * <li>- length(password) - 20, starting at 21st position for PKCS5S2</li>
* <li>- length(password) - 2, starting at 3rd position for crypt</li>
* </ul>
* <p>
@@ -303,6 +313,9 @@ public class PasswordUtil
return Strings.getBytesUtf8( crypted );
+ case HASH_METHOD_PKCS5S2:
+ return generatePbkdf2Hash( credentials, algorithm, salt );
+
default:
return credentials;
}
@@ -415,6 +428,9 @@ public class PasswordUtil
case HASH_METHOD_SSHA512:
return getCredentials( credentials, algoLength, SHA512_LENGTH, encryptionMethod );
+ case HASH_METHOD_PKCS5S2:
+ return getCredentials( credentials, algoLength, PKCS5S2_LENGTH, encryptionMethod );
+
case HASH_METHOD_CRYPT:
// The password is associated with a salt. Decompose it
// in two parts, storing the salt into the EncryptionMethod structure.
@@ -503,4 +519,30 @@ public class PasswordUtil
return expired;
}
+
+
+ /**
+ * generates a hash based on the <a href="http://en.wikipedia.org/wiki/PBKDF2">PKCS5S2 spec</a>
+ *
+ * @param algorithm the algorithm to use
+ * @param password the credentials
+ * @param salt the optional salt
+ * @return the digested credentials
+ */
+ private static byte[] generatePbkdf2Hash( byte[] credentials, LdapSecurityConstants algorithm, byte[] salt )
+ {
+ try
+ {
+ SecretKeyFactory sk = SecretKeyFactory.getInstance( algorithm.getAlgorithm() );
+ char[] password = Strings.utf8ToString( credentials ).toCharArray();
+ KeySpec keySpec = new PBEKeySpec( password, salt, 1000, 160 );
+ Key key = sk.generateSecret( keySpec );
+ return key.getEncoded();
+ }
+ catch( Exception e )
+ {
+ throw new RuntimeException( e );
+ }
+ }
+
}