All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.crypto.generators.PKCS12ParametersGenerator Maven / Gradle / Ivy

Go to download

The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. This jar contains JCE provider and lightweight API for the Bouncy Castle Cryptography APIs for Java 1.8 and later with debug enabled.

The newest version!
package org.bouncycastle.crypto.generators;

import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.ExtendedDigest;
import org.bouncycastle.crypto.PBEParametersGenerator;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;

/**
 * Generator for PBE derived keys and ivs as defined by PKCS 12 V1.0.
 * 

* The document this implementation is based on can be found at * * RSA's PKCS12 Page */ public class PKCS12ParametersGenerator extends PBEParametersGenerator { public static final int KEY_MATERIAL = 1; public static final int IV_MATERIAL = 2; public static final int MAC_MATERIAL = 3; private Digest digest; private int u; private int v; /** * Construct a PKCS 12 Parameters generator. This constructor will * accept any digest which also implements ExtendedDigest. * * @param digest the digest to be used as the source of derived keys. * @exception IllegalArgumentException if an unknown digest is passed in. */ public PKCS12ParametersGenerator( Digest digest) { this.digest = digest; if (digest instanceof ExtendedDigest) { u = digest.getDigestSize(); v = ((ExtendedDigest)digest).getByteLength(); } else { throw new IllegalArgumentException("Digest " + digest.getAlgorithmName() + " unsupported"); } } /** * add a + b + 1, returning the result in a. The a value is treated * as a BigInteger of length (b.length * 8) bits. The result is * modulo 2^b.length in case of overflow. */ private void adjust( byte[] a, int aOff, byte[] b) { int x = (b[b.length - 1] & 0xff) + (a[aOff + b.length - 1] & 0xff) + 1; a[aOff + b.length - 1] = (byte)x; x >>>= 8; for (int i = b.length - 2; i >= 0; i--) { x += (b[i] & 0xff) + (a[aOff + i] & 0xff); a[aOff + i] = (byte)x; x >>>= 8; } } /** * generation of a derived key ala PKCS12 V1.0. */ private byte[] generateDerivedKey( int idByte, int n) { byte[] D = new byte[v]; byte[] dKey = new byte[n]; for (int i = 0; i != D.length; i++) { D[i] = (byte)idByte; } byte[] S; if ((salt != null) && (salt.length != 0)) { S = new byte[v * ((salt.length + v - 1) / v)]; for (int i = 0; i != S.length; i++) { S[i] = salt[i % salt.length]; } } else { S = new byte[0]; } byte[] P; if ((password != null) && (password.length != 0)) { P = new byte[v * ((password.length + v - 1) / v)]; for (int i = 0; i != P.length; i++) { P[i] = password[i % password.length]; } } else { P = new byte[0]; } byte[] I = new byte[S.length + P.length]; System.arraycopy(S, 0, I, 0, S.length); System.arraycopy(P, 0, I, S.length, P.length); byte[] B = new byte[v]; int c = (n + u - 1) / u; byte[] A = new byte[u]; for (int i = 1; i <= c; i++) { digest.update(D, 0, D.length); digest.update(I, 0, I.length); digest.doFinal(A, 0); for (int j = 1; j < iterationCount; j++) { digest.update(A, 0, A.length); digest.doFinal(A, 0); } for (int j = 0; j != B.length; j++) { B[j] = A[j % A.length]; } for (int j = 0; j != I.length / v; j++) { adjust(I, j * v, B); } if (i == c) { System.arraycopy(A, 0, dKey, (i - 1) * u, dKey.length - ((i - 1) * u)); } else { System.arraycopy(A, 0, dKey, (i - 1) * u, A.length); } } return dKey; } /** * Generate a key parameter derived from the password, salt, and iteration * count we are currently initialised with. * * @param keySize the size of the key we want (in bits) * @return a KeyParameter object. */ public CipherParameters generateDerivedParameters( int keySize) { keySize = keySize / 8; byte[] dKey = generateDerivedKey(KEY_MATERIAL, keySize); return new KeyParameter(dKey, 0, keySize); } /** * Generate a key with initialisation vector parameter derived from * the password, salt, and iteration count we are currently initialised * with. * * @param keySize the size of the key we want (in bits) * @param ivSize the size of the iv we want (in bits) * @return a ParametersWithIV object. */ public CipherParameters generateDerivedParameters( int keySize, int ivSize) { keySize = keySize / 8; ivSize = ivSize / 8; byte[] dKey = generateDerivedKey(KEY_MATERIAL, keySize); byte[] iv = generateDerivedKey(IV_MATERIAL, ivSize); return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), iv, 0, ivSize); } /** * Generate a key parameter for use with a MAC derived from the password, * salt, and iteration count we are currently initialised with. * * @param keySize the size of the key we want (in bits) * @return a KeyParameter object. */ public CipherParameters generateDerivedMacParameters( int keySize) { keySize = keySize / 8; byte[] dKey = generateDerivedKey(MAC_MATERIAL, keySize); return new KeyParameter(dKey, 0, keySize); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy