svn commit: r950260 - /ofbiz/trunk/framework/base/src/org/ofbiz/base/crypto/HashCrypt.java

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r950260 - /ofbiz/trunk/framework/base/src/org/ofbiz/base/crypto/HashCrypt.java

doogie-3
Author: doogie
Date: Tue Jun  1 21:46:54 2010
New Revision: 950260

URL: http://svn.apache.org/viewvc?rev=950260&view=rev
Log:
Add unix(glibc)-compatible password hashing, exact same output, with
support for salts.

Modified:
    ofbiz/trunk/framework/base/src/org/ofbiz/base/crypto/HashCrypt.java

Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/crypto/HashCrypt.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/crypto/HashCrypt.java?rev=950260&r1=950259&r2=950260&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/org/ofbiz/base/crypto/HashCrypt.java (original)
+++ ofbiz/trunk/framework/base/src/org/ofbiz/base/crypto/HashCrypt.java Tue Jun  1 21:46:54 2010
@@ -18,9 +18,15 @@
  *******************************************************************************/
 package org.ofbiz.base.crypto;
 
+import java.io.UnsupportedEncodingException;
 import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Random;
 
+import org.apache.commons.codec.EncoderException;
+import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.codec.binary.Hex;
+import org.apache.commons.lang.RandomStringUtils;
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.GeneralRuntimeException;
 import org.ofbiz.base.util.StringUtil;
@@ -33,6 +39,66 @@ import org.ofbiz.base.util.UtilValidate;
 public class HashCrypt {
 
     public static final String module = HashCrypt.class.getName();
+    public static final String CRYPT_CHAR_SET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
+
+    public static boolean comparePassword(String crypted, String defaultCrypt, String password) {
+        try {
+            if (crypted.startsWith("{")) {
+                int typeEnd = crypted.indexOf("}");
+                String hashType = crypted.substring(1, typeEnd);
+                String hashed = crypted.substring(typeEnd + 1);
+                MessageDigest messagedigest = MessageDigest.getInstance(hashType);
+                // FIXME: should have been getBytes("UTF-8") originally
+                messagedigest.update(password.getBytes());
+                char[] digestChars = Hex.encodeHex(messagedigest.digest());
+                return hashed.equals(new String(digestChars));
+            } else if (crypted.startsWith("$")) {
+                int typeEnd = crypted.indexOf("$", 1);
+                int saltEnd = crypted.indexOf("$", typeEnd + 1);
+                String hashType = crypted.substring(1, typeEnd);
+                String salt = crypted.substring(typeEnd + 1, saltEnd);
+                String hashed = crypted.substring(saltEnd + 1);
+                MessageDigest messagedigest = MessageDigest.getInstance(hashType);
+                messagedigest.update(salt.getBytes("UTF-8"));
+                messagedigest.update(password.getBytes("UTF-8"));
+                return hashed.equals(Base64.encodeBase64String(messagedigest.digest()).replace('+', '.'));
+            } else {
+                String hashType = defaultCrypt;
+                String hashed = crypted;
+                MessageDigest messagedigest = MessageDigest.getInstance(hashType);
+                // FIXME: should have been getBytes("UTF-8") originally
+                messagedigest.update(password.getBytes());
+                char[] digestChars = Hex.encodeHex(messagedigest.digest());
+                return hashed.equals(new String(digestChars));
+            }
+        } catch (NoSuchAlgorithmException e) {
+            throw new GeneralRuntimeException("Error while comparing password", e);
+        } catch (UnsupportedEncodingException e) {
+            throw new GeneralRuntimeException("Error while comparing password", e);
+        }
+    }
+
+    public static String cryptPassword(String hashType, String password) {
+        Random random = new Random();
+        int saltLength = 8;//random.nextInt(15) + 1;
+        return cryptPassword(hashType, RandomStringUtils.random(saltLength, CRYPT_CHAR_SET), password);
+    }
+
+    public static String cryptPassword(String hashType, String salt, String password) {
+        try {
+            MessageDigest messagedigest = MessageDigest.getInstance(hashType);
+            messagedigest.update(salt.getBytes("UTF-8"));
+            messagedigest.update(password.getBytes("UTF-8"));
+            StringBuilder sb = new StringBuilder();
+            sb.append("$").append(hashType).append("$").append(salt).append("$");
+            sb.append(Base64.encodeBase64URLSafeString(messagedigest.digest()).replace('+', '.'));
+            return sb.toString();
+        } catch (NoSuchAlgorithmException e) {
+            throw new GeneralRuntimeException("Error while comparing password", e);
+        } catch (UnsupportedEncodingException e) {
+            throw new GeneralRuntimeException("Error while comparing password", e);
+        }
+    }
 
     public static String getDigestHash(String str) {
         return getDigestHash(str, "SHA");