<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.1" />

MiscPemGenerator

using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cms; using Org.BouncyCastle.Asn1.CryptoPro; using Org.BouncyCastle.Asn1.Oiw; using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Asn1.X9; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Math; using Org.BouncyCastle.Pkcs; using Org.BouncyCastle.Security; using Org.BouncyCastle.Security.Certificates; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Encoders; using Org.BouncyCastle.Utilities.IO.Pem; using Org.BouncyCastle.X509; using System; using System.Collections.Generic; using System.IO; namespace Org.BouncyCastle.OpenSsl { public class MiscPemGenerator : PemObjectGenerator { private readonly object obj; private readonly string algorithm; private readonly char[] password; private readonly SecureRandom random; public MiscPemGenerator(object obj) : this(obj, null, null, null) { } public MiscPemGenerator(object obj, string algorithm, char[] password, SecureRandom random) { this.obj = obj; this.algorithm = algorithm; this.password = password; this.random = random; } private static PemObject CreatePemObject(object obj) { if (obj == null) throw new ArgumentNullException("obj"); AsymmetricCipherKeyPair asymmetricCipherKeyPair = obj as AsymmetricCipherKeyPair; if (asymmetricCipherKeyPair != null) return CreatePemObject(asymmetricCipherKeyPair.Private); PemObject pemObject = obj as PemObject; if (pemObject != null) return pemObject; PemObjectGenerator pemObjectGenerator = obj as PemObjectGenerator; if (pemObjectGenerator != null) return pemObjectGenerator.Generate(); X509Certificate x509Certificate = obj as X509Certificate; string keyType; byte[] content; if (x509Certificate != null) { keyType = "CERTIFICATE"; try { content = x509Certificate.GetEncoded(); } catch (CertificateEncodingException ex) { throw new IOException("Cannot Encode object: " + ex.ToString()); } } else { X509Crl x509Crl = obj as X509Crl; if (x509Crl != null) { keyType = "X509 CRL"; try { content = x509Crl.GetEncoded(); } catch (CrlException ex2) { throw new IOException("Cannot Encode object: " + ex2.ToString()); } } else { AsymmetricKeyParameter asymmetricKeyParameter = obj as AsymmetricKeyParameter; if (asymmetricKeyParameter != null) content = ((!asymmetricKeyParameter.IsPrivate) ? EncodePublicKey(asymmetricKeyParameter, out keyType) : EncodePrivateKey(asymmetricKeyParameter, out keyType)); else { PrivateKeyInfo privateKeyInfo = obj as PrivateKeyInfo; if (privateKeyInfo != null) content = EncodePrivateKeyInfo(privateKeyInfo, out keyType); else { SubjectPublicKeyInfo subjectPublicKeyInfo = obj as SubjectPublicKeyInfo; if (subjectPublicKeyInfo != null) content = EncodePublicKeyInfo(subjectPublicKeyInfo, out keyType); else { X509V2AttributeCertificate x509V2AttributeCertificate = obj as X509V2AttributeCertificate; if (x509V2AttributeCertificate != null) { keyType = "ATTRIBUTE CERTIFICATE"; content = x509V2AttributeCertificate.GetEncoded(); } else { Pkcs8EncryptedPrivateKeyInfo pkcs8EncryptedPrivateKeyInfo = obj as Pkcs8EncryptedPrivateKeyInfo; if (pkcs8EncryptedPrivateKeyInfo != null) { keyType = "ENCRYPTED PRIVATE KEY"; content = pkcs8EncryptedPrivateKeyInfo.GetEncoded(); } else { Pkcs10CertificationRequest pkcs10CertificationRequest = obj as Pkcs10CertificationRequest; if (pkcs10CertificationRequest != null) { keyType = "CERTIFICATE REQUEST"; content = pkcs10CertificationRequest.GetEncoded(); } else { Org.BouncyCastle.Asn1.Cms.ContentInfo contentInfo = obj as Org.BouncyCastle.Asn1.Cms.ContentInfo; if (contentInfo != null) { keyType = "PKCS7"; content = contentInfo.GetEncoded(); } else { Org.BouncyCastle.Asn1.Pkcs.ContentInfo contentInfo2 = obj as Org.BouncyCastle.Asn1.Pkcs.ContentInfo; if (contentInfo2 == null) throw new PemGenerationException("Object type not supported: " + Platform.GetTypeName(obj)); keyType = "PKCS7"; content = contentInfo2.GetEncoded(); } } } } } } } } } return new PemObject(keyType, content); } private static PemObject CreatePemObject(object obj, string algorithm, char[] password, SecureRandom random) { if (obj == null) throw new ArgumentNullException("obj"); if (algorithm == null) throw new ArgumentNullException("algorithm"); if (password == null) throw new ArgumentNullException("password"); if (random == null) throw new ArgumentNullException("random"); AsymmetricCipherKeyPair asymmetricCipherKeyPair = obj as AsymmetricCipherKeyPair; if (asymmetricCipherKeyPair != null) return CreatePemObject(asymmetricCipherKeyPair.Private, algorithm, password, random); string keyType = null; byte[] array = null; AsymmetricKeyParameter asymmetricKeyParameter = obj as AsymmetricKeyParameter; if (asymmetricKeyParameter != null && asymmetricKeyParameter.IsPrivate) array = EncodePrivateKey(asymmetricKeyParameter, out keyType); if (keyType == null || array == null) throw new PemGenerationException("Object type not supported: " + Platform.GetTypeName(obj)); string text = algorithm.ToUpperInvariant(); if (text == "DESEDE") text = "DES-EDE3-CBC"; byte[] array2 = new byte[Platform.StartsWith(text, "AES-") ? 16 : 8]; random.NextBytes(array2); byte[] content = PemUtilities.Crypt(true, array, password, text, array2); List<PemHeader> list = new List<PemHeader>(2); list.Add(new PemHeader("Proc-Type", "4,ENCRYPTED")); list.Add(new PemHeader("DEK-Info", text + "," + Hex.ToHexString(array2, true))); return new PemObject(keyType, list, content); } public PemObject Generate() { try { if (algorithm == null) return CreatePemObject(obj); return CreatePemObject(obj, algorithm, password, random); } catch (IOException innerException) { throw new PemGenerationException("encoding exception", innerException); } } private static byte[] EncodePrivateKey(AsymmetricKeyParameter akp, out string keyType) { return EncodePrivateKeyInfo(PrivateKeyInfoFactory.CreatePrivateKeyInfo(akp), out keyType); } private static byte[] EncodePrivateKeyInfo(PrivateKeyInfo info, out string keyType) { AlgorithmIdentifier privateKeyAlgorithm = info.PrivateKeyAlgorithm; DerObjectIdentifier derObjectIdentifier = privateKeyAlgorithm.Algorithm; if (derObjectIdentifier.Equals(PkcsObjectIdentifiers.RsaEncryption)) { keyType = "RSA PRIVATE KEY"; return info.ParsePrivateKey().GetEncoded(); } if (derObjectIdentifier.Equals(X9ObjectIdentifiers.IdECPublicKey) || derObjectIdentifier.Equals(CryptoProObjectIdentifiers.GostR3410x2001)) { keyType = "EC PRIVATE KEY"; return info.ParsePrivateKey().GetEncoded(); } if (derObjectIdentifier.Equals(X9ObjectIdentifiers.IdDsa) || derObjectIdentifier.Equals(OiwObjectIdentifiers.DsaWithSha1)) { keyType = "DSA PRIVATE KEY"; DsaParameter instance = DsaParameter.GetInstance(privateKeyAlgorithm.Parameters); BigInteger value = DerInteger.GetInstance(info.ParsePrivateKey()).Value; BigInteger value2 = instance.G.ModPow(value, instance.P); return new DerSequence(DerInteger.Zero, new DerInteger(instance.P), new DerInteger(instance.Q), new DerInteger(instance.G), new DerInteger(value2), new DerInteger(value)).GetEncoded(); } keyType = "PRIVATE KEY"; return info.GetEncoded(); } private static byte[] EncodePublicKey(AsymmetricKeyParameter akp, out string keyType) { return EncodePublicKeyInfo(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(akp), out keyType); } private static byte[] EncodePublicKeyInfo(SubjectPublicKeyInfo info, out string keyType) { keyType = "PUBLIC KEY"; return info.GetEncoded(); } } }