Exemplo n.º 1
0
        ASN1Sequence decryptData(
            AlgorithmIdentifier algId,
            byte[]                data,
            char[]                password)
        {
            PKCS12PBEParams  pbeParams     = PKCS12PBEParams.getInstance(algId.getParameters());
            CipherParameters keyParameters = PBEUtil.generateCipherParameters(algId.getObjectId(), password, pbeParams);

            byte[] encoding = null;
            Object engine   = PBEUtil.createEngine(algId.getObjectId());

            if (engine is BufferedBlockCipher)
            {
                BufferedBlockCipher cipher = (BufferedBlockCipher)engine;

                cipher.init(false, keyParameters);

                int encLen = cipher.getOutputSize(data.Length);

                encoding = new byte[encLen];

                int off = cipher.processBytes(data, 0, data.Length, encoding, 0);

                cipher.doFinal(encoding, off);
            }
            else if (engine is StreamCipher)
            {
                StreamCipher cipher = (StreamCipher)engine;

                cipher.init(false, keyParameters);

                encoding = new byte[data.Length];

                cipher.processBytes(data, 0, data.Length, encoding, 0);
            }

            ASN1InputStream bIn = new ASN1InputStream(new MemoryStream(encoding));

            return((ASN1Sequence)bIn.readObject());
        }
Exemplo n.º 2
0
        public static CipherParameters generateCipherParameters(
            String algorithm,
            char[]          password,
            ASN1Encodable pbeParameters)
        {
            String mechanism = (string)algorithms[algorithm.ToUpper()];

            byte[]           key;
            CipherParameters parameters = null;
            String           type       = (String)algorithmType[mechanism];

            byte[] salt           = null;
            int    iterationCount = 0;

            if (isPKCS12(mechanism))
            {
                PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(pbeParameters);

                salt           = pbeParams.getIV();
                iterationCount = pbeParams.getIterations().intValue();
                key            = PBEParametersGenerator.PKCS12PasswordToBytes(password);
            }
            else if (isPKCS5Scheme2(mechanism))
            {
                PBKDF2Params pbeParams = PBKDF2Params.getInstance(pbeParameters);

                salt           = pbeParams.getSalt();
                iterationCount = pbeParams.getIterationCount().intValue();
                key            = PBEParametersGenerator.PKCS5PasswordToBytes(password);
            }
            else
            {
                PBEParameter pbeParams = PBEParameter.getInstance(pbeParameters);

                salt           = pbeParams.getSalt();
                iterationCount = pbeParams.getIterationCount().intValue();
                key            = PBEParametersGenerator.PKCS5PasswordToBytes(password);
            }

            if (mechanism.StartsWith("PBEwithSHA-1"))
            {
                PBEParametersGenerator generator = makePBEGenerator((String)algorithmType[mechanism], new SHA1Digest(), key, salt, iterationCount);

                if (mechanism.Equals("PBEwithSHA-1and128bitRC4"))
                {
                    parameters = generator.generateDerivedParameters(128);
                }
                else if (mechanism.Equals("PBEwithSHA-1and40bitRC4"))
                {
                    parameters = generator.generateDerivedParameters(40);
                }
                else if (mechanism.Equals("PBEwithSHA-1and3-keyDESEDE-CBC"))
                {
                    parameters = generator.generateDerivedParameters(192, 64);
                }
                else if (mechanism.Equals("PBEwithSHA-1and2-keyDESEDE-CBC"))
                {
                    parameters = generator.generateDerivedParameters(128, 64);
                }
                else if (mechanism.Equals("PBEwithSHA-1and128bitRC2-CBC"))
                {
                    parameters = generator.generateDerivedParameters(128, 64);
                }
                else if (mechanism.Equals("PBEwithSHA-1and40bitRC2-CBC"))
                {
                    parameters = generator.generateDerivedParameters(40, 64);
                }
                else if (mechanism.Equals("PBEwithSHA1andDES-CBC"))
                {
                    parameters = generator.generateDerivedParameters(64, 64);
                }
                else if (mechanism.Equals("PBEwithSHA1andRC2-CBC"))
                {
                    parameters = generator.generateDerivedParameters(128, 64);
                }
            }
            else if (mechanism.StartsWith("PBEwithMD5"))
            {
                PBEParametersGenerator generator = makePBEGenerator((String)algorithmType[mechanism], new MD5Digest(), key, salt, iterationCount);

                if (mechanism.Equals("PBEwithMD5andDES-CBC"))
                {
                    parameters = generator.generateDerivedParameters(64, 64);
                }
                else if (mechanism.Equals("PBEwithMD5andRC2-CBC"))
                {
                    parameters = generator.generateDerivedParameters(64, 64);
                }
            }
            else if (mechanism.StartsWith("PBEwithMD2"))
            {
                PBEParametersGenerator generator = makePBEGenerator((String)algorithmType[mechanism], new MD2Digest(), key, salt, iterationCount);

                if (mechanism.Equals("PBEwithMD2andDES-CBC"))
                {
                    parameters = generator.generateDerivedParameters(64, 64);
                }
                else if (mechanism.Equals("PBEwithMD2andRC2-CBC"))
                {
                    parameters = generator.generateDerivedParameters(64, 64);
                }
            }
            else if (mechanism.StartsWith("PBEwithHmac"))
            {
                if (mechanism.Equals("PBEwithHmacSHA-1"))
                {
                    PBEParametersGenerator generator = makePBEGenerator((String)algorithmType[mechanism], new SHA1Digest(), key, salt, iterationCount);

                    parameters = generator.generateDerivedMacParameters(160);
                }
                else if (mechanism.Equals("PBEwithHmacSHA-224"))
                {
                    PBEParametersGenerator generator = makePBEGenerator((String)algorithmType[mechanism], new SHA224Digest(), key, salt, iterationCount);

                    parameters = generator.generateDerivedMacParameters(224);
                }
                else if (mechanism.Equals("PBEwithHmacSHA-256"))
                {
                    PBEParametersGenerator generator = makePBEGenerator((String)algorithmType[mechanism], new SHA256Digest(), key, salt, iterationCount);

                    parameters = generator.generateDerivedMacParameters(256);
                }
                else if (mechanism.Equals("PBEwithHmacRIPEMD128"))
                {
                    PBEParametersGenerator generator = makePBEGenerator((String)algorithmType[mechanism], new RIPEMD128Digest(), key, salt, iterationCount);

                    parameters = generator.generateDerivedMacParameters(128);
                }
                else if (mechanism.Equals("PBEwithHmacRIPEMD160"))
                {
                    PBEParametersGenerator generator = makePBEGenerator((String)algorithmType[mechanism], new RIPEMD160Digest(), key, salt, iterationCount);

                    parameters = generator.generateDerivedMacParameters(160);
                }
                else if (mechanism.Equals("PBEwithHmacRIPEMD256"))
                {
                    PBEParametersGenerator generator = makePBEGenerator((String)algorithmType[mechanism], new RIPEMD256Digest(), key, salt, iterationCount);

                    parameters = generator.generateDerivedMacParameters(256);
                }
            }

            for (int i = 0; i != key.Length; i++)
            {
                key[i] = 0;
            }

            return(parameters);
        }
