Java Code Examples for javax.crypto.Mac#getMacLength()

The following examples show how to use javax.crypto.Mac#getMacLength() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: CcSigned.java    From takes with MIT License 6 votes vote down vote up
@Override
public Identity decode(final byte[] bytes) throws IOException {
    final Mac mac = this.mac();
    if (bytes.length < mac.getMacLength()) {
        throw new IOException("Invalid data size");
    }
    final byte[] signature = new byte[mac.getMacLength()];
    final byte[] encoded = new byte[bytes.length - signature.length];
    System.arraycopy(bytes, 0, encoded, 0, encoded.length);
    System.arraycopy(
        bytes,
        encoded.length,
        signature,
        0,
        signature.length
    );
    final byte[] actual = mac.doFinal(encoded);
    if (!Arrays.equals(actual, signature)) {
        throw new IOException("Bad signature");
    }
    return this.cdc.decode(encoded);
}
 
Example 2
Source File: Hkdf.java    From aws-dynamodb-encryption-java with Apache License 2.0 6 votes vote down vote up
/**
 * Initializes this Hkdf with input keying material and a salt. If <code>
 * salt</code> is <code>null</code> or of length 0, then a default salt of
 * HashLen zeros will be used (where HashLen is the length of the return
 * value of the supplied algorithm).
 *
 * @param salt
 *            the salt used for key extraction (optional)
 * @param ikm
 *            the Input Keying Material
 */
public void init(final byte[] ikm, final byte[] salt) {
    byte[] realSalt = (salt == null) ? EMPTY_ARRAY : salt.clone();
    byte[] rawKeyMaterial = EMPTY_ARRAY;
    try {
        Mac extractionMac = Mac.getInstance(algorithm, provider);
        if (realSalt.length == 0) {
            realSalt = new byte[extractionMac.getMacLength()];
            Arrays.fill(realSalt, (byte) 0);
        }
        extractionMac.init(new SecretKeySpec(realSalt, algorithm));
        rawKeyMaterial = extractionMac.doFinal(ikm);
        SecretKeySpec key = new SecretKeySpec(rawKeyMaterial, algorithm);
        Arrays.fill(rawKeyMaterial, (byte) 0);  // Zeroize temporary array
        unsafeInitWithoutKeyExtraction(key);
    } catch (GeneralSecurityException e) {
        // We've already checked all of the parameters so no exceptions
        // should be possible here.
        throw new RuntimeException("Unexpected exception", e);
    } finally {
        Arrays.fill(rawKeyMaterial, (byte) 0);  // Zeroize temporary array
    }
}
 
Example 3
Source File: Scrypt.java    From nifi with Apache License 2.0 5 votes vote down vote up
/**
 * Implementation of PBKDF2 (RFC2898).
 *
 * @param mac   the pre-initialized {@link Mac} instance to use
 * @param s     the salt
 * @param c     the iteration count
 * @param dk    the byte array that derived key will be placed in
 * @param dkLen the intended length, in octets, of the derived key
 * @throws GeneralSecurityException if the key length is too long
 */
private 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));
    }
}
 
Example 4
Source File: AttachmentCipherInputStream.java    From bcm-android with GNU General Public License v3.0 5 votes vote down vote up
private static void verifyMac(File file, Mac mac, byte[] theirDigest)
    throws FileNotFoundException, InvalidMacException
{
  try {
    MessageDigest   digest        = MessageDigest.getInstance("SHA256");
    FileInputStream fin           = new FileInputStream(file);
    int             remainingData = Util.toIntExact(file.length()) - mac.getMacLength();
    byte[]          buffer        = new byte[4096];

    while (remainingData > 0) {
      int read = fin.read(buffer, 0, Math.min(buffer.length, remainingData));
      mac.update(buffer, 0, read);
      digest.update(buffer, 0, read);
      remainingData -= read;
    }

    byte[] ourMac   = mac.doFinal();
    byte[] theirMac = new byte[mac.getMacLength()];
    Util.readFully(fin, theirMac);

    if (!MessageDigest.isEqual(ourMac, theirMac)) {
      throw new InvalidMacException("MAC doesn't match!");
    }

    byte[] ourDigest = digest.digest(theirMac);

    if (!MessageDigest.isEqual(ourDigest, theirDigest)) {
      throw new InvalidMacException("Digest doesn't match!");
    }

  } catch (IOException | ArithmeticException e1) {
    throw new InvalidMacException(e1);
  } catch (NoSuchAlgorithmException e) {
    throw new AssertionError(e);
  }
}
 
