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