-// Copyright (C) 2011 - Will Glozer. All rights reserved.
+// Copyright (C) 2011 - Will Glozer. All rights reserved.
package com.lambdaworks.crypto;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
-
-import static com.lambdaworks.codec.Base64.*;
+import java.util.Base64;
/**
- * Simple {@link SCrypt} interface for hashing passwords using the
- * <a href="http://www.tarsnap.com/scrypt.html">scrypt</a> key derivation function
+ * Simple {@link SCrypt} interface for hashing passwords using the <a
+ * href="http://www.tarsnap.com/scrypt.html">scrypt</a> key derivation function
* and comparing a plain text password to a hashed one. The hashed output is an
- * extended implementation of the Modular Crypt Format that also includes the scrypt
- * algorithm parameters.
- *
- * Format: <code>$s0$PARAMS$SALT$KEY</code>.
- *
+ * extended implementation of the Modular Crypt Format that also includes the
+ * scrypt algorithm parameters. Format: <code>$s0$PARAMS$SALT$KEY</code>.
* <dl>
- * <dd>PARAMS</dd><dt>32-bit hex integer containing log2(N) (16 bits), r (8 bits), and p (8 bits)</dt>
- * <dd>SALT</dd><dt>base64-encoded salt</dt>
- * <dd>KEY</dd><dt>base64-encoded derived key</dt>
+ * <dd>PARAMS</dd>
+ * <dt>32-bit hex integer containing log2(N) (16 bits), r (8 bits), and p (8
+ * bits)</dt>
+ * <dd>SALT</dd>
+ * <dt>base64-encoded salt</dt>
+ * <dd>KEY</dd>
+ * <dt>base64-encoded derived key</dt>
* </dl>
+ * <code>s0</code> identifies version 0 of the scrypt format, using a 128-bit
+ * salt and 256-bit derived key.
*
- * <code>s0</code> identifies version 0 of the scrypt format, using a 128-bit salt and 256-bit derived key.
- *
- * @author Will Glozer
+ * @author Will Glozer
*/
public class SCryptUtil {
+
/**
- * Hash the supplied plaintext password and generate output in the format described
- * in {@link SCryptUtil}.
- *
- * @param passwd Password.
- * @param N CPU cost parameter.
- * @param r Memory cost parameter.
- * @param p Parallelization parameter.
+ * Hash the supplied plaintext password and generate output in the format
+ * described in {@link SCryptUtil}.
*
+ * @param passwd
+ * Password.
+ * @param N
+ * CPU cost parameter.
+ * @param r
+ * Memory cost parameter.
+ * @param p
+ * Parallelization parameter.
* @return The hashed password.
*/
public static String scrypt(String passwd, int N, int r, int p) {
StringBuilder sb = new StringBuilder((salt.length + derived.length) * 2);
sb.append("$s0$").append(params).append('$');
- sb.append(encode(salt)).append('$');
- sb.append(encode(derived));
+ sb.append(Base64.getEncoder().encodeToString(salt)).append('$');
+ sb.append(Base64.getEncoder().encodeToString(derived));
return sb.toString();
} catch (UnsupportedEncodingException e) {
/**
* Compare the supplied plaintext password to a hashed password.
*
- * @param passwd Plaintext password.
- * @param hashed scrypt hashed password.
- *
+ * @param passwd
+ * Plaintext password.
+ * @param hashed
+ * scrypt hashed password.
* @return true if passwd matches hashed value.
*/
public static boolean check(String passwd, String hashed) {
}
long params = Long.parseLong(parts[2], 16);
- byte[] salt = decode(parts[3].toCharArray());
- byte[] derived0 = decode(parts[4].toCharArray());
+ byte[] salt = Base64.getDecoder().decode(parts[3]);
+ byte[] derived0 = Base64.getDecoder().decode(parts[4]);
int N = (int) Math.pow(2, params >> 16 & 0xffff);
int r = (int) params >> 8 & 0xff;
- int p = (int) params & 0xff;
+ int p = (int) params & 0xff;
byte[] derived1 = SCrypt.scrypt(passwd.getBytes("UTF-8"), salt, N, r, p, 32);
- if (derived0.length != derived1.length) return false;
+ if (derived0.length != derived1.length) {
+ return false;
+ }
int result = 0;
for (int i = 0; i < derived0.length; i++) {
private static int log2(int n) {
int log = 0;
- if ((n & 0xffff0000 ) != 0) { n >>>= 16; log = 16; }
- if (n >= 256) { n >>>= 8; log += 8; }
- if (n >= 16 ) { n >>>= 4; log += 4; }
- if (n >= 4 ) { n >>>= 2; log += 2; }
+ if ((n & 0xffff0000) != 0) {
+ n >>>= 16;
+ log = 16;
+ }
+ if (n >= 256) {
+ n >>>= 8;
+ log += 8;
+ }
+ if (n >= 16) {
+ n >>>= 4;
+ log += 4;
+ }
+ if (n >= 4) {
+ n >>>= 2;
+ log += 2;
+ }
return log + (n >>> 1);
}
}