Example 5
Source File: AttachmentCipherInputStream.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
private static void verifyMac(InputStream inputStream, long length, Mac mac, byte[] theirDigest)
    throws InvalidMacException
{
  try {
    MessageDigest   digest        = MessageDigest.getInstance("SHA256");
    int             remainingData = Util.toIntExact(length) - mac.getMacLength();
    byte[]          buffer        = new byte[4096];

    while (remainingData > 0) {
      int read = inputStream.read(buffer, 0, Math.min(buffer.length, remainingData));
      mac.update(buffer, 0, read);
      digest.update(buffer, 0, read);
      remainingData -= read;
    }

    byte[] ourMac   = mac.doFinal();
    byte[] theirMac = new byte[mac.getMacLength()];
    Util.readFully(inputStream, theirMac);

    if (!MessageDigest.isEqual(ourMac, theirMac)) {
      throw new InvalidMacException("MAC doesn't match!");
    }

    byte[] ourDigest = digest.digest(theirMac);

    if (theirDigest != null && !MessageDigest.isEqual(ourDigest, theirDigest)) {
      throw new InvalidMacException("Digest doesn't match!");
    }

  } catch (IOException | ArithmeticException e1) {
    throw new InvalidMacException(e1);
  } catch (NoSuchAlgorithmException e) {
    throw new AssertionError(e);
  }
}
 
Example 6
Source File: MasterSecretUtil.java    From bcm-android with GNU General Public License v3.0 5 votes vote down vote up
private static byte[] verifyMac(byte[] macSalt, int iterations, byte[] encryptedAndMacdData, String passphrase) throws InvalidPassphraseException, GeneralSecurityException, IOException {
    Mac hmac = getMacForPassphrase(passphrase, macSalt, iterations);

    byte[] encryptedData = new byte[encryptedAndMacdData.length - hmac.getMacLength()];
    System.arraycopy(encryptedAndMacdData, 0, encryptedData, 0, encryptedData.length);

    byte[] givenMac = new byte[hmac.getMacLength()];
    System.arraycopy(encryptedAndMacdData, encryptedAndMacdData.length - hmac.getMacLength(), givenMac, 0, givenMac.length);

    byte[] localMac = hmac.doFinal(encryptedData);

    if (Arrays.equals(givenMac, localMac)) return encryptedData;
    else throw new InvalidPassphraseException("MAC Error");
}
 
Example 7
Source File: PBKDF.java    From AndroidWallet with GNU General Public License v3.0 5 votes vote down vote up
/**
 * 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));
    }
}
 
Example 8
Source File: PBKDF2.java    From MyVirtualDirectory with Apache License 2.0 5 votes vote down vote up
public static byte[] deriveKey( byte[] password, byte[] salt, int iterationCount, int dkLen )
    throws java.security.NoSuchAlgorithmException, java.security.InvalidKeyException
{
    SecretKeySpec keyspec = new SecretKeySpec( password, "HmacSHA256" );
    Mac prf = Mac.getInstance( "HmacSHA256" );
    prf.init( keyspec );

    // Note: hLen, dkLen, l, r, T, F, etc. are horrible names for
    //       variables and functions in this day and age, but they
    //       reflect the terse symbols used in RFC 2898 to describe
    //       the PBKDF2 algorithm, which improves validation of the
    //       code vs. the RFC.
    //
    // dklen is expressed in bytes. (16 for a 128-bit key)

    int hLen = prf.getMacLength();   // 20 for SHA1
    int l = Math.max( dkLen, hLen); //  1 for 128bit (16-byte) keys
    int r = dkLen - (l-1)*hLen;      // 16 for 128bit (16-byte) keys
    byte T[] = new byte[l * hLen];
    int ti_offset = 0;
    for (int i = 1; i <= l; i++) {
        F( T, ti_offset, prf, salt, iterationCount, i );
        ti_offset += hLen;
    }

    if (r < hLen) {
        // Incomplete last block
        byte DK[] = new byte[dkLen];
        System.arraycopy(T, 0, DK, 0, dkLen);
        return DK;
    }
    return T;
}
 
Example 9
Source File: PBKDF.java    From bitshares_wallet with MIT License 5 votes vote down vote up
/**
 * 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));
    }
}
 
Example 10
Source File: MasterSecretUtil.java    From Silence with GNU General Public License v3.0 5 votes vote down vote up
private static byte[] verifyMac(byte[] macSalt, int iterations, byte[] encryptedAndMacdData, String passphrase) throws InvalidPassphraseException, GeneralSecurityException, IOException {
  Mac hmac        = getMacForPassphrase(passphrase, macSalt, iterations);

  byte[] encryptedData = new byte[encryptedAndMacdData.length - hmac.getMacLength()];
  System.arraycopy(encryptedAndMacdData, 0, encryptedData, 0, encryptedData.length);

  byte[] givenMac      = new byte[hmac.getMacLength()];
  System.arraycopy(encryptedAndMacdData, encryptedAndMacdData.length-hmac.getMacLength(), givenMac, 0, givenMac.length);

  byte[] localMac      = hmac.doFinal(encryptedData);

  if (Arrays.equals(givenMac, localMac)) return encryptedData;
  else                                   throw new InvalidPassphraseException("MAC Error");
}
 
Example 11
Source File: Scrypt.java    From localization_nifi with Apache License 2.0 5 votes vote down vote up
/**
 * Implementation of PBKDF2 (RFC2898).
 *
 * @param mac   the pre-initialized {@link Mac} instance to use
 * @param s     the salt
 * @param c     the iteration count
 * @param dk    the byte array that derived key will be placed in
 * @param dkLen the intended length, in octets, of the derived key
 * @throws GeneralSecurityException if the key length is too long
 */
