[New] Added Crypt, to generate crypt like strings for salt and pw
This commit is contained in:
parent
d44da5b587
commit
e2aea114d3
|
@ -0,0 +1,9 @@
|
||||||
|
package li.strolch.privilege.base;
|
||||||
|
|
||||||
|
public class PrivilegeConstants {
|
||||||
|
|
||||||
|
public static final String DEFAULT_ALGORITHM = "PBKDF2WithHmacSHA512";
|
||||||
|
public static final int DEFAULT_KEY_LENGTH = 256;
|
||||||
|
public static final int DEFAULT_SMALL_ITERATIONS = 10000;
|
||||||
|
public static final int DEFAULT_ITERATIONS = 200000;
|
||||||
|
}
|
|
@ -15,6 +15,13 @@
|
||||||
*/
|
*/
|
||||||
package li.strolch.privilege.handler;
|
package li.strolch.privilege.handler;
|
||||||
|
|
||||||
|
import static li.strolch.privilege.base.PrivilegeConstants.DEFAULT_ALGORITHM;
|
||||||
|
import static li.strolch.privilege.base.PrivilegeConstants.DEFAULT_ITERATIONS;
|
||||||
|
import static li.strolch.privilege.base.PrivilegeConstants.DEFAULT_KEY_LENGTH;
|
||||||
|
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
import javax.crypto.SecretKeyFactory;
|
||||||
|
import javax.crypto.spec.PBEKeySpec;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
@ -22,16 +29,12 @@ import java.security.spec.InvalidKeySpecException;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.crypto.SecretKey;
|
|
||||||
import javax.crypto.SecretKeyFactory;
|
|
||||||
import javax.crypto.spec.PBEKeySpec;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import li.strolch.privilege.base.PrivilegeException;
|
import li.strolch.privilege.base.PrivilegeException;
|
||||||
|
import li.strolch.privilege.helper.Crypt;
|
||||||
import li.strolch.privilege.helper.XmlConstants;
|
import li.strolch.privilege.helper.XmlConstants;
|
||||||
import li.strolch.utils.helper.StringHelper;
|
import li.strolch.utils.helper.StringHelper;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -73,6 +76,26 @@ public class DefaultEncryptionHandler implements EncryptionHandler {
|
||||||
*/
|
*/
|
||||||
private int keyLength;
|
private int keyLength;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Crypt newCryptInstance() {
|
||||||
|
return new Crypt().setAlgorithm(this.algorithm).setIterations(this.iterations).setKeyLength(this.keyLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAlgorithm() {
|
||||||
|
return this.algorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIterations() {
|
||||||
|
return this.iterations;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getKeyLength() {
|
||||||
|
return this.keyLength;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String nextToken() {
|
public String nextToken() {
|
||||||
byte[] bytes = new byte[32];
|
byte[] bytes = new byte[32];
|
||||||
|
@ -94,8 +117,7 @@ public class DefaultEncryptionHandler implements EncryptionHandler {
|
||||||
SecretKeyFactory skf = SecretKeyFactory.getInstance(this.algorithm);
|
SecretKeyFactory skf = SecretKeyFactory.getInstance(this.algorithm);
|
||||||
PBEKeySpec spec = new PBEKeySpec(password, salt, this.iterations, this.keyLength);
|
PBEKeySpec spec = new PBEKeySpec(password, salt, this.iterations, this.keyLength);
|
||||||
SecretKey key = skf.generateSecret(spec);
|
SecretKey key = skf.generateSecret(spec);
|
||||||
byte[] res = key.getEncoded();
|
return key.getEncoded();
|
||||||
return res;
|
|
||||||
|
|
||||||
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
|
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
|
||||||
throw new IllegalStateException(e);
|
throw new IllegalStateException(e);
|
||||||
|
@ -108,14 +130,17 @@ public class DefaultEncryptionHandler implements EncryptionHandler {
|
||||||
this.secureRandom = new SecureRandom();
|
this.secureRandom = new SecureRandom();
|
||||||
|
|
||||||
// get hash algorithm parameters
|
// get hash algorithm parameters
|
||||||
this.algorithm = parameterMap.getOrDefault(XmlConstants.XML_PARAM_HASH_ALGORITHM, "PBKDF2WithHmacSHA512");
|
this.algorithm = parameterMap.getOrDefault(XmlConstants.XML_PARAM_HASH_ALGORITHM, DEFAULT_ALGORITHM);
|
||||||
this.iterations = Integer.parseInt(parameterMap.getOrDefault(XmlConstants.XML_PARAM_HASH_ITERATIONS, "200000"));
|
this.iterations = Integer.parseInt(
|
||||||
this.keyLength = Integer.parseInt(parameterMap.getOrDefault(XmlConstants.XML_PARAM_HASH_KEY_LENGTH, "256"));
|
parameterMap.getOrDefault(XmlConstants.XML_PARAM_HASH_ITERATIONS, String.valueOf(DEFAULT_ITERATIONS)));
|
||||||
|
this.keyLength = Integer.parseInt(
|
||||||
|
parameterMap.getOrDefault(XmlConstants.XML_PARAM_HASH_KEY_LENGTH, String.valueOf(DEFAULT_KEY_LENGTH)));
|
||||||
|
|
||||||
// test hash algorithm
|
// test hash algorithm
|
||||||
try {
|
try {
|
||||||
hashPassword("test".toCharArray(), "test".getBytes()); //$NON-NLS-1$
|
hashPassword("test".toCharArray(), "test".getBytes()); //$NON-NLS-1$
|
||||||
DefaultEncryptionHandler.logger.info(MessageFormat.format("Using hashing algorithm {0}", this.algorithm)); //$NON-NLS-1$
|
DefaultEncryptionHandler.logger
|
||||||
|
.info(MessageFormat.format("Using hashing algorithm {0}", this.algorithm)); //$NON-NLS-1$
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
String msg = "[{0}] Defined parameter {1} is invalid because of underlying exception: {2}"; //$NON-NLS-1$
|
String msg = "[{0}] Defined parameter {1} is invalid because of underlying exception: {2}"; //$NON-NLS-1$
|
||||||
msg = MessageFormat.format(msg, EncryptionHandler.class.getName(), XmlConstants.XML_PARAM_HASH_ALGORITHM,
|
msg = MessageFormat.format(msg, EncryptionHandler.class.getName(), XmlConstants.XML_PARAM_HASH_ALGORITHM,
|
||||||
|
|
|
@ -17,6 +17,8 @@ package li.strolch.privilege.handler;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import li.strolch.privilege.helper.Crypt;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link EncryptionHandler} exposes API which is used to handle encrypting of strings, or returning secure tokens
|
* The {@link EncryptionHandler} exposes API which is used to handle encrypting of strings, or returning secure tokens
|
||||||
* for certificates and so forth
|
* for certificates and so forth
|
||||||
|
@ -26,18 +28,46 @@ import java.util.Map;
|
||||||
public interface EncryptionHandler {
|
public interface EncryptionHandler {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a token which can be used to identify certificates and so forth
|
* Returns a new crypt instance
|
||||||
*
|
*
|
||||||
* @return a new token
|
* @return a new crypt instance
|
||||||
*/
|
*/
|
||||||
public String nextToken();
|
Crypt newCryptInstance();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the configured algorithm
|
||||||
|
*
|
||||||
|
* @return the configured algorithm
|
||||||
|
*/
|
||||||
|
String getAlgorithm();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the configured iterations
|
||||||
|
*
|
||||||
|
* @return the configured iterations
|
||||||
|
*/
|
||||||
|
int getIterations();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the configured key length
|
||||||
|
*
|
||||||
|
* @return the configured key length
|
||||||
|
*/
|
||||||
|
int getKeyLength();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a token which can be used to identify certificates and so forth
|
* Generates a token which can be used to identify certificates and so forth
|
||||||
*
|
*
|
||||||
* @return a new token
|
* @return a new token
|
||||||
*/
|
*/
|
||||||
public byte[] nextSalt();
|
String nextToken();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a token which can be used to identify certificates and so forth
|
||||||
|
*
|
||||||
|
* @return a new token
|
||||||
|
*/
|
||||||
|
byte[] nextSalt();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hashes the given password with the given salt with the configured algorithm
|
* Hashes the given password with the given salt with the configured algorithm
|
||||||
|
@ -49,7 +79,7 @@ public interface EncryptionHandler {
|
||||||
*
|
*
|
||||||
* @return the hashed password
|
* @return the hashed password
|
||||||
*/
|
*/
|
||||||
public byte[] hashPassword(final char[] password, final byte[] salt);
|
byte[] hashPassword(final char[] password, final byte[] salt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the concrete {@link EncryptionHandler}. The passed parameter map contains any configuration the
|
* Initialize the concrete {@link EncryptionHandler}. The passed parameter map contains any configuration the
|
||||||
|
@ -58,5 +88,5 @@ public interface EncryptionHandler {
|
||||||
* @param parameterMap
|
* @param parameterMap
|
||||||
* a map containing configuration properties
|
* a map containing configuration properties
|
||||||
*/
|
*/
|
||||||
public void initialize(Map<String, String> parameterMap);
|
void initialize(Map<String, String> parameterMap);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,226 @@
|
||||||
|
package li.strolch.privilege.helper;
|
||||||
|
|
||||||
|
import static li.strolch.privilege.base.PrivilegeConstants.DEFAULT_SMALL_ITERATIONS;
|
||||||
|
import static li.strolch.utils.helper.StringHelper.fromHexString;
|
||||||
|
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
import javax.crypto.SecretKeyFactory;
|
||||||
|
import javax.crypto.spec.PBEKeySpec;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import li.strolch.utils.dbc.DBC;
|
||||||
|
import li.strolch.utils.helper.StringHelper;
|
||||||
|
|
||||||
|
public class Crypt {
|
||||||
|
|
||||||
|
private String algorithm;
|
||||||
|
private int keyLength;
|
||||||
|
private int iterations;
|
||||||
|
private byte[] salt;
|
||||||
|
private byte[] password;
|
||||||
|
|
||||||
|
public Crypt() {
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAlgorithm() {
|
||||||
|
return algorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Crypt setAlgorithm(String algorithm) {
|
||||||
|
this.algorithm = algorithm;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getSalt() {
|
||||||
|
return salt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Crypt setSalt(byte[] salt) {
|
||||||
|
this.salt = salt;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getKeyLength() {
|
||||||
|
return this.keyLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Crypt setKeyLength(int keyLength) {
|
||||||
|
this.keyLength = keyLength;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIterations() {
|
||||||
|
return this.iterations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Crypt setIterations(int iterations) {
|
||||||
|
this.iterations = iterations;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Crypt setPassword(byte[] password) {
|
||||||
|
this.password = password;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Crypt parseCrypt(String crypt) {
|
||||||
|
DBC.PRE.assertNotEmpty("crypt can no be empty", crypt);
|
||||||
|
|
||||||
|
if (crypt.contains("$")) {
|
||||||
|
String[] parts = crypt.split("\\$");
|
||||||
|
|
||||||
|
if (parts.length == 5) {
|
||||||
|
|
||||||
|
setAlgorithm(parts[1], true);
|
||||||
|
|
||||||
|
Map<String, String> algOptions = parseAlgOptions(parts[2]);
|
||||||
|
if (algOptions == null)
|
||||||
|
this.iterations = DEFAULT_SMALL_ITERATIONS;
|
||||||
|
else
|
||||||
|
this.iterations = Integer.parseInt(algOptions.get("rounds"));
|
||||||
|
|
||||||
|
this.salt = fromHexString(parts[3]);
|
||||||
|
this.password = fromHexString(parts[4]);
|
||||||
|
|
||||||
|
} else if (parts.length == 4) {
|
||||||
|
|
||||||
|
setAlgorithm(parts[1], true);
|
||||||
|
this.iterations = DEFAULT_SMALL_ITERATIONS;
|
||||||
|
this.salt = fromHexString(parts[2]);
|
||||||
|
this.password = fromHexString(parts[3]);
|
||||||
|
|
||||||
|
} else if (parts.length == 3) {
|
||||||
|
|
||||||
|
setAlgorithm(parts[1], false);
|
||||||
|
this.password = fromHexString(parts[2]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Wrong number of $ chars in " + crypt + ": " + parts.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
this.algorithm = "SHA-512";
|
||||||
|
this.password = fromHexString(crypt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assertSame(char[] password) {
|
||||||
|
if (!isSame(password))
|
||||||
|
throw new IllegalStateException("Passwords not the same");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSame(char[] password) {
|
||||||
|
if (this.password == null)
|
||||||
|
throw new IllegalStateException("password not set, call parseCrypt() first!");
|
||||||
|
if (password == null)
|
||||||
|
throw new IllegalStateException("password must not be null");
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
byte[] hash;
|
||||||
|
if (this.salt == null) {
|
||||||
|
|
||||||
|
hash = StringHelper.hash(this.algorithm, new String(password).getBytes());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
PBEKeySpec spec = new PBEKeySpec(password, this.salt, this.iterations, this.keyLength);
|
||||||
|
SecretKeyFactory skf = SecretKeyFactory.getInstance(this.algorithm);
|
||||||
|
SecretKey key = skf.generateSecret(spec);
|
||||||
|
hash = key.getEncoded();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Arrays.equals(hash, this.password);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalStateException("Failed validation password for algorithm " + this.algorithm, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toCryptString() {
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
sb.append("$");
|
||||||
|
switch (this.algorithm) {
|
||||||
|
case "MD5":
|
||||||
|
sb.append("1");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "PBKDF2WithHmacSHA256":
|
||||||
|
case "SHA-256":
|
||||||
|
sb.append("5");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "PBKDF2WithHmacSHA512":
|
||||||
|
case "SHA-512":
|
||||||
|
sb.append("6");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Unhandled algorithm " + this.algorithm);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.iterations != 0 && this.iterations != DEFAULT_SMALL_ITERATIONS) {
|
||||||
|
sb.append("$");
|
||||||
|
sb.append("rounds");
|
||||||
|
sb.append("=");
|
||||||
|
sb.append(iterations);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.salt != null) {
|
||||||
|
sb.append("$");
|
||||||
|
sb.append(StringHelper.toHexString(this.salt));
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append("$");
|
||||||
|
sb.append(StringHelper.toHexString(this.password));
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> parseAlgOptions(String part) {
|
||||||
|
String[] options = part.split(",");
|
||||||
|
Map<String, String> algOptions = new HashMap<>(options.length);
|
||||||
|
for (String option : options) {
|
||||||
|
if (option.trim().isEmpty())
|
||||||
|
continue;
|
||||||
|
if (!option.contains("="))
|
||||||
|
throw new IllegalStateException("Option " + option + " is missing = char");
|
||||||
|
String[] keyValue = option.split("=");
|
||||||
|
algOptions.put(keyValue[0].trim(), keyValue[1].trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
return algOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setAlgorithm(String id, boolean hasSalt) {
|
||||||
|
switch (id) {
|
||||||
|
case "1":
|
||||||
|
this.algorithm = "MD5";
|
||||||
|
this.keyLength = 0;
|
||||||
|
break;
|
||||||
|
case "5":
|
||||||
|
this.algorithm = hasSalt ? "PBKDF2WithHmacSHA256" : "SHA-256";
|
||||||
|
this.keyLength = 256;
|
||||||
|
break;
|
||||||
|
case "6":
|
||||||
|
this.algorithm = hasSalt ? "PBKDF2WithHmacSHA512" : "SHA-512";
|
||||||
|
this.keyLength = 256;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Unhandled ID " + id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,13 +15,16 @@
|
||||||
*/
|
*/
|
||||||
package li.strolch.privilege.helper;
|
package li.strolch.privilege.helper;
|
||||||
|
|
||||||
|
import static li.strolch.privilege.base.PrivilegeConstants.DEFAULT_ALGORITHM;
|
||||||
|
import static li.strolch.privilege.base.PrivilegeConstants.DEFAULT_SMALL_ITERATIONS;
|
||||||
|
import static li.strolch.privilege.base.PrivilegeConstants.DEFAULT_KEY_LENGTH;
|
||||||
|
|
||||||
|
import javax.crypto.SecretKeyFactory;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.crypto.SecretKeyFactory;
|
|
||||||
|
|
||||||
import li.strolch.privilege.handler.DefaultEncryptionHandler;
|
import li.strolch.privilege.handler.DefaultEncryptionHandler;
|
||||||
import li.strolch.utils.helper.StringHelper;
|
import li.strolch.utils.helper.StringHelper;
|
||||||
|
|
||||||
|
@ -37,6 +40,7 @@ public class PasswordCreator {
|
||||||
/**
|
/**
|
||||||
* @param args
|
* @param args
|
||||||
* the args from the command line, NOT USED
|
* the args from the command line, NOT USED
|
||||||
|
*
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* thrown if anything goes wrong
|
* thrown if anything goes wrong
|
||||||
*/
|
*/
|
||||||
|
@ -49,11 +53,11 @@ public class PasswordCreator {
|
||||||
|
|
||||||
String hashAlgorithm = null;
|
String hashAlgorithm = null;
|
||||||
while (hashAlgorithm == null) {
|
while (hashAlgorithm == null) {
|
||||||
System.out.print("Hash Algorithm [PBKDF2WithHmacSHA512]: ");
|
System.out.print("Hash Algorithm [" + DEFAULT_ALGORITHM + "]: ");
|
||||||
String readLine = r.readLine().trim();
|
String readLine = r.readLine().trim();
|
||||||
|
|
||||||
if (readLine.isEmpty()) {
|
if (readLine.isEmpty()) {
|
||||||
hashAlgorithm = "PBKDF2WithHmacSHA512";
|
hashAlgorithm = DEFAULT_ALGORITHM;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -68,11 +72,11 @@ public class PasswordCreator {
|
||||||
|
|
||||||
int iterations = -1;
|
int iterations = -1;
|
||||||
while (iterations == -1) {
|
while (iterations == -1) {
|
||||||
System.out.print("Hash iterations [10000]: ");
|
System.out.print("Hash iterations [" + DEFAULT_SMALL_ITERATIONS + "]: ");
|
||||||
String readLine = r.readLine().trim();
|
String readLine = r.readLine().trim();
|
||||||
|
|
||||||
if (readLine.isEmpty()) {
|
if (readLine.isEmpty()) {
|
||||||
iterations = 10000;
|
iterations = DEFAULT_SMALL_ITERATIONS;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -86,11 +90,11 @@ public class PasswordCreator {
|
||||||
|
|
||||||
int keyLength = -1;
|
int keyLength = -1;
|
||||||
while (keyLength == -1) {
|
while (keyLength == -1) {
|
||||||
System.out.print("Hash keyLength [256]: ");
|
System.out.print("Hash keyLength [" + DEFAULT_KEY_LENGTH + "]: ");
|
||||||
String readLine = r.readLine().trim();
|
String readLine = r.readLine().trim();
|
||||||
|
|
||||||
if (readLine.isEmpty()) {
|
if (readLine.isEmpty()) {
|
||||||
keyLength = 256;
|
keyLength = DEFAULT_KEY_LENGTH;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -98,6 +102,7 @@ public class PasswordCreator {
|
||||||
if (keyLength <= 0)
|
if (keyLength <= 0)
|
||||||
throw new IllegalArgumentException("KeyLength must be > 0");
|
throw new IllegalArgumentException("KeyLength must be > 0");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
System.err.println(e.getLocalizedMessage());
|
||||||
System.err.println(e.getLocalizedMessage());
|
System.err.println(e.getLocalizedMessage());
|
||||||
keyLength = -1;
|
keyLength = -1;
|
||||||
}
|
}
|
||||||
|
@ -128,8 +133,9 @@ public class PasswordCreator {
|
||||||
System.out.println("Salt is: " + saltS);
|
System.out.println("Salt is: " + saltS);
|
||||||
System.out.println();
|
System.out.println();
|
||||||
|
|
||||||
System.out.println(XmlConstants.XML_ATTR_PASSWORD + "=\"" + passwordHashS + "\" "
|
System.out.println(
|
||||||
+ XmlConstants.XML_ATTR_SALT + "=\"" + saltS + "\"");
|
XmlConstants.XML_ATTR_PASSWORD + "=\"" + passwordHashS + "\" " + XmlConstants.XML_ATTR_SALT + "=\""
|
||||||
|
+ saltS + "\"");
|
||||||
System.out.println();
|
System.out.println();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
package li.strolch.privilege.test;
|
||||||
|
|
||||||
|
import static li.strolch.privilege.base.PrivilegeConstants.*;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import li.strolch.privilege.handler.DefaultEncryptionHandler;
|
||||||
|
import li.strolch.privilege.helper.Crypt;
|
||||||
|
import li.strolch.privilege.helper.XmlConstants;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class CryptTest {
|
||||||
|
|
||||||
|
private static DefaultEncryptionHandler encryptionHandler;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() {
|
||||||
|
Map<String, String> parameterMap = new HashMap<>();
|
||||||
|
parameterMap.put(XmlConstants.XML_PARAM_HASH_ALGORITHM, DEFAULT_ALGORITHM);
|
||||||
|
parameterMap.put(XmlConstants.XML_PARAM_HASH_ITERATIONS, "" + DEFAULT_SMALL_ITERATIONS);
|
||||||
|
parameterMap.put(XmlConstants.XML_PARAM_HASH_KEY_LENGTH, "" + DEFAULT_KEY_LENGTH);
|
||||||
|
|
||||||
|
encryptionHandler = new DefaultEncryptionHandler();
|
||||||
|
encryptionHandler.initialize(parameterMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldAssertSamePassword01() {
|
||||||
|
|
||||||
|
String hash = "$1$21232f297a57a5a743894a0e4a801fc3";
|
||||||
|
char[] password = "admin".toCharArray();
|
||||||
|
|
||||||
|
Crypt crypt = new Crypt().parseCrypt(hash);
|
||||||
|
crypt.assertSame(password);
|
||||||
|
assertEquals(hash, crypt.toCryptString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldAssertSamePassword05() {
|
||||||
|
|
||||||
|
String hash = "$5$8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918";
|
||||||
|
char[] password = "admin".toCharArray();
|
||||||
|
|
||||||
|
Crypt crypt = new Crypt().parseCrypt(hash);
|
||||||
|
crypt.assertSame(password);
|
||||||
|
assertEquals(hash, crypt.toCryptString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldAssertSamePassword06() {
|
||||||
|
|
||||||
|
String hash = "$6$c7ad44cbad762a5da0a452f9e854fdc1e0e7a52a38015f23f3eab1d80b931dd472634dfac71cd34ebc35d16ab7fb8a90c81f975113d6c7538dc69dd8de9077ec";
|
||||||
|
char[] password = "admin".toCharArray();
|
||||||
|
|
||||||
|
Crypt crypt = new Crypt().parseCrypt(hash);
|
||||||
|
crypt.assertSame(password);
|
||||||
|
assertEquals(hash, crypt.toCryptString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldAssertSamePassword15() {
|
||||||
|
|
||||||
|
String hash = "$5$61646d696e$f4aec2c20dd0c3ff0547f4bd56facd76097cce7c613da80c67842b6a357fdc04";
|
||||||
|
char[] password = "admin".toCharArray();
|
||||||
|
|
||||||
|
Crypt crypt = new Crypt().parseCrypt(hash);
|
||||||
|
crypt.assertSame(password);
|
||||||
|
assertEquals(hash, crypt.toCryptString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldAssertSamePassword16() {
|
||||||
|
|
||||||
|
String hash = "$6$rounds=5000$61646d696e$5a39ca7443147f9bf549ee0c2d5ded0640690ed56ef8c903e1b0da2a3339010b";
|
||||||
|
char[] password = "admin".toCharArray();
|
||||||
|
|
||||||
|
Crypt crypt = new Crypt().parseCrypt(hash);
|
||||||
|
crypt.assertSame(password);
|
||||||
|
assertEquals(hash, crypt.toCryptString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldAssertSamePassword20() {
|
||||||
|
|
||||||
|
char[] password = "admin".toCharArray();
|
||||||
|
|
||||||
|
byte[] salt = "admin".getBytes();
|
||||||
|
byte[] passwordHash = encryptionHandler.hashPassword(password, salt);
|
||||||
|
|
||||||
|
Crypt crypt = encryptionHandler.newCryptInstance();
|
||||||
|
crypt.setSalt(salt);
|
||||||
|
crypt.setPassword(passwordHash);
|
||||||
|
|
||||||
|
String hash = "$6$61646d696e$cb69962946617da006a2f95776d78b49e5ec7941d2bdb2d25cdb05f957f64344";
|
||||||
|
assertEquals(hash, crypt.toCryptString());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue