FileDocCategorySizeDatePackage
BrokenPBE.javaAPI DocAndroid 1.5 API13824Wed May 06 22:41:06 BST 2009org.bouncycastle.jce.provider

OldPKCS12ParametersGenerator

public class OldPKCS12ParametersGenerator extends org.bouncycastle.crypto.PBEParametersGenerator
Generator for PBE derived keys and ivs as defined by PKCS 12 V1.0, with a bug affecting 180 bit plus keys - this class is only here to allow smooth migration of the version 0 keystore to version 1. Don't use it (it won't be staying around).

The document this implementation is based on can be found at RSA's PKCS12 Page

Fields Summary
public static final int
KEY_MATERIAL
public static final int
IV_MATERIAL
public static final int
MAC_MATERIAL
private org.bouncycastle.crypto.Digest
digest
private int
u
private int
v
Constructors Summary
public OldPKCS12ParametersGenerator(org.bouncycastle.crypto.Digest digest)
Construct a PKCS 12 Parameters generator. This constructor will accept MD5, SHA1, and RIPEMD160.

param
digest the digest to be used as the source of derived keys.
exception
IllegalArgumentException if an unknown digest is passed in.


                                             
     
          
    
        this.digest = digest;
        if (digest instanceof MD5Digest)
        {
            u = 128 / 8;
            v = 512 / 8;
        }
        else if (digest instanceof SHA1Digest)
        {
            u = 160 / 8;
            v = 512 / 8;
        }
        // BEGIN android-removed
        // else if (digest instanceof RIPEMD160Digest)
        // {
        //     u = 160 / 8;
        //     v = 512 / 8;
        // }
        // END android-removed
        else
        {
            throw new IllegalArgumentException("Digest " + digest.getAlgorithmName() + " unsupported");
        }
    
Methods Summary
private voidadjust(byte[] a, int aOff, byte[] b)
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.

        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;
        }
    
private byte[]generateDerivedKey(int idByte, int n)
generation of a derived key ala PKCS12 V1.0.

        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;

        for (int i = 1; i <= c; i++)
        {
            byte[]  A = new byte[u];

            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[i] = 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;
    
public org.bouncycastle.crypto.CipherParametersgenerateDerivedMacParameters(int keySize)
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.

        keySize = keySize / 8;

        byte[]  dKey = generateDerivedKey(MAC_MATERIAL, keySize);

        return new KeyParameter(dKey, 0, keySize);
    
public org.bouncycastle.crypto.CipherParametersgenerateDerivedParameters(int keySize)
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.

        keySize = keySize / 8;

        byte[]  dKey = generateDerivedKey(KEY_MATERIAL, keySize);

        return new KeyParameter(dKey, 0, keySize);
    
public org.bouncycastle.crypto.CipherParametersgenerateDerivedParameters(int keySize, int ivSize)
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.

        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);