private 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));
    }
}
 
Example 12
Source File: AttachmentCipherInputStream.java    From Silence with GNU General Public License v3.0 5 votes vote down vote up
private void verifyMac(File file, Mac mac, Optional<byte[]> theirDigest)
    throws FileNotFoundException, InvalidMacException
{
  try {
    MessageDigest   digest        = MessageDigest.getInstance("SHA256");
    FileInputStream fin           = new FileInputStream(file);
    int             remainingData = Util.toIntExact(file.length()) - mac.getMacLength();
    byte[]          buffer        = new byte[4096];

    while (remainingData > 0) {
      int read = fin.read(buffer, 0, Math.min(buffer.length, remainingData));
      mac.update(buffer, 0, read);
      digest.update(buffer, 0, read);
      remainingData -= read;
    }

    byte[] ourMac   = mac.doFinal();
    byte[] theirMac = new byte[mac.getMacLength()];
    Util.readFully(fin, theirMac);

    if (!MessageDigest.isEqual(ourMac, theirMac)) {
      throw new InvalidMacException("MAC doesn't match!");
    }

    byte[] ourDigest = digest.digest(theirMac);

    if (theirDigest.isPresent() && !MessageDigest.isEqual(ourDigest, theirDigest.get())) {
      throw new InvalidMacException("Digest doesn't match!");
    }

  } catch (IOException | ArithmeticException e1) {
    throw new InvalidMacException(e1);
  } catch (NoSuchAlgorithmException e) {
    throw new AssertionError(e);
  }
}
 
Example 13
Source File: Pbkdf2Utils.java    From super-cloudops with Apache License 2.0 5 votes vote down vote up
private static byte[] deriveKey(byte[] password, byte[] salt, int iterationCount, int dkLen)
		throws NoSuchAlgorithmException, InvalidKeyException {
	SecretKeySpec keyspec = new SecretKeySpec(password, "HmacSHA256");
	Mac prf = Mac.getInstance("HmacSHA256");
	prf.init(keyspec);

	// Note: hLen, dkLen, l, r, T, F, etc. are horrible names for
	// variables and functions in this day and age, but they
	// reflect the terse symbols used in RFC 2898 to describe
	// the PBKDF2 algorithm, which improves validation of the
	// code vs. the RFC.
	//
	// dklen is expressed in bytes. (16 for a 128-bit key)

	int hLen = prf.getMacLength(); // 20 for SHA1
	int l = Math.max(dkLen, hLen); // 1 for 128bit (16-byte) keys
	int r = dkLen - (l - 1) * hLen; // 16 for 128bit (16-byte) keys
	byte T[] = new byte[l * hLen];
	int ti_offset = 0;
	for (int i = 1; i <= l; i++) {
		F(T, ti_offset, prf, salt, iterationCount, i);
		ti_offset += hLen;
	}

	if (r < hLen) {
		// Incomplete last block
		byte DK[] = new byte[dkLen];
		System.arraycopy(T, 0, DK, 0, dkLen);
		return DK;
	}
	return T;
}
 
