
com.lambdaworks.crypto.PBKDF Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scrypt Show documentation
Show all versions of scrypt Show documentation
Java implementation of scrypt
// Copyright (C) 2011 - Will Glozer. All rights reserved.
package com.lambdaworks.crypto;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.GeneralSecurityException;
import static java.lang.System.arraycopy;
/**
* An implementation of the Password-Based Key Derivation Function as specified
* in RFC 2898.
*
* @author Will Glozer
*/
public class PBKDF {
/**
* Implementation of PBKDF2 (RFC2898).
*
* @param alg HMAC algorithm to use.
* @param P Password.
* @param S Salt.
* @param c Iteration count.
* @param dkLen Intended length, in octets, of the derived key.
*
* @return The derived key.
*
* @throws GeneralSecurityException
*/
public static byte[] pbkdf2(String alg, byte[] P, byte[] S, int c, int dkLen) throws GeneralSecurityException {
Mac mac = Mac.getInstance(alg);
mac.init(new SecretKeySpec(P, alg));
byte[] DK = new byte[dkLen];
pbkdf2(mac, S, c, DK, dkLen);
return DK;
}
/**
* Implementation of PBKDF2 (RFC2898).
*
* @param mac Pre-initialized {@link Mac} instance to use.
* @param S Salt.
* @param c Iteration count.
* @param DK Byte array that derived key will be placed in.
* @param dkLen Intended length, in octets, of the derived key.
*
* @throws GeneralSecurityException
*/
public static void pbkdf2(Mac mac, byte[] S, int c, byte[] DK, int dkLen) throws GeneralSecurityException {
int hLen = mac.getMacLength();
if (dkLen > (Math.pow(2, 32) - 1) * hLen) {
throw new GeneralSecurityException("Requested key length too long");
}
byte[] U = new byte[hLen];
byte[] T = new byte[hLen];
byte[] block1 = new byte[S.length + 4];
int l = (int) Math.ceil((double) dkLen / hLen);
int r = dkLen - (l - 1) * hLen;
arraycopy(S, 0, block1, 0, S.length);
for (int i = 1; i <= l; i++) {
block1[S.length + 0] = (byte) (i >> 24 & 0xff);
block1[S.length + 1] = (byte) (i >> 16 & 0xff);
block1[S.length + 2] = (byte) (i >> 8 & 0xff);
block1[S.length + 3] = (byte) (i >> 0 & 0xff);
mac.update(block1);
mac.doFinal(U, 0);
arraycopy(U, 0, T, 0, hLen);
for (int j = 1; j < c; j++) {
mac.update(U);
mac.doFinal(U, 0);
for (int k = 0; k < hLen; k++) {
T[k] ^= U[k];
}
}
arraycopy(T, 0, DK, (i - 1) * hLen, (i == l ? r : hLen));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy