using System; using System.Collections; using System.IO; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Oiw; using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Collections; using Org.BouncyCastle.Utilities.Encoders; using Org.BouncyCastle.X509; namespace Org.BouncyCastle.Pkcs; public class Pkcs12Store { internal class CertId { private readonly byte[] id; internal byte[] Id => id; internal CertId(AsymmetricKeyParameter pubKey) { id = CreateSubjectKeyID(pubKey).GetKeyIdentifier(); } internal CertId(byte[] id) { this.id = id; } public override int GetHashCode() { return Arrays.GetHashCode(id); } public override bool Equals(object obj) { if (obj == this) { return true; } if (!(obj is CertId certId)) { return false; } return Arrays.AreEqual(id, certId.id); } } private class IgnoresCaseHashtable : IEnumerable { private readonly IDictionary orig = Platform.CreateHashtable(); private readonly IDictionary keys = Platform.CreateHashtable(); public ICollection Keys => orig.Keys; public object this[string alias] { get { string key = Platform.ToUpperInvariant(alias); string text = (string)keys[key]; if (text == null) { return null; } return orig[text]; } set { string key = Platform.ToUpperInvariant(alias); string text = (string)keys[key]; if (text != null) { orig.Remove(text); } keys[key] = alias; orig[alias] = value; } } public ICollection Values => orig.Values; public void Clear() { orig.Clear(); keys.Clear(); } public IEnumerator GetEnumerator() { return orig.GetEnumerator(); } public object Remove(string alias) { string key = Platform.ToUpperInvariant(alias); string text = (string)keys[key]; if (text == null) { return null; } keys.Remove(key); object result = orig[text]; orig.Remove(text); return result; } } private const int MinIterations = 1024; private const int SaltSize = 20; private readonly IgnoresCaseHashtable keys = new IgnoresCaseHashtable(); private readonly IDictionary localIds = Platform.CreateHashtable(); private readonly IgnoresCaseHashtable certs = new IgnoresCaseHashtable(); private readonly IDictionary chainCerts = Platform.CreateHashtable(); private readonly IDictionary keyCerts = Platform.CreateHashtable(); private readonly DerObjectIdentifier keyAlgorithm; private readonly DerObjectIdentifier certAlgorithm; private readonly bool useDerEncoding; private AsymmetricKeyEntry unmarkedKeyEntry = null; public IEnumerable Aliases => new EnumerableProxy(GetAliasesTable().Keys); public int Count => GetAliasesTable().Count; private static SubjectKeyIdentifier CreateSubjectKeyID(AsymmetricKeyParameter pubKey) { return new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pubKey)); } internal Pkcs12Store(DerObjectIdentifier keyAlgorithm, DerObjectIdentifier certAlgorithm, bool useDerEncoding) { this.keyAlgorithm = keyAlgorithm; this.certAlgorithm = certAlgorithm; this.useDerEncoding = useDerEncoding; } public Pkcs12Store() : this(PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc, PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc, useDerEncoding: false) { } public Pkcs12Store(Stream input, char[] password) : this() { Load(input, password); } protected virtual void LoadKeyBag(PrivateKeyInfo privKeyInfo, Asn1Set bagAttributes) { AsymmetricKeyParameter key = PrivateKeyFactory.CreateKey(privKeyInfo); IDictionary dictionary = Platform.CreateHashtable(); AsymmetricKeyEntry value = new AsymmetricKeyEntry(key, dictionary); string text = null; Asn1OctetString asn1OctetString = null; if (bagAttributes != null) { foreach (Asn1Sequence bagAttribute in bagAttributes) { DerObjectIdentifier instance = DerObjectIdentifier.GetInstance(bagAttribute[0]); Asn1Set instance2 = Asn1Set.GetInstance(bagAttribute[1]); Asn1Encodable asn1Encodable = null; if (instance2.Count <= 0) { continue; } asn1Encodable = instance2[0]; if (dictionary.Contains(instance.Id)) { if (!dictionary[instance.Id].Equals(asn1Encodable)) { throw new IOException("attempt to add existing attribute with different value"); } } else { dictionary.Add(instance.Id, asn1Encodable); } if (instance.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName)) { text = ((DerBmpString)asn1Encodable).GetString(); keys[text] = value; } else if (instance.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID)) { asn1OctetString = (Asn1OctetString)asn1Encodable; } } } if (asn1OctetString != null) { string text2 = Hex.ToHexString(asn1OctetString.GetOctets()); if (text == null) { keys[text2] = value; } else { localIds[text] = text2; } } else { unmarkedKeyEntry = value; } } protected virtual void LoadPkcs8ShroudedKeyBag(EncryptedPrivateKeyInfo encPrivKeyInfo, Asn1Set bagAttributes, char[] password, bool wrongPkcs12Zero) { if (password != null) { PrivateKeyInfo privKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(password, wrongPkcs12Zero, encPrivKeyInfo); LoadKeyBag(privKeyInfo, bagAttributes); } } public void Load(Stream input, char[] password) { if (input == null) { throw new ArgumentNullException("input"); } Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromStream(input); Pfx pfx = new Pfx(seq); ContentInfo authSafe = pfx.AuthSafe; bool wrongPkcs12Zero = false; if (password != null && pfx.MacData != null) { MacData macData = pfx.MacData; DigestInfo mac = macData.Mac; AlgorithmIdentifier algorithmID = mac.AlgorithmID; byte[] salt = macData.GetSalt(); int intValue = macData.IterationCount.IntValue; byte[] octets = ((Asn1OctetString)authSafe.Content).GetOctets(); byte[] a = CalculatePbeMac(algorithmID.Algorithm, salt, intValue, password, wrongPkcs12Zero: false, octets); byte[] digest = mac.GetDigest(); if (!Arrays.ConstantTimeAreEqual(a, digest)) { if (password.Length > 0) { throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file."); } a = CalculatePbeMac(algorithmID.Algorithm, salt, intValue, password, wrongPkcs12Zero: true, octets); if (!Arrays.ConstantTimeAreEqual(a, digest)) { throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file."); } wrongPkcs12Zero = true; } } keys.Clear(); localIds.Clear(); unmarkedKeyEntry = null; IList list = Platform.CreateArrayList(); if (authSafe.ContentType.Equals(PkcsObjectIdentifiers.Data)) { byte[] octets2 = ((Asn1OctetString)authSafe.Content).GetOctets(); AuthenticatedSafe authenticatedSafe = new AuthenticatedSafe((Asn1Sequence)Asn1Object.FromByteArray(octets2)); ContentInfo[] contentInfo = authenticatedSafe.GetContentInfo(); ContentInfo[] array = contentInfo; foreach (ContentInfo contentInfo2 in array) { DerObjectIdentifier contentType = contentInfo2.ContentType; byte[] array2 = null; if (contentType.Equals(PkcsObjectIdentifiers.Data)) { array2 = ((Asn1OctetString)contentInfo2.Content).GetOctets(); } else if (contentType.Equals(PkcsObjectIdentifiers.EncryptedData) && password != null) { EncryptedData instance = EncryptedData.GetInstance(contentInfo2.Content); array2 = CryptPbeData(forEncryption: false, instance.EncryptionAlgorithm, password, wrongPkcs12Zero, instance.Content.GetOctets()); } if (array2 == null) { continue; } Asn1Sequence asn1Sequence = (Asn1Sequence)Asn1Object.FromByteArray(array2); foreach (Asn1Sequence item in asn1Sequence) { SafeBag safeBag = new SafeBag(item); if (safeBag.BagID.Equals(PkcsObjectIdentifiers.CertBag)) { list.Add(safeBag); } else if (safeBag.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag)) { LoadPkcs8ShroudedKeyBag(EncryptedPrivateKeyInfo.GetInstance(safeBag.BagValue), safeBag.BagAttributes, password, wrongPkcs12Zero); } else if (safeBag.BagID.Equals(PkcsObjectIdentifiers.KeyBag)) { LoadKeyBag(PrivateKeyInfo.GetInstance(safeBag.BagValue), safeBag.BagAttributes); } } } } certs.Clear(); chainCerts.Clear(); keyCerts.Clear(); foreach (SafeBag item2 in list) { CertBag certBag = new CertBag((Asn1Sequence)item2.BagValue); byte[] octets3 = ((Asn1OctetString)certBag.CertValue).GetOctets(); X509Certificate x509Certificate = new X509CertificateParser().ReadCertificate(octets3); IDictionary dictionary = Platform.CreateHashtable(); Asn1OctetString asn1OctetString = null; string text = null; if (item2.BagAttributes != null) { foreach (Asn1Sequence bagAttribute in item2.BagAttributes) { DerObjectIdentifier instance2 = DerObjectIdentifier.GetInstance(bagAttribute[0]); Asn1Set instance3 = Asn1Set.GetInstance(bagAttribute[1]); if (instance3.Count <= 0) { continue; } Asn1Encodable asn1Encodable = instance3[0]; if (dictionary.Contains(instance2.Id)) { if (!dictionary[instance2.Id].Equals(asn1Encodable)) { throw new IOException("attempt to add existing attribute with different value"); } } else { dictionary.Add(instance2.Id, asn1Encodable); } if (instance2.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName)) { text = ((DerBmpString)asn1Encodable).GetString(); } else if (instance2.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID)) { asn1OctetString = (Asn1OctetString)asn1Encodable; } } } CertId certId = new CertId(x509Certificate.GetPublicKey()); X509CertificateEntry value = new X509CertificateEntry(x509Certificate, dictionary); chainCerts[certId] = value; if (unmarkedKeyEntry != null) { if (keyCerts.Count == 0) { string text2 = Hex.ToHexString(certId.Id); keyCerts[text2] = value; keys[text2] = unmarkedKeyEntry; } else { keys["unmarked"] = unmarkedKeyEntry; } continue; } if (asn1OctetString != null) { string key = Hex.ToHexString(asn1OctetString.GetOctets()); keyCerts[key] = value; } if (text != null) { certs[text] = value; } } } public AsymmetricKeyEntry GetKey(string alias) { if (alias == null) { throw new ArgumentNullException("alias"); } return (AsymmetricKeyEntry)keys[alias]; } public bool IsCertificateEntry(string alias) { if (alias == null) { throw new ArgumentNullException("alias"); } if (certs[alias] != null) { return keys[alias] == null; } return false; } public bool IsKeyEntry(string alias) { if (alias == null) { throw new ArgumentNullException("alias"); } return keys[alias] != null; } private IDictionary GetAliasesTable() { IDictionary dictionary = Platform.CreateHashtable(); foreach (string key3 in certs.Keys) { dictionary[key3] = "cert"; } foreach (string key4 in keys.Keys) { if (dictionary[key4] == null) { dictionary[key4] = "key"; } } return dictionary; } public bool ContainsAlias(string alias) { if (certs[alias] == null) { return keys[alias] != null; } return true; } public X509CertificateEntry GetCertificate(string alias) { if (alias == null) { throw new ArgumentNullException("alias"); } X509CertificateEntry x509CertificateEntry = (X509CertificateEntry)certs[alias]; if (x509CertificateEntry == null) { string text = (string)localIds[alias]; x509CertificateEntry = ((text == null) ? ((X509CertificateEntry)keyCerts[alias]) : ((X509CertificateEntry)keyCerts[text])); } return x509CertificateEntry; } public string GetCertificateAlias(X509Certificate cert) { if (cert == null) { throw new ArgumentNullException("cert"); } foreach (object cert2 in certs) { DictionaryEntry dictionaryEntry = (DictionaryEntry)cert2; X509CertificateEntry x509CertificateEntry = (X509CertificateEntry)dictionaryEntry.Value; if (x509CertificateEntry.Certificate.Equals(cert)) { return (string)dictionaryEntry.Key; } } foreach (object keyCert in keyCerts) { DictionaryEntry dictionaryEntry2 = (DictionaryEntry)keyCert; X509CertificateEntry x509CertificateEntry2 = (X509CertificateEntry)dictionaryEntry2.Value; if (x509CertificateEntry2.Certificate.Equals(cert)) { return (string)dictionaryEntry2.Key; } } return null; } public X509CertificateEntry[] GetCertificateChain(string alias) { if (alias == null) { throw new ArgumentNullException("alias"); } if (!IsKeyEntry(alias)) { return null; } X509CertificateEntry x509CertificateEntry = GetCertificate(alias); if (x509CertificateEntry != null) { IList list = Platform.CreateArrayList(); while (x509CertificateEntry != null) { X509Certificate certificate = x509CertificateEntry.Certificate; X509CertificateEntry x509CertificateEntry2 = null; Asn1OctetString extensionValue = certificate.GetExtensionValue(X509Extensions.AuthorityKeyIdentifier); if (extensionValue != null) { AuthorityKeyIdentifier instance = AuthorityKeyIdentifier.GetInstance(Asn1Object.FromByteArray(extensionValue.GetOctets())); if (instance.GetKeyIdentifier() != null) { x509CertificateEntry2 = (X509CertificateEntry)chainCerts[new CertId(instance.GetKeyIdentifier())]; } } if (x509CertificateEntry2 == null) { X509Name issuerDN = certificate.IssuerDN; X509Name subjectDN = certificate.SubjectDN; if (!issuerDN.Equivalent(subjectDN)) { foreach (CertId key in chainCerts.Keys) { X509CertificateEntry x509CertificateEntry3 = (X509CertificateEntry)chainCerts[key]; X509Certificate certificate2 = x509CertificateEntry3.Certificate; X509Name subjectDN2 = certificate2.SubjectDN; if (subjectDN2.Equivalent(issuerDN)) { try { certificate.Verify(certificate2.GetPublicKey()); x509CertificateEntry2 = x509CertificateEntry3; } catch (InvalidKeyException) { continue; } break; } } } } list.Add(x509CertificateEntry); x509CertificateEntry = ((x509CertificateEntry2 == x509CertificateEntry) ? null : x509CertificateEntry2); } X509CertificateEntry[] array = new X509CertificateEntry[list.Count]; for (int i = 0; i < list.Count; i++) { array[i] = (X509CertificateEntry)list[i]; } return array; } return null; } public void SetCertificateEntry(string alias, X509CertificateEntry certEntry) { if (alias == null) { throw new ArgumentNullException("alias"); } if (certEntry == null) { throw new ArgumentNullException("certEntry"); } if (keys[alias] != null) { throw new ArgumentException("There is a key entry with the name " + alias + "."); } certs[alias] = certEntry; chainCerts[new CertId(certEntry.Certificate.GetPublicKey())] = certEntry; } public void SetKeyEntry(string alias, AsymmetricKeyEntry keyEntry, X509CertificateEntry[] chain) { if (alias == null) { throw new ArgumentNullException("alias"); } if (keyEntry == null) { throw new ArgumentNullException("keyEntry"); } if (keyEntry.Key.IsPrivate && chain == null) { throw new ArgumentException("No certificate chain for private key"); } if (keys[alias] != null) { DeleteEntry(alias); } keys[alias] = keyEntry; certs[alias] = chain[0]; for (int i = 0; i != chain.Length; i++) { chainCerts[new CertId(chain[i].Certificate.GetPublicKey())] = chain[i]; } } public void DeleteEntry(string alias) { if (alias == null) { throw new ArgumentNullException("alias"); } AsymmetricKeyEntry asymmetricKeyEntry = (AsymmetricKeyEntry)keys[alias]; if (asymmetricKeyEntry != null) { keys.Remove(alias); } X509CertificateEntry x509CertificateEntry = (X509CertificateEntry)certs[alias]; if (x509CertificateEntry != null) { certs.Remove(alias); chainCerts.Remove(new CertId(x509CertificateEntry.Certificate.GetPublicKey())); } if (asymmetricKeyEntry != null) { string text = (string)localIds[alias]; if (text != null) { localIds.Remove(alias); x509CertificateEntry = (X509CertificateEntry)keyCerts[text]; } if (x509CertificateEntry != null) { keyCerts.Remove(text); chainCerts.Remove(new CertId(x509CertificateEntry.Certificate.GetPublicKey())); } } if (x509CertificateEntry == null && asymmetricKeyEntry == null) { throw new ArgumentException("no such entry as " + alias); } } public bool IsEntryOfType(string alias, Type entryType) { if ((object)entryType == typeof(X509CertificateEntry)) { return IsCertificateEntry(alias); } if ((object)entryType == typeof(AsymmetricKeyEntry)) { if (IsKeyEntry(alias)) { return GetCertificate(alias) != null; } return false; } return false; } [Obsolete("Use 'Count' property instead")] public int Size() { return Count; } public void Save(Stream stream, char[] password, SecureRandom random) { if (stream == null) { throw new ArgumentNullException("stream"); } if (random == null) { throw new ArgumentNullException("random"); } Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector(); foreach (string key2 in keys.Keys) { byte[] array = new byte[20]; random.NextBytes(array); AsymmetricKeyEntry asymmetricKeyEntry = (AsymmetricKeyEntry)keys[key2]; DerObjectIdentifier oid; Asn1Encodable asn1Encodable; if (password == null) { oid = PkcsObjectIdentifiers.KeyBag; asn1Encodable = PrivateKeyInfoFactory.CreatePrivateKeyInfo(asymmetricKeyEntry.Key); } else { oid = PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag; asn1Encodable = EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(keyAlgorithm, password, array, 1024, asymmetricKeyEntry.Key); } Asn1EncodableVector asn1EncodableVector2 = new Asn1EncodableVector(); foreach (string bagAttributeKey in asymmetricKeyEntry.BagAttributeKeys) { Asn1Encodable obj = asymmetricKeyEntry[bagAttributeKey]; if (!bagAttributeKey.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id)) { asn1EncodableVector2.Add(new DerSequence(new DerObjectIdentifier(bagAttributeKey), new DerSet(obj))); } } asn1EncodableVector2.Add(new DerSequence(PkcsObjectIdentifiers.Pkcs9AtFriendlyName, new DerSet(new DerBmpString(key2)))); if (asymmetricKeyEntry[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null) { X509CertificateEntry certificate = GetCertificate(key2); AsymmetricKeyParameter publicKey = certificate.Certificate.GetPublicKey(); SubjectKeyIdentifier obj2 = CreateSubjectKeyID(publicKey); asn1EncodableVector2.Add(new DerSequence(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID, new DerSet(obj2))); } asn1EncodableVector.Add(new SafeBag(oid, asn1Encodable.ToAsn1Object(), new DerSet(asn1EncodableVector2))); } byte[] derEncoded = new DerSequence(asn1EncodableVector).GetDerEncoded(); ContentInfo contentInfo = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(derEncoded)); byte[] array2 = new byte[20]; random.NextBytes(array2); Asn1EncodableVector asn1EncodableVector3 = new Asn1EncodableVector(); Pkcs12PbeParams pkcs12PbeParams = new Pkcs12PbeParams(array2, 1024); AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(certAlgorithm, pkcs12PbeParams.ToAsn1Object()); ISet set = new HashSet(); foreach (string key3 in keys.Keys) { X509CertificateEntry certificate2 = GetCertificate(key3); CertBag certBag = new CertBag(PkcsObjectIdentifiers.X509Certificate, new DerOctetString(certificate2.Certificate.GetEncoded())); Asn1EncodableVector asn1EncodableVector4 = new Asn1EncodableVector(); foreach (string bagAttributeKey2 in certificate2.BagAttributeKeys) { Asn1Encodable obj3 = certificate2[bagAttributeKey2]; if (!bagAttributeKey2.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id)) { asn1EncodableVector4.Add(new DerSequence(new DerObjectIdentifier(bagAttributeKey2), new DerSet(obj3))); } } asn1EncodableVector4.Add(new DerSequence(PkcsObjectIdentifiers.Pkcs9AtFriendlyName, new DerSet(new DerBmpString(key3)))); if (certificate2[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null) { AsymmetricKeyParameter publicKey2 = certificate2.Certificate.GetPublicKey(); SubjectKeyIdentifier obj4 = CreateSubjectKeyID(publicKey2); asn1EncodableVector4.Add(new DerSequence(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID, new DerSet(obj4))); } asn1EncodableVector3.Add(new SafeBag(PkcsObjectIdentifiers.CertBag, certBag.ToAsn1Object(), new DerSet(asn1EncodableVector4))); set.Add(certificate2.Certificate); } foreach (string key4 in certs.Keys) { X509CertificateEntry x509CertificateEntry = (X509CertificateEntry)certs[key4]; if (keys[key4] != null) { continue; } CertBag certBag2 = new CertBag(PkcsObjectIdentifiers.X509Certificate, new DerOctetString(x509CertificateEntry.Certificate.GetEncoded())); Asn1EncodableVector asn1EncodableVector5 = new Asn1EncodableVector(); foreach (string bagAttributeKey3 in x509CertificateEntry.BagAttributeKeys) { if (!bagAttributeKey3.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Id)) { Asn1Encodable obj5 = x509CertificateEntry[bagAttributeKey3]; if (!bagAttributeKey3.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id)) { asn1EncodableVector5.Add(new DerSequence(new DerObjectIdentifier(bagAttributeKey3), new DerSet(obj5))); } } } asn1EncodableVector5.Add(new DerSequence(PkcsObjectIdentifiers.Pkcs9AtFriendlyName, new DerSet(new DerBmpString(key4)))); asn1EncodableVector3.Add(new SafeBag(PkcsObjectIdentifiers.CertBag, certBag2.ToAsn1Object(), new DerSet(asn1EncodableVector5))); set.Add(x509CertificateEntry.Certificate); } foreach (CertId key5 in chainCerts.Keys) { X509CertificateEntry x509CertificateEntry2 = (X509CertificateEntry)chainCerts[key5]; if (set.Contains(x509CertificateEntry2.Certificate)) { continue; } CertBag certBag3 = new CertBag(PkcsObjectIdentifiers.X509Certificate, new DerOctetString(x509CertificateEntry2.Certificate.GetEncoded())); Asn1EncodableVector asn1EncodableVector6 = new Asn1EncodableVector(); foreach (string bagAttributeKey4 in x509CertificateEntry2.BagAttributeKeys) { if (!bagAttributeKey4.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Id)) { asn1EncodableVector6.Add(new DerSequence(new DerObjectIdentifier(bagAttributeKey4), new DerSet(x509CertificateEntry2[bagAttributeKey4]))); } } asn1EncodableVector3.Add(new SafeBag(PkcsObjectIdentifiers.CertBag, certBag3.ToAsn1Object(), new DerSet(asn1EncodableVector6))); } byte[] derEncoded2 = new DerSequence(asn1EncodableVector3).GetDerEncoded(); ContentInfo contentInfo2; if (password == null) { contentInfo2 = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(derEncoded2)); } else { byte[] str = CryptPbeData(forEncryption: true, algorithmIdentifier, password, wrongPkcs12Zero: false, derEncoded2); EncryptedData encryptedData = new EncryptedData(PkcsObjectIdentifiers.Data, algorithmIdentifier, new BerOctetString(str)); contentInfo2 = new ContentInfo(PkcsObjectIdentifiers.EncryptedData, encryptedData.ToAsn1Object()); } ContentInfo[] info = new ContentInfo[2] { contentInfo, contentInfo2 }; byte[] encoded = new AuthenticatedSafe(info).GetEncoded(useDerEncoding ? "DER" : "BER"); ContentInfo contentInfo3 = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(encoded)); MacData macData = null; if (password != null) { byte[] array3 = new byte[20]; random.NextBytes(array3); byte[] digest = CalculatePbeMac(OiwObjectIdentifiers.IdSha1, array3, 1024, password, wrongPkcs12Zero: false, encoded); AlgorithmIdentifier algID = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance); DigestInfo digInfo = new DigestInfo(algID, digest); macData = new MacData(digInfo, array3, 1024); } Pfx obj6 = new Pfx(contentInfo3, macData); DerOutputStream derOutputStream = ((!useDerEncoding) ? new BerOutputStream(stream) : new DerOutputStream(stream)); derOutputStream.WriteObject(obj6); } internal static byte[] CalculatePbeMac(DerObjectIdentifier oid, byte[] salt, int itCount, char[] password, bool wrongPkcs12Zero, byte[] data) { Asn1Encodable pbeParameters = PbeUtilities.GenerateAlgorithmParameters(oid, salt, itCount); ICipherParameters parameters = PbeUtilities.GenerateCipherParameters(oid, password, wrongPkcs12Zero, pbeParameters); IMac mac = (IMac)PbeUtilities.CreateEngine(oid); mac.Init(parameters); return MacUtilities.DoFinal(mac, data); } private static byte[] CryptPbeData(bool forEncryption, AlgorithmIdentifier algId, char[] password, bool wrongPkcs12Zero, byte[] data) { if (!(PbeUtilities.CreateEngine(algId.Algorithm) is IBufferedCipher bufferedCipher)) { throw new Exception("Unknown encryption algorithm: " + algId.Algorithm); } Pkcs12PbeParams instance = Pkcs12PbeParams.GetInstance(algId.Parameters); ICipherParameters parameters = PbeUtilities.GenerateCipherParameters(algId.Algorithm, password, wrongPkcs12Zero, instance); bufferedCipher.Init(forEncryption, parameters); return bufferedCipher.DoFinal(data); } }