Example 14
Source File: Pbkdf2Utils.java    From super-cloudops with Apache License 2.0 5 votes vote down vote up
private static void F(byte[] dest, int offset, Mac prf, byte[] S, int c, int blockIndex) {
	final int hLen = prf.getMacLength();
	byte U_r[] = new byte[hLen];
	// U0 = S || INT (i);
	byte U_i[] = new byte[S.length + 4];
	System.arraycopy(S, 0, U_i, 0, S.length);
	INT(U_i, S.length, blockIndex);
	for (int i = 0; i < c; i++) {
		U_i = prf.doFinal(U_i);
		xor(U_r, U_i);
	}

	System.arraycopy(U_r, 0, dest, offset, hLen);
}
 
Example 15
Source File: PBKDF2KeyImpl.java    From Bytecoder with Apache License 2.0 4 votes vote down vote up
private static byte[] deriveKey(final Mac prf, final byte[] password,
        byte[] salt, int iterCount, int keyLengthInBit) {
    int keyLength = keyLengthInBit/8;
    byte[] key = new byte[keyLength];
    try {
        int hlen = prf.getMacLength();
        int intL = (keyLength + hlen - 1)/hlen; // ceiling
        int intR = keyLength - (intL - 1)*hlen; // residue
        byte[] ui = new byte[hlen];
        byte[] ti = new byte[hlen];
        // SecretKeySpec cannot be used, since password can be empty here.
        SecretKey macKey = new SecretKey() {
            @java.io.Serial
            private static final long serialVersionUID = 7874493593505141603L;
            @Override
            public String getAlgorithm() {
                return prf.getAlgorithm();
            }
            @Override
            public String getFormat() {
                return "RAW";
            }
            @Override
            public byte[] getEncoded() {
                return password;
            }
            @Override
            public int hashCode() {
                return Arrays.hashCode(password) * 41 +
                  prf.getAlgorithm().toLowerCase(Locale.ENGLISH).hashCode();
            }
            @Override
            public boolean equals(Object obj) {
                if (this == obj) return true;
                if (this.getClass() != obj.getClass()) return false;
                SecretKey sk = (SecretKey)obj;
                return prf.getAlgorithm().equalsIgnoreCase(
                    sk.getAlgorithm()) &&
                    MessageDigest.isEqual(password, sk.getEncoded());
            }
        };
        prf.init(macKey);

        byte[] ibytes = new byte[4];
        for (int i = 1; i <= intL; i++) {
            prf.update(salt);
            ibytes[3] = (byte) i;
            ibytes[2] = (byte) ((i >> 8) & 0xff);
            ibytes[1] = (byte) ((i >> 16) & 0xff);
            ibytes[0] = (byte) ((i >> 24) & 0xff);
            prf.update(ibytes);
            prf.doFinal(ui, 0);
            System.arraycopy(ui, 0, ti, 0, ui.length);

            for (int j = 2; j <= iterCount; j++) {
                prf.update(ui);
                prf.doFinal(ui, 0);
                // XOR the intermediate Ui's together.
                for (int k = 0; k < ui.length; k++) {
                    ti[k] ^= ui[k];
                }
            }
            if (i == intL) {
                System.arraycopy(ti, 0, key, (i-1)*hlen, intR);
            } else {
                System.arraycopy(ti, 0, key, (i-1)*hlen, hlen);
            }
        }
    } catch (GeneralSecurityException gse) {
        throw new RuntimeException("Error deriving PBKDF2 keys", gse);
    }
    return key;
}
 