Exemplo n.º 3
0
        public void save(Stream stream, char[] password, SecureRandom random)
        {
            if (password == null)
            {
                throw new ArgumentException("No password supplied for PKCS12Store.");
            }

            ContentInfo[] c = new ContentInfo[2];


            //
            // handle the key
            //
            ASN1EncodableVector keyS = new ASN1EncodableVector();


            IEnumerator ks = keys.Keys.GetEnumerator();

            while (ks.MoveNext())
            {
                byte[] kSalt = new byte[saltSize];

                random.nextBytes(kSalt);

                String                  name    = (String)ks.Current;
                AsymmetricKeyEntry      privKey = (AsymmetricKeyEntry)keys[name];
                EncryptedPrivateKeyInfo kInfo   = EncryptedPrivateKeyInfoFactory.createEncryptedPrivateKeyInfo(keyAlgorithm, password, kSalt, minIterations, privKey.getKey());
                ASN1EncodableVector     kName   = new ASN1EncodableVector();

                IEnumerator e = privKey.getBagAttributeKeys();

                while (e.MoveNext())
                {
                    String oid = (String)e.Current;
                    ASN1EncodableVector kSeq = new ASN1EncodableVector();

                    kSeq.add(new DERObjectIdentifier(oid));
                    kSeq.add(new DERSet(privKey.getBagAttribute(new DERObjectIdentifier(oid))));

                    kName.add(new DERSequence(kSeq));
                }

                //
                // make sure we have a local key-id
                //
                if (privKey.getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId) == null)
                {
                    ASN1EncodableVector  kSeq = new ASN1EncodableVector();
                    X509CertificateEntry ct   = getCertificate(name);

                    kSeq.add(PKCSObjectIdentifiers.pkcs_9_at_localKeyId);
                    kSeq.add(new DERSet(new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(ct.getCertificate().getPublicKey()))));

                    kName.add(new DERSequence(kSeq));
                }

                //
                // make sure we are using the local alias on store
                //
                DERBMPString nm = (DERBMPString)privKey.getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName);
                if (nm == null || !nm.getString().Equals(name))
                {
                    ASN1EncodableVector kSeq = new ASN1EncodableVector();

                    kSeq.add(PKCSObjectIdentifiers.pkcs_9_at_friendlyName);
                    kSeq.add(new DERSet(new DERBMPString(name)));

                    kName.add(new DERSequence(kSeq));
                }

                SafeBag kBag = new SafeBag(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag, kInfo.toASN1Object(), new DERSet(kName));
                keyS.add(kBag);
            }

            MemoryStream    bOut = new MemoryStream();
            DEROutputStream dOut = new DEROutputStream(bOut);

            dOut.writeObject(new DERSequence(keyS));

            BEROctetString keyString = new BEROctetString(bOut.ToArray());

            //
            // certficate processing
            //
            byte[] cSalt = new byte[saltSize];

            random.nextBytes(cSalt);

            ASN1EncodableVector certSeq   = new ASN1EncodableVector();
            PKCS12PBEParams     cParams   = new PKCS12PBEParams(cSalt, minIterations);
            AlgorithmIdentifier cAlgId    = new AlgorithmIdentifier(certAlgorithm, cParams.toASN1Object());
            Hashtable           doneCerts = new Hashtable();

            IEnumerator cs = keys.Keys.GetEnumerator();

            while (cs.MoveNext())
            {
                try
                {
                    String name = (String)cs.Current;
                    X509CertificateEntry cert = getCertificate(name);
                    CertBag cBag = new CertBag(
                        PKCSObjectIdentifiers.x509certType,
                        new DEROctetString(cert.getCertificate().getEncoded()));
                    ASN1EncodableVector fName = new ASN1EncodableVector();

                    IEnumerator e = cert.getBagAttributeKeys();

                    while (e.MoveNext())
                    {
                        String oid = (String)e.Current;
                        ASN1EncodableVector fSeq = new ASN1EncodableVector();

                        fSeq.add(new DERObjectIdentifier(oid));
                        fSeq.add(new DERSet(cert.getBagAttribute(new DERObjectIdentifier(oid))));
                        fName.add(new DERSequence(fSeq));
                    }

                    //
                    // make sure we are using the local alias on store
                    //
                    DERBMPString nm = (DERBMPString)cert.getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName);
                    if (nm == null || !nm.getString().Equals(name))
                    {
                        ASN1EncodableVector fSeq = new ASN1EncodableVector();

                        fSeq.add(PKCSObjectIdentifiers.pkcs_9_at_friendlyName);
                        fSeq.add(new DERSet(new DERBMPString(name)));

                        fName.add(new DERSequence(fSeq));
                    }

                    //
                    // make sure we have a local key-id
                    //
                    if (cert.getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId) == null)
                    {
                        ASN1EncodableVector fSeq = new ASN1EncodableVector();

                        fSeq.add(PKCSObjectIdentifiers.pkcs_9_at_localKeyId);
                        fSeq.add(new DERSet(new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(cert.getCertificate().getPublicKey()))));
                        fName.add(new DERSequence(fSeq));
                    }

                    SafeBag sBag = new SafeBag(PKCSObjectIdentifiers.certBag, cBag.toASN1Object(), new DERSet(fName));

                    certSeq.add(sBag);

                    doneCerts.Add(cert, cert);
                }
                catch (Exception e)
                {
                    throw new Exception("Error encoding certificate: " + e.Message);
                }
            }

            cs = certs.Keys.GetEnumerator();
            while (cs.MoveNext())
            {
                try
                {
                    String certId             = (String)cs.Current;
                    X509CertificateEntry cert = (X509CertificateEntry)certs[certId];

                    if (keys[certId] != null)
                    {
                        continue;
                    }

                    CertBag cBag = new CertBag(
                        PKCSObjectIdentifiers.x509certType,
                        new DEROctetString(cert.getCertificate().getEncoded()));
                    ASN1EncodableVector fName = new ASN1EncodableVector();
                    IEnumerator         e     = cert.getBagAttributeKeys();

                    while (e.MoveNext())
                    {
                        String oid = (String)e.Current;
                        ASN1EncodableVector fSeq = new ASN1EncodableVector();

                        fSeq.add(new DERObjectIdentifier(oid));
                        fSeq.add(new DERSet(cert.getBagAttribute(new DERObjectIdentifier(oid))));
                        fName.add(new DERSequence(fSeq));
                    }

                    //
                    // make sure we are using the local alias on store
                    //
                    DERBMPString nm = (DERBMPString)cert.getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName);
                    if (nm == null || !nm.getString().Equals(certId))
                    {
                        ASN1EncodableVector fSeq = new ASN1EncodableVector();

                        fSeq.add(PKCSObjectIdentifiers.pkcs_9_at_friendlyName);
                        fSeq.add(new DERSet(new DERBMPString(certId)));

                        fName.add(new DERSequence(fSeq));
                    }

                    SafeBag sBag = new SafeBag(PKCSObjectIdentifiers.certBag, cBag.toASN1Object(), new DERSet(fName));

                    certSeq.add(sBag);

                    doneCerts.Add(cert, cert);
                }
                catch (Exception e)
                {
                    throw new Exception("Error encoding certificate: " + e.Message);
                }
            }

            cs = chainCerts.Keys.GetEnumerator();
            while (cs.MoveNext())
            {
                try
                {
                    CertId certId             = (CertId)cs.Current;
                    X509CertificateEntry cert = (X509CertificateEntry)chainCerts[certId];

                    if (doneCerts[cert] != null)
                    {
                        continue;
                    }

                    CertBag cBag = new CertBag(
                        PKCSObjectIdentifiers.x509certType,
                        new DEROctetString(cert.getCertificate().getEncoded()));
                    ASN1EncodableVector fName = new ASN1EncodableVector();

                    IEnumerator e = cert.getBagAttributeKeys();

                    while (e.MoveNext())
                    {
                        DERObjectIdentifier oid  = (DERObjectIdentifier)e.Current;
                        ASN1EncodableVector fSeq = new ASN1EncodableVector();

                        fSeq.add(oid);
                        fSeq.add(new DERSet(cert.getBagAttribute(oid)));
                        fName.add(new DERSequence(fSeq));
                    }

                    SafeBag sBag = new SafeBag(PKCSObjectIdentifiers.certBag, cBag.toASN1Object(), new DERSet(fName));

                    certSeq.add(sBag);
                }
                catch (Exception e)
                {
                    throw new Exception("Error encoding certificate: " + e.Message);
                }
            }

            bOut = new MemoryStream();

            dOut = new DEROutputStream(bOut);

            dOut.writeObject(new DERSequence(certSeq));

            dOut.Close();

            byte[]        certBytes = encryptData(new AlgorithmIdentifier(certAlgorithm, cParams), bOut.ToArray(), password);
            EncryptedData cInfo     = new EncryptedData(PKCSObjectIdentifiers.data, cAlgId, new BEROctetString(certBytes));

            c[0] = new ContentInfo(PKCSObjectIdentifiers.data, keyString);

            c[1] = new ContentInfo(PKCSObjectIdentifiers.encryptedData, cInfo.toASN1Object());

            AuthenticatedSafe auth = new AuthenticatedSafe(c);

            bOut = new MemoryStream();

            BEROutputStream berOut = new BEROutputStream(bOut);

            berOut.writeObject(auth);

            byte[] pkg = bOut.ToArray();

            ContentInfo mainInfo = new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(pkg));

            //
            // create the mac
            //
            byte[] mSalt   = new byte[20];
            int    itCount = minIterations;

            random.nextBytes(mSalt);

            byte[] data = ((ASN1OctetString)mainInfo.getContent()).getOctets();

            MacData mData = null;

            try
            {
                ASN1Encodable    parameters    = PBEUtil.generateAlgorithmParameters(OIWObjectIdentifiers.id_SHA1, mSalt, itCount);
                CipherParameters keyParameters = PBEUtil.generateCipherParameters(OIWObjectIdentifiers.id_SHA1, password, parameters);
                Mac mac = (Mac)PBEUtil.createEngine(OIWObjectIdentifiers.id_SHA1);

                mac.init(keyParameters);

                mac.update(data, 0, data.Length);

                byte[] res = new byte[mac.getMacSize()];

                mac.doFinal(res, 0);

                AlgorithmIdentifier algId = new AlgorithmIdentifier(OIWObjectIdentifiers.id_SHA1, new DERNull());
                DigestInfo          dInfo = new DigestInfo(algId, res);

                mData = new MacData(dInfo, mSalt, itCount);
            }
            catch (Exception e)
            {
                throw new Exception("error constructing MAC: " + e.Message);
            }

            //
            // output the Pfx
            //
            Pfx pfx = new Pfx(mainInfo, mData);

            berOut = new BEROutputStream(stream);

            berOut.writeObject(pfx);
        }