mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-02-06 14:49:11 +01:00
added more options to HashBuilder and added extractor method
This commit is contained in:
@@ -39,6 +39,14 @@ package sonia.scm.security;
|
||||
public interface HashBuilder
|
||||
{
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public HashBuilder appendSalt();
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
@@ -57,6 +65,14 @@ public interface HashBuilder
|
||||
*/
|
||||
public HashBuilder createSalt(int length);
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public HashBuilder enableLabel();
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
|
||||
@@ -49,7 +49,7 @@ public class MD5HashBuilder extends MessageDigestHashBuilder
|
||||
*/
|
||||
public MD5HashBuilder()
|
||||
{
|
||||
super(DIGEST, null, null, 0);
|
||||
super(DIGEST, null, null, 0, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,7 +60,7 @@ public class MD5HashBuilder extends MessageDigestHashBuilder
|
||||
*/
|
||||
public MD5HashBuilder(String value)
|
||||
{
|
||||
super(DIGEST, value, null, 0);
|
||||
super(DIGEST, value, null, 0, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,7 +72,7 @@ public class MD5HashBuilder extends MessageDigestHashBuilder
|
||||
*/
|
||||
public MD5HashBuilder(String value, byte[] salt)
|
||||
{
|
||||
super(DIGEST, value, salt, 0);
|
||||
super(DIGEST, value, salt, 0, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,6 +85,37 @@ public class MD5HashBuilder extends MessageDigestHashBuilder
|
||||
*/
|
||||
public MD5HashBuilder(String value, byte[] salt, int iterations)
|
||||
{
|
||||
super(DIGEST, value, salt, iterations);
|
||||
super(DIGEST, value, salt, iterations, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param value
|
||||
* @param salt
|
||||
* @param iterations
|
||||
* @param appendSalt
|
||||
*/
|
||||
public MD5HashBuilder(String value, byte[] salt, int iterations,
|
||||
boolean appendSalt)
|
||||
{
|
||||
super(DIGEST, value, salt, iterations, appendSalt, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param value
|
||||
* @param salt
|
||||
* @param iterations
|
||||
* @param appendSalt
|
||||
* @param enableLabel
|
||||
*/
|
||||
public MD5HashBuilder(String value, byte[] salt, int iterations,
|
||||
boolean appendSalt, boolean enableLabel)
|
||||
{
|
||||
super(DIGEST, value, salt, iterations, appendSalt, enableLabel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,9 @@ import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
@@ -60,6 +63,9 @@ public class MessageDigestHashBuilder implements HashBuilder
|
||||
/** Field description */
|
||||
public static final String RANDOM_INSTANCE = "SHA1PRNG";
|
||||
|
||||
/** Field description */
|
||||
private static Pattern PATTERN = Pattern.compile("\\{([^\\}]+)\\}(.*)");
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -70,18 +76,50 @@ public class MessageDigestHashBuilder implements HashBuilder
|
||||
* @param value
|
||||
* @param salt
|
||||
* @param iterations
|
||||
* @param appendSalt
|
||||
* @param enableLabel
|
||||
*/
|
||||
public MessageDigestHashBuilder(String digest, String value, byte[] salt,
|
||||
int iterations)
|
||||
int iterations, boolean appendSalt,
|
||||
boolean enableLabel)
|
||||
{
|
||||
this.digest = digest;
|
||||
this.value = value;
|
||||
this.salt = salt;
|
||||
this.iterations = iterations;
|
||||
this.appendSalt = appendSalt;
|
||||
this.enableLable = enableLabel;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param hash
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Extractor createExtractor(String hash)
|
||||
{
|
||||
return new Extractor(hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public HashBuilder appendSalt()
|
||||
{
|
||||
this.appendSalt = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
@@ -120,6 +158,20 @@ public class MessageDigestHashBuilder implements HashBuilder
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public HashBuilder enableLabel()
|
||||
{
|
||||
this.enableLable = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
@@ -152,6 +204,15 @@ public class MessageDigestHashBuilder implements HashBuilder
|
||||
input = md.digest(input);
|
||||
}
|
||||
}
|
||||
|
||||
if ((salt != null) && appendSalt)
|
||||
{
|
||||
byte[] content = new byte[input.length + salt.length];
|
||||
|
||||
System.arraycopy(input, 0, content, 0, input.length);
|
||||
System.arraycopy(salt, 0, content, input.length, salt.length);
|
||||
input = content;
|
||||
}
|
||||
}
|
||||
catch (UnsupportedEncodingException ex)
|
||||
{
|
||||
@@ -174,7 +235,22 @@ public class MessageDigestHashBuilder implements HashBuilder
|
||||
@Override
|
||||
public String toHexString()
|
||||
{
|
||||
return Util.toString(toByteArray());
|
||||
String hexString = null;
|
||||
|
||||
if (enableLable)
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
|
||||
buffer.append("{").append(digest).append("}");
|
||||
buffer.append(Util.toString(toByteArray()));
|
||||
hexString = buffer.toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
hexString = Util.toString(toByteArray());
|
||||
}
|
||||
|
||||
return hexString;
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
@@ -260,11 +336,155 @@ public class MessageDigestHashBuilder implements HashBuilder
|
||||
return this;
|
||||
}
|
||||
|
||||
//~--- inner classes --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Class description
|
||||
*
|
||||
*
|
||||
* @version Enter version here..., 12/02/17
|
||||
* @author Enter your name here...
|
||||
*/
|
||||
public static class Extractor
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param hash
|
||||
*/
|
||||
public Extractor(String hash)
|
||||
{
|
||||
this.hash = hash;
|
||||
}
|
||||
|
||||
//~--- get methods --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public MessageDigestHashBuilder getHashBuilder()
|
||||
{
|
||||
return getHashBuilder(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param saltLength
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public MessageDigestHashBuilder getHashBuilder(int saltLength)
|
||||
{
|
||||
MessageDigestHashBuilder hashBuilder = null;
|
||||
Matcher m = PATTERN.matcher(hash);
|
||||
|
||||
if (m.matches())
|
||||
{
|
||||
String digest = m.group(1);
|
||||
|
||||
if (digest != null)
|
||||
{
|
||||
byte[] salt = null;
|
||||
|
||||
if (saltLength > 0)
|
||||
{
|
||||
String hashWithoutPrefix = m.group(2);
|
||||
|
||||
salt = getSalt(hashWithoutPrefix, saltLength);
|
||||
}
|
||||
|
||||
hashBuilder = new MessageDigestHashBuilder(digest, null, salt, 0,
|
||||
salt != null, true);
|
||||
}
|
||||
}
|
||||
|
||||
return hashBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getLabel()
|
||||
{
|
||||
String label = null;
|
||||
Matcher m = PATTERN.matcher(hash);
|
||||
|
||||
if (m.matches())
|
||||
{
|
||||
label = m.group(1);
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param length
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public byte[] getSalt(int length)
|
||||
{
|
||||
Matcher m = PATTERN.matcher(hash);
|
||||
String hashWithoutPrefix = hash;
|
||||
|
||||
if (m.matches())
|
||||
{
|
||||
hashWithoutPrefix = m.group(2);
|
||||
}
|
||||
|
||||
return getSalt(hashWithoutPrefix, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param hashWithoutPrefix
|
||||
* @param length
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private byte[] getSalt(String hashWithoutPrefix, int length)
|
||||
{
|
||||
byte[] content = Util.fromHexString(hashWithoutPrefix);
|
||||
byte[] salt = new byte[length];
|
||||
|
||||
System.arraycopy(content, content.length - length, salt, 0, length);
|
||||
|
||||
return salt;
|
||||
}
|
||||
|
||||
//~--- fields -------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private String hash;
|
||||
}
|
||||
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private boolean appendSalt;
|
||||
|
||||
/** Field description */
|
||||
private String digest;
|
||||
|
||||
/** Field description */
|
||||
private boolean enableLable;
|
||||
|
||||
/** Field description */
|
||||
private int iterations;
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ public class SHA1HashBuilder extends MessageDigestHashBuilder
|
||||
*/
|
||||
public SHA1HashBuilder()
|
||||
{
|
||||
super(DIGEST, null, null, 0);
|
||||
super(DIGEST, null, null, 0, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,7 +61,7 @@ public class SHA1HashBuilder extends MessageDigestHashBuilder
|
||||
*/
|
||||
public SHA1HashBuilder(String value)
|
||||
{
|
||||
super(DIGEST, value, null, 0);
|
||||
super(DIGEST, value, null, 0, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,7 +73,7 @@ public class SHA1HashBuilder extends MessageDigestHashBuilder
|
||||
*/
|
||||
public SHA1HashBuilder(String value, byte[] salt)
|
||||
{
|
||||
super(DIGEST, value, salt, 0);
|
||||
super(DIGEST, value, salt, 0, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,6 +86,37 @@ public class SHA1HashBuilder extends MessageDigestHashBuilder
|
||||
*/
|
||||
public SHA1HashBuilder(String value, byte[] salt, int iterations)
|
||||
{
|
||||
super(DIGEST, value, salt, iterations);
|
||||
super(DIGEST, value, salt, iterations, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param value
|
||||
* @param salt
|
||||
* @param iterations
|
||||
* @param appendSalt
|
||||
*/
|
||||
public SHA1HashBuilder(String value, byte[] salt, int iterations,
|
||||
boolean appendSalt)
|
||||
{
|
||||
super(DIGEST, value, salt, iterations, appendSalt, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param value
|
||||
* @param salt
|
||||
* @param iterations
|
||||
* @param appendSalt
|
||||
* @param enableLable
|
||||
*/
|
||||
public SHA1HashBuilder(String value, byte[] salt, int iterations,
|
||||
boolean appendSalt, boolean enableLabel)
|
||||
{
|
||||
super(DIGEST, value, salt, iterations, appendSalt, enableLabel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public class SHA512HashBuilder extends MessageDigestHashBuilder
|
||||
*/
|
||||
public SHA512HashBuilder()
|
||||
{
|
||||
super(DIGEST, null, null, 0);
|
||||
super(DIGEST, null, null, 0, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,7 +61,7 @@ public class SHA512HashBuilder extends MessageDigestHashBuilder
|
||||
*/
|
||||
public SHA512HashBuilder(String value)
|
||||
{
|
||||
super(DIGEST, value, null, 0);
|
||||
super(DIGEST, value, null, 0, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,7 +73,7 @@ public class SHA512HashBuilder extends MessageDigestHashBuilder
|
||||
*/
|
||||
public SHA512HashBuilder(String value, byte[] salt)
|
||||
{
|
||||
super(DIGEST, value, salt, 0);
|
||||
super(DIGEST, value, salt, 0, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,6 +86,37 @@ public class SHA512HashBuilder extends MessageDigestHashBuilder
|
||||
*/
|
||||
public SHA512HashBuilder(String value, byte[] salt, int iterations)
|
||||
{
|
||||
super(DIGEST, value, salt, iterations);
|
||||
super(DIGEST, value, salt, iterations, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param value
|
||||
* @param salt
|
||||
* @param iterations
|
||||
* @param appendSalt
|
||||
*/
|
||||
public SHA512HashBuilder(String value, byte[] salt, int iterations,
|
||||
boolean appendSalt)
|
||||
{
|
||||
super(DIGEST, value, salt, iterations, appendSalt, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param value
|
||||
* @param salt
|
||||
* @param iterations
|
||||
* @param appendSalt
|
||||
* @param enableLabel
|
||||
*/
|
||||
public SHA512HashBuilder(String value, byte[] salt, int iterations,
|
||||
boolean appendSalt, boolean enableLabel)
|
||||
{
|
||||
super(DIGEST, value, salt, iterations, appendSalt, enableLabel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,8 @@ package sonia.scm.util;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
@@ -334,6 +336,22 @@ public class Util
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static byte[] fromHexString(String value)
|
||||
{
|
||||
return new BigInteger(value, 16).toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param value
|
||||
*
|
||||
*
|
||||
* @since 1.13
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String nonNull(Object value)
|
||||
{
|
||||
return (value != null)
|
||||
|
||||
Reference in New Issue
Block a user