Example 16
Source File: PBKDF2KeyImpl.java    From jdk8u_jdk with GNU General Public License v2.0 4 votes vote down vote up
private static byte[] deriveKey(final Mac prf, final byte[] password,
        byte[] salt, int iterCount, int keyLengthInBit) {
    int keyLength = keyLengthInBit/8;
    byte[] key = new byte[keyLength];
    try {
        int hlen = prf.getMacLength();
        int intL = (keyLength + hlen - 1)/hlen; // ceiling
        int intR = keyLength - (intL - 1)*hlen; // residue
        byte[] ui = new byte[hlen];
        byte[] ti = new byte[hlen];
        // SecretKeySpec cannot be used, since password can be empty here.
        SecretKey macKey = new SecretKey() {
            private static final long serialVersionUID = 7874493593505141603L;
            @Override
            public String getAlgorithm() {
                return prf.getAlgorithm();
            }
            @Override
            public String getFormat() {
                return "RAW";
            }
            @Override
            public byte[] getEncoded() {
                return password;
            }
            @Override
            public int hashCode() {
                return Arrays.hashCode(password) * 41 +
                  prf.getAlgorithm().toLowerCase(Locale.ENGLISH).hashCode();
            }
            @Override
            public boolean equals(Object obj) {
                if (this == obj) return true;
                if (this.getClass() != obj.getClass()) return false;
                SecretKey sk = (SecretKey)obj;
                return prf.getAlgorithm().equalsIgnoreCase(
                    sk.getAlgorithm()) &&
                    MessageDigest.isEqual(password, sk.getEncoded());
            }
        };
        prf.init(macKey);

        byte[] ibytes = new byte[4];
        for (int i = 1; i <= intL; i++) {
            prf.update(salt);
            ibytes[3] = (byte) i;
            ibytes[2] = (byte) ((i >> 8) & 0xff);
            ibytes[1] = (byte) ((i >> 16) & 0xff);
            ibytes[0] = (byte) ((i >> 24) & 0xff);
            prf.update(ibytes);
            prf.doFinal(ui, 0);
            System.arraycopy(ui, 0, ti, 0, ui.length);

            for (int j = 2; j <= iterCount; j++) {
                prf.update(ui);
                prf.doFinal(ui, 0);
                // XOR the intermediate Ui's together.
                for (int k = 0; k < ui.length; k++) {
                    ti[k] ^= ui[k];
                }
            }
            if (i == intL) {
                System.arraycopy(ti, 0, key, (i-1)*hlen, intR);
            } else {
                System.arraycopy(ti, 0, key, (i-1)*hlen, hlen);
            }
        }
    } catch (GeneralSecurityException gse) {
        throw new RuntimeException("Error deriving PBKDF2 keys");
    }
    return key;
}
 
Example 17
Source File: PBKDF2KeyImpl.java    From jdk8u-jdk with GNU General Public License v2.0 4 votes vote down vote up
private static byte[] deriveKey(final Mac prf, final byte[] password,
        byte[] salt, int iterCount, int keyLengthInBit) {
    int keyLength = keyLengthInBit/8;
    byte[] key = new byte[keyLength];
    try {
        int hlen = prf.getMacLength();
        int intL = (keyLength + hlen - 1)/hlen; // ceiling
        int intR = keyLength - (intL - 1)*hlen; // residue
        byte[] ui = new byte[hlen];
        byte[] ti = new byte[hlen];
        // SecretKeySpec cannot be used, since password can be empty here.
        SecretKey macKey = new SecretKey() {
            private static final long serialVersionUID = 7874493593505141603L;
            @Override
            public String getAlgorithm() {
                return prf.getAlgorithm();
            }
            @Override
            public String getFormat() {
                return "RAW";
            }
            @Override
            public byte[] getEncoded() {
                return password;
            }
            @Override
            public int hashCode() {
                return Arrays.hashCode(password) * 41 +
                  prf.getAlgorithm().toLowerCase(Locale.ENGLISH).hashCode();
            }
            @Override
            public boolean equals(Object obj) {
                if (this == obj) return true;
                if (this.getClass() != obj.getClass()) return false;
                SecretKey sk = (SecretKey)obj;
                return prf.getAlgorithm().equalsIgnoreCase(
                    sk.getAlgorithm()) &&
                    MessageDigest.isEqual(password, sk.getEncoded());
            }
        };
        prf.init(macKey);

        byte[] ibytes = new byte[4];
        for (int i = 1; i <= intL; i++) {
            prf.update(salt);
            ibytes[3] = (byte) i;
            ibytes[2] = (byte) ((i >> 8) & 0xff);
            ibytes[1] = (byte) ((i >> 16) & 0xff);
            ibytes[0] = (byte) ((i >> 24) & 0xff);
            prf.update(ibytes);
            prf.doFinal(ui, 0);
            System.arraycopy(ui, 0, ti, 0, ui.length);

            for (int j = 2; j <= iterCount; j++) {
                prf.update(ui);
                prf.doFinal(ui, 0);
                // XOR the intermediate Ui's together.
                for (int k = 0; k < ui.length; k++) {
                    ti[k] ^= ui[k];
                }
            }
            if (i == intL) {
                System.arraycopy(ti, 0, key, (i-1)*hlen, intR);
            } else {
                System.arraycopy(ti, 0, key, (i-1)*hlen, hlen);
            }
        }
    } catch (GeneralSecurityException gse) {
        throw new RuntimeException("Error deriving PBKDF2 keys");
    }
    return key;
}
 
