|
Author: doogie
Date: Wed Apr 18 23:49:10 2012 New Revision: 1327740 URL: http://svn.apache.org/viewvc?rev=1327740&view=rev Log: FEATURE: 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=1327740&r1=1327739&r2=1327740&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 Wed Apr 18 23:49:10 2012 @@ -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,84 @@ 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()); + byte[] digestBytes = messagedigest.digest(); + char[] digestChars = Hex.encodeHex(digestBytes); + if (hashed.equals(new String(digestChars))) { + return true; + } + // This next block should be removed when all {prefix}oldFunnyHex are fixed. + int k = 0; + digestChars = new char[digestBytes.length * 2]; + for (int l = 0; l < digestBytes.length; l++) { + int i1 = digestBytes[l]; + + if (i1 < 0) { + i1 = 127 + i1 * -1; + } + StringUtil.encodeInt(i1, k, digestChars); + k += 2; + } + if (hashed.equals(new String(digestChars))) { + Debug.logWarning("Warning: detected oldFunnyHex password prefixed with a hashType; this is not valid", module); + return true; + } + return false; + } 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); + return hashed.equals(getCrypted(hashType, salt, password)); + } 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); + } + } + + public static String cryptPassword(String hashType, String password) { + int saltLength = new Random().nextInt(15) + 1; + return cryptPassword(hashType, RandomStringUtils.random(saltLength, CRYPT_CHAR_SET), password); + } + + public static String cryptPassword(String hashType, String salt, String password) { + StringBuilder sb = new StringBuilder(); + sb.append("$").append(hashType).append("$").append(salt).append("$"); + sb.append(getCrypted(hashType, salt, password)); + return sb.toString(); + } + + private static String getCrypted(String hashType, String salt, String password) { + try { + MessageDigest messagedigest = MessageDigest.getInstance(hashType); + messagedigest.update(salt.getBytes("UTF-8")); + messagedigest.update(password.getBytes("UTF-8")); + return Base64.encodeBase64URLSafeString(messagedigest.digest()).replace('+', '.'); + } 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"); |
| Free forum by Nabble | Edit this page |
