Refactored using IntelliJ
This commit is contained in:
@@ -7,7 +7,8 @@ import java.nio.charset.StandardCharsets;
|
||||
*/
|
||||
public final class Html {
|
||||
|
||||
private Html() {}
|
||||
private Html() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes text for HTML.
|
||||
@@ -37,7 +38,7 @@ public final class Html {
|
||||
* Simple page wrapper.
|
||||
*
|
||||
* @param title title
|
||||
* @param body body html
|
||||
* @param body body html
|
||||
* @return full html
|
||||
*/
|
||||
public static String page(String title, String body) {
|
||||
|
||||
@@ -88,7 +88,7 @@ public final class RequestParams {
|
||||
* Returns SHA-256 hex of a header value.
|
||||
*
|
||||
* @param hasher hasher
|
||||
* @param key header key
|
||||
* @param key header key
|
||||
* @return sha256 hex (or null if missing)
|
||||
*/
|
||||
public String getSha256Hex(WebHasher hasher, String key) {
|
||||
|
||||
@@ -26,8 +26,8 @@ public final class WebHasher {
|
||||
* Creates a hasher.
|
||||
*
|
||||
* @param pbkdf2Iterations iterations (recommended >= 100k)
|
||||
* @param pbkdf2SaltBytes salt bytes
|
||||
* @param pbkdf2KeyBytes derived key bytes
|
||||
* @param pbkdf2SaltBytes salt bytes
|
||||
* @param pbkdf2KeyBytes derived key bytes
|
||||
*/
|
||||
public WebHasher(int pbkdf2Iterations, int pbkdf2SaltBytes, int pbkdf2KeyBytes) {
|
||||
if (pbkdf2Iterations < 10_000) throw new IllegalArgumentException("pbkdf2Iterations too low");
|
||||
@@ -38,6 +38,35 @@ public final class WebHasher {
|
||||
this.pbkdf2KeyBytes = pbkdf2KeyBytes;
|
||||
}
|
||||
|
||||
private static byte[] derive(char[] password, byte[] salt, int iterations, int keyBytes) {
|
||||
try {
|
||||
PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, keyBytes * 8);
|
||||
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
|
||||
return skf.generateSecret(spec).getEncoded();
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("PBKDF2 not available", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean constantTimeEquals(byte[] a, byte[] b) {
|
||||
if (a == null || b == null) return false;
|
||||
if (a.length != b.length) return false;
|
||||
int r = 0;
|
||||
for (int i = 0; i < a.length; i++) r |= (a[i] ^ b[i]);
|
||||
return r == 0;
|
||||
}
|
||||
|
||||
private static String toHexLower(byte[] data) {
|
||||
final char[] hex = "0123456789abcdef".toCharArray();
|
||||
char[] out = new char[data.length * 2];
|
||||
int i = 0;
|
||||
for (byte b : data) {
|
||||
out[i++] = hex[(b >>> 4) & 0x0F];
|
||||
out[i++] = hex[b & 0x0F];
|
||||
}
|
||||
return new String(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* SHA-256 hashes text (lowercase hex).
|
||||
*
|
||||
@@ -77,7 +106,7 @@ public final class WebHasher {
|
||||
* Verifies a raw password against a stored PBKDF2 string.
|
||||
*
|
||||
* @param password raw password
|
||||
* @param stored stored format
|
||||
* @param stored stored format
|
||||
* @return true if valid
|
||||
*/
|
||||
public boolean pbkdf2Verify(String password, String stored) {
|
||||
@@ -107,33 +136,4 @@ public final class WebHasher {
|
||||
byte[] actual = derive(password.toCharArray(), salt, it, expected.length);
|
||||
return constantTimeEquals(expected, actual);
|
||||
}
|
||||
|
||||
private static byte[] derive(char[] password, byte[] salt, int iterations, int keyBytes) {
|
||||
try {
|
||||
PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, keyBytes * 8);
|
||||
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
|
||||
return skf.generateSecret(spec).getEncoded();
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("PBKDF2 not available", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean constantTimeEquals(byte[] a, byte[] b) {
|
||||
if (a == null || b == null) return false;
|
||||
if (a.length != b.length) return false;
|
||||
int r = 0;
|
||||
for (int i = 0; i < a.length; i++) r |= (a[i] ^ b[i]);
|
||||
return r == 0;
|
||||
}
|
||||
|
||||
private static String toHexLower(byte[] data) {
|
||||
final char[] hex = "0123456789abcdef".toCharArray();
|
||||
char[] out = new char[data.length * 2];
|
||||
int i = 0;
|
||||
for (byte b : data) {
|
||||
out[i++] = hex[(b >>> 4) & 0x0F];
|
||||
out[i++] = hex[b & 0x0F];
|
||||
}
|
||||
return new String(out);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user