Example 18
Source File: PasswordBasedKeyDerivationFunction2.java    From Jose4j with Apache License 2.0 4 votes vote down vote up
public byte[] derive(byte[] password, byte[] salt, int iterationCount, int dkLen, String provider) throws JoseException
{
    Mac prf = MacUtil.getInitializedMac(hmacAlgorithm, new HmacKey(password), provider);
    int hLen = prf.getMacLength();

    //  1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and
    //     stop.
    long maxDerivedKeyLength = 4294967295L; // value of (long) Math.pow(2, 32) - 1;
    if (dkLen > maxDerivedKeyLength)
    {
        throw new UncheckedJoseException("derived key too long " + dkLen);
    }

    //  2. Let l be the number of hLen-octet blocks in the derived key,
    //     rounding up, and let r be the number of octets in the last
    //     block:
    //
    //               l = CEIL (dkLen / hLen) ,
    //               r = dkLen - (l - 1) * hLen .
    //
    //     Here, CEIL (x) is the "ceiling" function, i.e. the smallest
    //     integer greater than, or equal to, x.
    int l = (int) Math.ceil((double) dkLen / (double) hLen);
    int r = dkLen - (l - 1) * hLen;

    //  3. For each block of the derived key apply the function F defined
    //     below to the password P, the salt S, the iteration count c, and
    //     the block index to compute the block:
    //
    //               T_1 = F (P, S, c, 1) ,
    //               T_2 = F (P, S, c, 2) ,
    //               ...
    //               T_l = F (P, S, c, l) ,
    //
    //     where the function F is defined as the exclusive-or sum of the
    //     first c iterates of the underlying pseudorandom function PRF
    //     applied to the password P and the concatenation of the salt S
    //     and the block index i:
    //
    //               F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c
    //
    //     where
    //
    //               U_1 = PRF (P, S || INT (i)) ,
    //               U_2 = PRF (P, U_1) ,
    //               ...
    //               U_c = PRF (P, U_{c-1}) .
    //
    //     Here, INT (i) is a four-octet encoding of the integer i, most
    //     significant octet first.

    //  4. Concatenate the blocks and extract the first dkLen octets to
    //     produce a derived key DK:
    //
    //               DK = T_1 || T_2 ||  ...  || T_l<0..r-1>
    //
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    for (int i = 0; i < l; i++)
    {
        byte[] block = f(salt, iterationCount, i + 1, prf);
        if (i == (l - 1))
        {
            block = ByteUtil.subArray(block, 0, r);
        }
        byteArrayOutputStream.write(block, 0, block.length);
    }

    //  5. Output the derived key DK.
    return byteArrayOutputStream.toByteArray();
}
 
