Improved: LoginWorker HashCrypt the type of hash for one-way encryption
(OFBIZ-8537)
Committed wangjunyuan's new patch.
Thanks: wangjunyuan for the new patch to make the PBKDF2 hashed password comply with RFC 6070, the feedbacks of Jacques and Nicolas on the previous patch.
git-svn-id: https://svn.apache.org/repos/asf/ofbiz/trunk@1773066 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/base/src/main/java/org/apache/ofbiz/base/crypto/HashCrypt.java b/framework/base/src/main/java/org/apache/ofbiz/base/crypto/HashCrypt.java
index 1e0d29d..8c66937 100644
--- a/framework/base/src/main/java/org/apache/ofbiz/base/crypto/HashCrypt.java
+++ b/framework/base/src/main/java/org/apache/ofbiz/base/crypto/HashCrypt.java
@@ -46,15 +46,11 @@
public static final String module = HashCrypt.class.getName();
public static final String CRYPT_CHAR_SET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
- private static final String PBKDF2_SHA1 ="pbkdf2_sha1";
-
- private static final String PBKDF2_SHA256 ="pbkdf2_sha256";
-
- private static final String PBKDF2_SHA384 ="pbkdf2_sha384";
-
- private static final String PBKDF2_SHA512 ="pbkdf2_sha512";
-
- private static final int PBKDF2_ITERATIONS = UtilProperties.getPropertyAsInteger("security.properties", "password.encrypt.pbkdf2.iterations", 1000);
+ private static final String PBKDF2_SHA1 ="PBKDF2-SHA1";
+ private static final String PBKDF2_SHA256 ="PBKDF2-SHA256";
+ private static final String PBKDF2_SHA384 ="PBKDF2-SHA384";
+ private static final String PBKDF2_SHA512 ="PBKDF2-SHA512";
+ private static final int PBKDF2_ITERATIONS = UtilProperties.getPropertyAsInteger("security.properties", "password.encrypt.pbkdf2.iterations", 10000);
public static MessageDigest getMessageDigest(String type) {
try {
@@ -65,13 +61,13 @@
}
public static boolean comparePassword(String crypted, String defaultCrypt, String password) {
- if (crypted.startsWith("{")) {
+ if (crypted.startsWith("{PBKDF2")) {
+ return doComparePbkdf2(crypted, password);
+ } else if (crypted.startsWith("{")) {
// FIXME: should have been getBytes("UTF-8") originally
return doCompareTypePrefix(crypted, defaultCrypt, password.getBytes());
} else if (crypted.startsWith("$")) {
return doComparePosix(crypted, defaultCrypt, password.getBytes(UtilIO.getUtf8()));
- } else if (crypted.startsWith("pbkdf2")) {
- return doComparePbkdf2(crypted, password);
} else {
// FIXME: should have been getBytes("UTF-8") originally
return doCompareBare(crypted, defaultCrypt, password.getBytes());
@@ -194,7 +190,12 @@
default:
pbkdf2Type = PBKDF2_SHA1;
}
- return pbkdf2Type + "$" + PBKDF2_ITERATIONS + "$" + salt + "$" + new String(hash);
+ StringBuilder sb = new StringBuilder();
+ sb.append("{").append(pbkdf2Type).append("}");
+ sb.append(PBKDF2_ITERATIONS).append("$");
+ sb.append(org.apache.ofbiz.base.util.Base64.base64Encode(salt)).append("$");
+ sb.append(new String(hash)).toString();
+ return sb.toString();
} catch (InvalidKeySpecException e) {
throw new GeneralRuntimeException("Error while creating SecretKey", e);
} catch (NoSuchAlgorithmException e) {
@@ -202,24 +203,24 @@
}
}
- public static boolean doComparePbkdf2(String storedPassword, String originalPassword){
+ public static boolean doComparePbkdf2(String crypted, String password){
try {
- String[] parts = storedPassword.split("\\$");
- String hashHead = parts[0];
- int iterations = Integer.parseInt(parts[1]);
- byte[] salt = parts[2].getBytes();
- byte[] hash = Base64.decodeBase64(parts[3].getBytes());
+ int typeEnd = crypted.indexOf("}");
+ String hashType = crypted.substring(1, typeEnd);
+ String[] parts = crypted.split("\\$");
+ int iterations = Integer.parseInt(parts[0].substring(typeEnd+1));
+ byte[] salt = org.apache.ofbiz.base.util.Base64.base64Decode(parts[1]).getBytes();
+ byte[] hash = Base64.decodeBase64(parts[2].getBytes());
- PBEKeySpec spec = new PBEKeySpec(originalPassword.toCharArray(), salt, iterations, hash.length * 8);
- String hashType = null;
- switch (hashHead.substring(hashHead.indexOf("_")+4)) {
- case "256":
+ PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterations, hash.length * 8);
+ switch (hashType.substring(hashType.indexOf("-")+1)) {
+ case "SHA256":
hashType = "PBKDF2WithHmacSHA256";
break;
- case "384":
+ case "SHA384":
hashType = "PBKDF2WithHmacSHA384";
break;
- case "512":
+ case "SHA512":
hashType = "PBKDF2WithHmacSHA512";
break;
default:
diff --git a/framework/security/config/security.properties b/framework/security/config/security.properties
index 1fe9452..d7cdac4 100644
--- a/framework/security/config/security.properties
+++ b/framework/security/config/security.properties
@@ -87,7 +87,7 @@
# -- if the type of hash to use for one-way encryption is PBKDF2WithHmacSHA1 or PBKDF2WithHmacSHA256 or PBKDF2WithHmacSHA384 or PBKDF2WithHmacSHA512
# -- the type of hash to use for one-way encryption needs iteration
-password.encrypt.pbkdf2.iterations=1000
+password.encrypt.pbkdf2.iterations=10000
# -- this is helpful to recover old accounts or to be able to login at all sometimes --
# -- SHOULD GENERALLY NOT BE TRUE FOR PRODUCTION SITES, but is useful for interim periods when going to password encryption --
diff --git a/framework/security/data/PasswordSecurityDemoData.xml b/framework/security/data/PasswordSecurityDemoData.xml
index f7b6621..a575c8b 100644
--- a/framework/security/data/PasswordSecurityDemoData.xml
+++ b/framework/security/data/PasswordSecurityDemoData.xml
@@ -21,6 +21,15 @@
<entity-engine-xml>
<!-- from the securityext component: SecurityExtData.xml -->
<UserLogin userLoginId="admin" currentPassword="{SHA}47b56994cbc2b6d10aa1be30f70165adb305a41a" passwordHint=""/>
+ <!-- PBKDF2-SHA1
+ <UserLogin userLoginId="flexadmin" currentPassword="{PBKDF2-SHA1}10000$W0JAMTY4ZTNlZjA=$HkbaHQBTdUbfDuL3tJ1eeyqouQ+66qqIj8Axx9vbHPQ=" passwordHint=""/>
+ PBKDF2-SHA256
+ <UserLogin userLoginId="flexadmin" currentPassword="{PBKDF2-SHA256}10000$W0JAMTRjMzI4YmE=$vWXmPPjyVlvPjN/7v7heWXRPW5ZBWEQTeYv/vxDT5L8=" passwordHint=""/>
+ PBKDF2-SHA384
+ <UserLogin userLoginId="flexadmin" currentPassword="{PBKDF2-SHA384}10000$W0JANWVhMDNjYzE=$H+ouAKild4PCvzFaBxZDbsH2kU1yGJFoCofklWa7YZE=" passwordHint=""/>
+ PBKDF2-SHA512
+ <UserLogin userLoginId="flexadmin" currentPassword="{PBKDF2-SHA512}10000$W0JANTAwZGIwZDY=$M1ZJMdOEjE8bo5E7s5qfza6SZ3dVKwIiwZ8LyKL+2ns=" passwordHint=""/>
+ -->
<UserLogin userLoginId="flexadmin" currentPassword="{SHA}47b56994cbc2b6d10aa1be30f70165adb305a41a" passwordHint=""/>
<UserLogin userLoginId="demoadmin" currentPassword="{SHA}47b56994cbc2b6d10aa1be30f70165adb305a41a" passwordHint=""/>
<UserLogin userLoginId="ltdadmin" currentPassword="{SHA}47b56994cbc2b6d10aa1be30f70165adb305a41a" passwordHint=""/>