Added additional Hasher implementations
- `BCRYPT`, `MD5`, `SHA1`, `SHA2`, - Also removed the support for bcrypt minor version y (i.e. $2y$) as it's not supported by our BCrypt implementation Original commit: elastic/x-pack-elasticsearch@12cf024a59
This commit is contained in:
parent
1224454714
commit
836540455a
|
@ -9,6 +9,7 @@ import org.apache.commons.codec.binary.Base64;
|
|||
import org.apache.commons.codec.digest.Crypt;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.codec.digest.Md5Crypt;
|
||||
import org.apache.commons.codec.digest.Sha2Crypt;
|
||||
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||
import org.elasticsearch.common.os.OsUtils;
|
||||
|
||||
|
@ -34,9 +35,6 @@ public enum Hasher {
|
|||
@Override
|
||||
public boolean verify(SecuredString text, char[] hash) {
|
||||
String hashStr = new String(hash);
|
||||
if (hashStr.startsWith(BCRYPT_PREFIX_Y)) {
|
||||
hashStr = BCRYPT_PREFIX + hashStr.substring(BCRYPT_PREFIX_Y.length());
|
||||
}
|
||||
if (hashStr.startsWith(BCRYPT_PREFIX)) {
|
||||
return BCrypt.checkpw(text, hashStr);
|
||||
}
|
||||
|
@ -52,16 +50,94 @@ public enum Hasher {
|
|||
String passwd64 = Base64.encodeBase64String(DigestUtils.sha1(textBytes));
|
||||
return hashStr.substring(SHA1_PREFIX.length()).compareTo(passwd64) == 0;
|
||||
}
|
||||
if (hashStr.startsWith(SHA2_PREFIX_5) || hashStr.startsWith(SHA2_PREFIX_6)) {
|
||||
return hashStr.compareTo(Sha2Crypt.sha256Crypt(textBytes, hashStr)) == 0;
|
||||
}
|
||||
return CRYPT_SUPPORTED ?
|
||||
hashStr.compareTo(Crypt.crypt(textBytes, hashStr)) == 0 : // crypt algo
|
||||
text.equals(hashStr); // plain text
|
||||
hashStr.compareTo(Crypt.crypt(textBytes, hashStr)) == 0 : // crypt algo
|
||||
text.equals(hashStr); // plain text
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
BCRYPT() {
|
||||
@Override
|
||||
public char[] hash(SecuredString text) {
|
||||
String salt = org.elasticsearch.shield.authc.support.BCrypt.gensalt();
|
||||
return BCrypt.hashpw(text, salt).toCharArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verify(SecuredString text, char[] hash) {
|
||||
String hashStr = new String(hash);
|
||||
if (!hashStr.startsWith(BCRYPT_PREFIX)) {
|
||||
return false;
|
||||
}
|
||||
return BCrypt.checkpw(text, hashStr);
|
||||
}
|
||||
},
|
||||
|
||||
MD5() {
|
||||
@Override
|
||||
public char[] hash(SecuredString text) {
|
||||
byte[] textBytes = CharArrays.toUtf8Bytes(text.internalChars());
|
||||
return Md5Crypt.apr1Crypt(textBytes).toCharArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verify(SecuredString text, char[] hash) {
|
||||
String hashStr = new String(hash);
|
||||
if (!hashStr.startsWith(APR1_PREFIX)) {
|
||||
return false;
|
||||
}
|
||||
byte[] textBytes = CharArrays.toUtf8Bytes(text.internalChars());
|
||||
return hashStr.compareTo(Md5Crypt.apr1Crypt(textBytes, hashStr)) == 0;
|
||||
}
|
||||
},
|
||||
|
||||
SHA1() {
|
||||
@Override
|
||||
public char[] hash(SecuredString text) {
|
||||
byte[] textBytes = CharArrays.toUtf8Bytes(text.internalChars());
|
||||
String hash = Base64.encodeBase64String(DigestUtils.sha1(textBytes));
|
||||
return (SHA1_PREFIX + hash).toCharArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verify(SecuredString text, char[] hash) {
|
||||
String hashStr = new String(hash);
|
||||
if (!hashStr.startsWith(SHA1_PREFIX)) {
|
||||
return false;
|
||||
}
|
||||
byte[] textBytes = CharArrays.toUtf8Bytes(text.internalChars());
|
||||
String passwd64 = Base64.encodeBase64String(DigestUtils.sha1(textBytes));
|
||||
return hashStr.substring(SHA1_PREFIX.length()).compareTo(passwd64) == 0;
|
||||
}
|
||||
},
|
||||
|
||||
SHA2() {
|
||||
@Override
|
||||
public char[] hash(SecuredString text) {
|
||||
byte[] textBytes = CharArrays.toUtf8Bytes(text.internalChars());
|
||||
return Sha2Crypt.sha256Crypt(textBytes).toCharArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verify(SecuredString text, char[] hash) {
|
||||
String hashStr = new String(hash);
|
||||
if (hashStr.startsWith(SHA2_PREFIX_5) || hashStr.startsWith(SHA2_PREFIX_6)) {
|
||||
byte[] textBytes = CharArrays.toUtf8Bytes(text.internalChars());
|
||||
return hashStr.compareTo(Sha2Crypt.sha256Crypt(textBytes, hashStr)) == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
private static final String APR1_PREFIX = "$apr1$";
|
||||
private static final String BCRYPT_PREFIX = "$2a$";
|
||||
private static final String BCRYPT_PREFIX_Y = "$2y$";
|
||||
private static final String SHA1_PREFIX = "{SHA}";
|
||||
private static final String SHA2_PREFIX_5 = "$5$";
|
||||
private static final String SHA2_PREFIX_6 = "$6$";
|
||||
private static final String PLAIN_PREFIX = "{plain}";
|
||||
static final boolean CRYPT_SUPPORTED = !OsUtils.WINDOWS;
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ public class FileUserPasswdStoreTests extends ElasticsearchTestCase {
|
|||
assertThat(users, notNullValue());
|
||||
assertThat(users.size(), is(6));
|
||||
assertThat(users.get("bcrypt"), notNullValue());
|
||||
assertThat(new String(users.get("bcrypt")), equalTo("$2y$05$zxnP0vdREMxnEpkLCDI2OuSaSk/QEKA2.A42iOpI6U2u.RLLOWm1e"));
|
||||
assertThat(new String(users.get("bcrypt")), equalTo("$2a$05$zxnP0vdREMxnEpkLCDI2OuSaSk/QEKA2.A42iOpI6U2u.RLLOWm1e"));
|
||||
assertThat(users.get("bcrypt10"), notNullValue());
|
||||
assertThat(new String(users.get("bcrypt10")), equalTo("$2y$10$FMhmFjwU5.qxQ/BsEciS9OqcJVkFMgXMo4uH5CelOR1j4N9zIv67e"));
|
||||
assertThat(users.get("md5"), notNullValue());
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
package org.elasticsearch.shield.authc.support;
|
||||
|
||||
import org.elasticsearch.common.os.OsUtils;
|
||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -15,11 +14,11 @@ import org.junit.Test;
|
|||
public class HasherTests extends ElasticsearchTestCase {
|
||||
|
||||
@Test
|
||||
public void testHtpasswdToolGenerated() throws Exception {
|
||||
public void testHtpasswd_ToolGenerated() throws Exception {
|
||||
Hasher hasher = Hasher.HTPASSWD;
|
||||
SecuredString passwd = SecuredStringTests.build("test123");
|
||||
assertTrue(hasher.verify(passwd, "$2a$05$zxnP0vdREMxnEpkLCDI2OuSaSk/QEKA2.A42iOpI6U2u.RLLOWm1e".toCharArray()));
|
||||
assertTrue(hasher.verify(passwd, "$2a$10$FMhmFjwU5.qxQ/BsEciS9OqcJVkFMgXMo4uH5CelOR1j4N9zIv67e".toCharArray()));
|
||||
assertTrue(hasher.verify(passwd, "$2a$10$vNMk6GyVUU./7YSZB6BGPuozm921GVPw/Pdukzd09s.sL2rIWROU6".toCharArray()));
|
||||
assertTrue(hasher.verify(passwd, "$apr1$R3DdqiAZ$aljIkaIVPSarmDMlJUBBP.".toCharArray()));
|
||||
if (!Hasher.CRYPT_SUPPORTED) {
|
||||
assertTrue(hasher.verify(passwd, "test123".toCharArray()));
|
||||
|
@ -28,12 +27,37 @@ public class HasherTests extends ElasticsearchTestCase {
|
|||
}
|
||||
assertTrue(hasher.verify(passwd, "{plain}test123".toCharArray()));
|
||||
assertTrue(hasher.verify(passwd, "{SHA}cojt0Pw//L6ToM8G41aOKFIWh7w=".toCharArray()));
|
||||
assertTrue(hasher.verify(passwd, "$5$RsqcsPiF$51tIIXf6oZb3Awox6FWNhITVlM/aW3oa8uN2eptIf54".toCharArray()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHtpasswdSelfGenerated() throws Exception {
|
||||
Hasher hasher = Hasher.HTPASSWD;
|
||||
public void testHtpasswd_SelfGenerated() throws Exception {
|
||||
testHasherSelfGenerated(Hasher.HTPASSWD);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBcrypt_SelfGenerated() throws Exception {
|
||||
testHasherSelfGenerated(Hasher.BCRYPT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMd5_SelfGenerated() throws Exception {
|
||||
testHasherSelfGenerated(Hasher.MD5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSha1_SelfGenerated() throws Exception {
|
||||
testHasherSelfGenerated(Hasher.SHA1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSha2_SelfGenerated() throws Exception {
|
||||
testHasherSelfGenerated(Hasher.SHA2);
|
||||
}
|
||||
|
||||
public void testHasherSelfGenerated(Hasher hasher) throws Exception {
|
||||
SecuredString passwd = SecuredStringTests.build("test123");
|
||||
assertTrue(hasher.verify(passwd, hasher.hash(passwd)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
bcrypt: $2y$05$zxnP0vdREMxnEpkLCDI2OuSaSk/QEKA2.A42iOpI6U2u.RLLOWm1e
|
||||
bcrypt: $2a$05$zxnP0vdREMxnEpkLCDI2OuSaSk/QEKA2.A42iOpI6U2u.RLLOWm1e
|
||||
md5: $apr1$R3DdqiAZ$aljIkaIVPSarmDMlJUBBP.
|
||||
crypt: hsP1PYSLsEEvs
|
||||
plain: {plain}test123
|
||||
|
|
Loading…
Reference in New Issue