Example 19
Source File: PBKDF2KeyImpl.java    From TencentKona-8 with GNU General Public License v2.0 4 votes vote down vote up
private static byte[] deriveKey(final Mac prf, final byte[] password,
        byte[] salt, int iterCount, int keyLengthInBit) {
    int keyLength = keyLengthInBit/8;
    byte[] key = new byte[keyLength];
    try {
        int hlen = prf.getMacLength();
        int intL = (keyLength + hlen - 1)/hlen; // ceiling
        int intR = keyLength - (intL - 1)*hlen; // residue
        byte[] ui = new byte[hlen];
        byte[] ti = new byte[hlen];
        // SecretKeySpec cannot be used, since password can be empty here.
        SecretKey macKey = new SecretKey() {
            private static final long serialVersionUID = 7874493593505141603L;
            @Override
            public String getAlgorithm() {
                return prf.getAlgorithm();
            }
            @Override
            public String getFormat() {
                return "RAW";
            }
            @Override
            public byte[] getEncoded() {
                return password;
            }
            @Override
            public int hashCode() {
                return Arrays.hashCode(password) * 41 +
                  prf.getAlgorithm().toLowerCase(Locale.ENGLISH).hashCode();
            }
            @Override
            public boolean equals(Object obj) {
                if (this == obj) return true;
                if (this.getClass() != obj.getClass()) return false;
                SecretKey sk = (SecretKey)obj;
                return prf.getAlgorithm().equalsIgnoreCase(
                    sk.getAlgorithm()) &&
                    MessageDigest.isEqual(password, sk.getEncoded());
            }
        };
        prf.init(macKey);

        byte[] ibytes = new byte[4];
        for (int i = 1; i <= intL; i++) {
            prf.update(salt);
            ibytes[3] = (byte) i;
            ibytes[2] = (byte) ((i >> 8) & 0xff);
            ibytes[1] = (byte) ((i >> 16) & 0xff);
            ibytes[0] = (byte) ((i >> 24) & 0xff);
            prf.update(ibytes);
            prf.doFinal(ui, 0);
            System.arraycopy(ui, 0, ti, 0, ui.length);

            for (int j = 2; j <= iterCount; j++) {
                prf.update(ui);
                prf.doFinal(ui, 0);
                // XOR the intermediate Ui's together.
                for (int k = 0; k < ui.length; k++) {
                    ti[k] ^= ui[k];
                }
            }
            if (i == intL) {
                System.arraycopy(ti, 0, key, (i-1)*hlen, intR);
            } else {
                System.arraycopy(ti, 0, key, (i-1)*hlen, hlen);
            }
        }
    } catch (GeneralSecurityException gse) {
        throw new RuntimeException("Error deriving PBKDF2 keys");
    }
    return key;
}
 
Example 20
Source File: PBKDF2KeyImpl.java    From openjdk-jdk9 with GNU General Public License v2.0 4 votes vote down vote up
private static byte[] deriveKey(final Mac prf, final byte[] password,
        byte[] salt, int iterCount, int keyLengthInBit) {
    int keyLength = keyLengthInBit/8;
    byte[] key = new byte[keyLength];
    try {
        int hlen = prf.getMacLength();
        int intL = (keyLength + hlen - 1)/hlen; // ceiling
        int intR = keyLength - (intL - 1)*hlen; // residue
        byte[] ui = new byte[hlen];
        byte[] ti = new byte[hlen];
        // SecretKeySpec cannot be used, since password can be empty here.
        SecretKey macKey = new SecretKey() {
            private static final long serialVersionUID = 7874493593505141603L;
            @Override
            public String getAlgorithm() {
                return prf.getAlgorithm();
            }
            @Override
            public String getFormat() {
                return "RAW";
            }
            @Override
            public byte[] getEncoded() {
                return password;
            }
            @Override
            public int hashCode() {
                return Arrays.hashCode(password) * 41 +
                  prf.getAlgorithm().toLowerCase(Locale.ENGLISH).hashCode();
            }
            @Override
            public boolean equals(Object obj) {
                if (this == obj) return true;
                if (this.getClass() != obj.getClass()) return false;
                SecretKey sk = (SecretKey)obj;
                return prf.getAlgorithm().equalsIgnoreCase(
                    sk.getAlgorithm()) &&
                    MessageDigest.isEqual(password, sk.getEncoded());
            }
        };
        prf.init(macKey);

        byte[] ibytes = new byte[4];
        for (int i = 1; i <= intL; i++) {
            prf.update(salt);
            ibytes[3] = (byte) i;
            ibytes[2] = (byte) ((i >> 8) & 0xff);
            ibytes[1] = (byte) ((i >> 16) & 0xff);
            ibytes[0] = (byte) ((i >> 24) & 0xff);
            prf.update(ibytes);
            prf.doFinal(ui, 0);
            System.arraycopy(ui, 0, ti, 0, ui.length);

            for (int j = 2; j <= iterCount; j++) {
                prf.update(ui);
                prf.doFinal(ui, 0);
                // XOR the intermediate Ui's together.
                for (int k = 0; k < ui.length; k++) {
                    ti[k] ^= ui[k];
                }
            }
            if (i == intL) {
                System.arraycopy(ti, 0, key, (i-1)*hlen, intR);
            } else {
                System.arraycopy(ti, 0, key, (i-1)*hlen, hlen);
            }
        }
    } catch (GeneralSecurityException gse) {
        throw new RuntimeException("Error deriving PBKDF2 keys");
    }
    return key;
}