コード例 #1
1
        //---------------------------------------私钥转换
        public static void getPriKeyPem()
        {
            var rsa = new RSACryptoServiceProvider();
            using (var sr = new StreamReader("E:\\PriKey.xml"))
            {
                rsa.FromXmlString(sr.ReadToEnd());
            }
            var p = rsa.ExportParameters(true);

            var key = new RsaPrivateCrtKeyParameters(
                new BigInteger(1, p.Modulus), new BigInteger(1, p.Exponent), new BigInteger(1, p.D),
                new BigInteger(1, p.P), new BigInteger(1, p.Q), new BigInteger(1, p.DP), new BigInteger(1, p.DQ),
                new BigInteger(1, p.InverseQ));

            using (var sw = new StreamWriter("e:\\PriKey.pem"))
            {
                var pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(sw);
                pemWriter.WriteObject(key);
            }
        }
コード例 #2
0
 private static string GimmeKey(AsymmetricKeyParameter key)
 {
     var sb = new StringBuilder();
     using (var prvSw = new StringWriter(sb)) {
         var pmw = new Org.BouncyCastle.OpenSsl.PemWriter(prvSw);
         pmw.WriteObject(key);
     }
     return sb.ToString();
 }
コード例 #3
0
ファイル: RSAHelper.cs プロジェクト: JieWenDC/JW.RequestRelay
        /// <summary>
        /// XML格式私钥转换PEM格式
        /// </summary>
        public static string XMLPrivatekeyToPEM(string xml)
        {
            var rsa2 = new RSACryptoServiceProvider();

            rsa2.FromXmlString(xml);
            var p   = rsa2.ExportParameters(true);
            var key = new RsaPrivateCrtKeyParameters(
                new BigInteger(1, p.Modulus), new BigInteger(1, p.Exponent), new BigInteger(1, p.D),
                new BigInteger(1, p.P), new BigInteger(1, p.Q), new BigInteger(1, p.DP), new BigInteger(1, p.DQ),
                new BigInteger(1, p.InverseQ));

            using (MemoryStream stream = new MemoryStream())
            {
                using (var sw = new StreamWriter(stream, Encoding.UTF8))
                {
                    var pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(sw);
                    pemWriter.WriteObject(key);
                    sw.Flush();
                    var ret = System.Text.Encoding.UTF8.GetString(stream.ToArray());
                    return(ret);
                }
            }
        }
コード例 #4
0
        public static string GetPrivatePemString(RSAParameters p)
        {
            var key = new RsaPrivateCrtKeyParameters(
              new BigInteger(1, p.Modulus),
              new BigInteger(1, p.Exponent),
              new BigInteger(1, p.D),
              new BigInteger(1, p.P),
              new BigInteger(1, p.Q),
              new BigInteger(1, p.DP),
              new BigInteger(1, p.DQ),
              new BigInteger(1, p.InverseQ));

            using (var stream = new MemoryStream())
            {
                using (var writer = new StreamWriter(stream, new UTF8Encoding()))
                {
                    var pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(writer);
                    pemWriter.WriteObject(key);
                }

                return new UTF8Encoding().GetString(stream.ToArray()).Replace("\r\n", "\n");
            }
        }
コード例 #5
0
        /// <summary>
        /// Creates a new X509 certificate and returns its data in PEM format.
        ///
        /// <see cref="PatchingCertificatePem"/> is generated using this method.
        /// </summary>
        public string GenerateNewCertificatePem()
        {
            var randomGenerator      = new CryptoApiRandomGenerator();
            var random               = new SecureRandom(randomGenerator);
            var certificateGenerator = new X509V3CertificateGenerator();
            var serialNumber         = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);

            certificateGenerator.SetSerialNumber(serialNumber);

            // TODO: Figure out ISignatureFactory to avoid these deprecated methods
#pragma warning disable 618
            certificateGenerator.SetSignatureAlgorithm("SHA256WithRSA");
#pragma warning restore 618
            var subjectDn = new X509Name("cn=Unknown");
            var issuerDn  = subjectDn;
            certificateGenerator.SetIssuerDN(issuerDn);
            certificateGenerator.SetSubjectDN(subjectDn);
            certificateGenerator.SetNotBefore(DateTime.UtcNow.Date.AddYears(-10));
            certificateGenerator.SetNotAfter(DateTime.UtcNow.Date.AddYears(50));
            var keyGenerationParameters = new KeyGenerationParameters(random, 2048);
            var keyPairGenerator        = new RsaKeyPairGenerator();
            keyPairGenerator.Init(keyGenerationParameters);
            var subjectKeyPair = keyPairGenerator.GenerateKeyPair();
            certificateGenerator.SetPublicKey(subjectKeyPair.Public);

            // TODO: Figure out ISignatureFactory to avoid these deprecated methods
#pragma warning disable 618
            X509Certificate cert = certificateGenerator.Generate(subjectKeyPair.Private);
#pragma warning restore 618

            using var writer = new StringWriter();
            var pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(writer);

            pemWriter.WriteObject(new PemObject("CERTIFICATE", cert.GetEncoded()));
            pemWriter.WriteObject(subjectKeyPair.Private);
            return(writer.ToString());
        }
コード例 #6
0
        /// <summary>
        ///  XML格式私钥转PEM
        /// </summary>
        /// <param name="xml">XML格式私钥</param>
        /// <param name="saveFile">保存文件的物理路径</param>
        public static string Xml2PemPrivate(string xml, string saveFile)
        {
            var rsa = new RSACryptoServiceProvider();

            rsa.FromXmlString(xml);
            var p   = rsa.ExportParameters(true);
            var key = new RsaPrivateCrtKeyParameters(
                new BigInteger(1, p.Modulus), new BigInteger(1, p.Exponent), new BigInteger(1, p.D),
                new BigInteger(1, p.P), new BigInteger(1, p.Q), new BigInteger(1, p.DP), new BigInteger(1, p.DQ),
                new BigInteger(1, p.InverseQ));

            using (var sw = new StreamWriter(saveFile))
            {
                var pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(sw);
                pemWriter.WriteObject(key);
            }

            PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(key);

            byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetEncoded();
            string privateKey             = Convert.ToBase64String(serializedPrivateBytes);

            return(Format(privateKey, 2));
        }
コード例 #7
0
        // http://stackoverflow.com/questions/36942094/how-can-i-generate-a-self-signed-cert-without-using-obsolete-bouncycastle-1-7-0
        public static System.Security.Cryptography.X509Certificates.X509Certificate2 CreateX509Cert2(string certName)
        {
            var keypairgen = new Org.BouncyCastle.Crypto.Generators.RsaKeyPairGenerator();

            keypairgen.Init(new Org.BouncyCastle.Crypto.KeyGenerationParameters(
                                new Org.BouncyCastle.Security.SecureRandom(
                                    new Org.BouncyCastle.Crypto.Prng.CryptoApiRandomGenerator()
                                    )
                                , 1024
                                //, 512
                                )
                            );

            Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair keypair = keypairgen.GenerateKeyPair();

            // --- Until here we generate a keypair



            var random = new Org.BouncyCastle.Security.SecureRandom(
                new Org.BouncyCastle.Crypto.Prng.CryptoApiRandomGenerator()
                );


            // SHA1WITHRSA
            // SHA256WITHRSA
            // SHA384WITHRSA
            // SHA512WITHRSA

            // SHA1WITHECDSA
            // SHA224WITHECDSA
            // SHA256WITHECDSA
            // SHA384WITHECDSA
            // SHA512WITHECDSA

            Org.BouncyCastle.Crypto.ISignatureFactory signatureFactory =
                new Org.BouncyCastle.Crypto.Operators.Asn1SignatureFactory("SHA512WITHRSA", keypair.Private, random)
            ;



            var gen = new Org.BouncyCastle.X509.X509V3CertificateGenerator();


            var CN = new Org.BouncyCastle.Asn1.X509.X509Name("CN=" + certName);
            var SN = Org.BouncyCastle.Math.BigInteger.ProbablePrime(120, new Random());

            gen.SetSerialNumber(SN);
            gen.SetSubjectDN(CN);
            gen.SetIssuerDN(CN);
            gen.SetNotAfter(DateTime.Now.AddYears(1));
            gen.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0)));
            gen.SetPublicKey(keypair.Public);


            // -- Are these necessary ?

            // public static readonly DerObjectIdentifier AuthorityKeyIdentifier = new DerObjectIdentifier("2.5.29.35");
            // OID value: 2.5.29.35
            // OID description: id-ce-authorityKeyIdentifier
            // This extension may be used either as a certificate or CRL extension.
            // It identifies the public key to be used to verify the signature on this certificate or CRL.
            // It enables distinct keys used by the same CA to be distinguished (e.g., as key updating occurs).


            // http://stackoverflow.com/questions/14930381/generating-x509-certificate-using-bouncy-castle-java
            gen.AddExtension(
                Org.BouncyCastle.Asn1.X509.X509Extensions.AuthorityKeyIdentifier.Id,
                false,
                new Org.BouncyCastle.Asn1.X509.AuthorityKeyIdentifier(
                    Org.BouncyCastle.X509.SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keypair.Public),
                    new Org.BouncyCastle.Asn1.X509.GeneralNames(new Org.BouncyCastle.Asn1.X509.GeneralName(CN)),
                    SN
                    ));

            // OID value: 1.3.6.1.5.5.7.3.1
            // OID description: Indicates that a certificate can be used as an SSL server certificate.
            gen.AddExtension(
                Org.BouncyCastle.Asn1.X509.X509Extensions.ExtendedKeyUsage.Id,
                false,
                new Org.BouncyCastle.Asn1.X509.ExtendedKeyUsage(
                    new System.Collections.Generic.List <object>()
            {
                new Org.BouncyCastle.Asn1.DerObjectIdentifier("1.3.6.1.5.5.7.3.1")
            }
                    )
                );


            gen.AddExtension(
                new Org.BouncyCastle.Asn1.DerObjectIdentifier("2.5.29.19"),
                false,
                new Org.BouncyCastle.Asn1.X509.BasicConstraints(false) // true if it is allowed to sign other certs
                );

            gen.AddExtension(
                new Org.BouncyCastle.Asn1.DerObjectIdentifier("2.5.29.15"),
                true,
                new Org.BouncyCastle.X509.X509KeyUsage(
                    Org.BouncyCastle.X509.X509KeyUsage.DigitalSignature |
                    Org.BouncyCastle.X509.X509KeyUsage.NonRepudiation |
                    Org.BouncyCastle.X509.X509KeyUsage.KeyEncipherment |
                    Org.BouncyCastle.X509.X509KeyUsage.DataEncipherment)
                );


            // -- End are these necessary ?

            Org.BouncyCastle.X509.X509Certificate bouncyCert = gen.Generate(signatureFactory);
            // Org.BouncyCastle.X509.X509Certificate bouncyCert = gen.Generate(keypair.Private);

            bouncyCert.GetPublicKey();

            byte[] ba = bouncyCert.GetEncoded();

            using (System.IO.TextWriter textWriter = new System.IO.StringWriter())
            {
                Org.BouncyCastle.OpenSsl.PemWriter pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(textWriter);

                pemWriter.WriteObject(bouncyCert);
                pemWriter.WriteObject(keypair.Private);
                pemWriter.Writer.Flush();

                string privateKey = textWriter.ToString();
                System.Console.WriteLine(privateKey);
            } // End Using textWriter


            string certFile = @"D:\mycert.cert";

            using (System.IO.FileStream fs = System.IO.File.OpenWrite(certFile))
            {
                using (System.IO.TextWriter textWriter = new System.IO.StreamWriter(fs))
                {
                    Org.BouncyCastle.OpenSsl.PemWriter pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(textWriter);

                    pemWriter.WriteObject(bouncyCert);
                    pemWriter.WriteObject(keypair.Private);
                    pemWriter.Writer.Flush();

                    string privateKey = textWriter.ToString();
                    System.Console.WriteLine(privateKey);
                } // End Using textWriter
            }     // End Using fs


            // https://github.com/dotnet/corefx/blob/master/src/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Certificate.cs
            // https://github.com/dotnet/corefx/blob/master/src/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Certificate2.cs



            // System.Security.Cryptography.X509Certificates.X509Certificate2 msCert = new System.Security.Cryptography.X509Certificates.X509Certificate2(ba);
            System.Security.Cryptography.X509Certificates.X509Certificate2 msCert =
                new System.Security.Cryptography.X509Certificates
                .X509Certificate2(ba, null
                                  , System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable


                                  // System.Security.Cryptography.X509Certificates.X509KeyStorageFlag.PersistKeySet |
                                  // System.Security.Cryptography.X509Certificates.X509KeyStorageFlag.MachineKeySet |
                                  // System.Security.Cryptography.X509Certificates.X509KeyStorageFlag.Exportable
                                  );

            msCert = new X509Certificate2(certFile, null, X509KeyStorageFlags.MachineKeySet);
            object obj = msCert.GetRSAPrivateKey();

            System.Console.WriteLine(obj);

            if (msCert.HasPrivateKey)
            {
                Console.WriteLine(msCert.HasPrivateKey);
            }

            return(msCert);
        }
コード例 #8
0
        } // End Function GenerateEcdsaKeyPair

        public static void WritePrivatePublic(Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair keyPair)
        {
            string privateKey = null;
            string publicKey  = null;
            string bothKeys   = null;

            // id_rsa
            using (System.IO.TextWriter textWriter = new System.IO.StringWriter())
            {
                Org.BouncyCastle.OpenSsl.PemWriter pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(textWriter);
                pemWriter.WriteObject(keyPair.Private);
                pemWriter.Writer.Flush();

                privateKey = textWriter.ToString();
            } // End Using textWriter

            // id_rsa.pub
            using (System.IO.TextWriter textWriter = new System.IO.StringWriter())
            {
                Org.BouncyCastle.OpenSsl.PemWriter pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(textWriter);
                pemWriter.WriteObject(keyPair.Public);
                pemWriter.Writer.Flush();

                publicKey = textWriter.ToString();
            } // End Using textWriter


            // // This writes the same as private key, not both
            //using (System.IO.TextWriter textWriter = new System.IO.StringWriter())
            //{
            //    Org.BouncyCastle.OpenSsl.PemWriter pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(textWriter);
            //    pemWriter.WriteObject(keyPair);
            //    pemWriter.Writer.Flush();

            //    bothKeys = textWriter.ToString();
            //} // End Using textWriter

            System.Console.WriteLine(privateKey);
            System.Console.WriteLine(publicKey);
            //System.Console.WriteLine(bothKeys);


            // Org.BouncyCastle.Crypto.AsymmetricKeyParameter pk = ReadPrivateKey(privateKey);
            // Org.BouncyCastle.Crypto.AsymmetricKeyParameter pubKey = ReadPublicKey(publicKey);

            // ReadPublicKey(privateKey); // Cannot read this
            // ReadPrivateKey(publicKey); // Cannot read this either...
            ReadPublicKey(publicKey);
            // ReadPrivateKey(publicKey);
            Org.BouncyCastle.Crypto.AsymmetricKeyParameter privKey = ReadPrivateKey(privateKey);


            byte[] value = System.Text.Encoding.UTF8.GetBytes("hello world");

            // Org.BouncyCastle.Crypto.Parameters.ECPrivateKeyParameters privKey = pk; // key.EcPrivateKey;
            Org.BouncyCastle.Crypto.ISigner signer =
                // https://github.com/neoeinstein/bouncycastle/blob/master/crypto/src/security/SignerUtilities.cs
                Org.BouncyCastle.Security.SignerUtilities.GetSigner("SHA-256withECDSA");

            signer.Init(true, privKey);
            signer.BlockUpdate(value, 0, value.Length);
            byte[] signature = signer.GenerateSignature();
            System.Console.WriteLine(signature);
        } // End Sub WritePrivatePublic
コード例 #9
0
        }         // End Sub WriteCerAndCrt

        public static void Test()
        {
            Org.BouncyCastle.Asn1.X509.X509Name caName      = new Org.BouncyCastle.Asn1.X509.X509Name("CN=TestCA");
            Org.BouncyCastle.Asn1.X509.X509Name eeName      = new Org.BouncyCastle.Asn1.X509.X509Name("CN=TestEE");
            Org.BouncyCastle.Asn1.X509.X509Name eeName25519 = new Org.BouncyCastle.Asn1.X509.X509Name("CN=TestEE25519");

            string countryIso2Characters = "EA";
            string stateOrProvince       = "ERA";
            string localityOrCity        = "NeutralZone";
            string companyName           = "Skynet Earth Inc.";
            string division   = "Skynet mbH";
            string domainName = "sky.net";
            string email      = "*****@*****.**";


            Org.BouncyCastle.Asn1.X509.X509Name subj = CertificateInfo.CreateSubject(
                countryIso2Characters, stateOrProvince
                , localityOrCity, companyName
                , division, domainName, email);

            System.Console.WriteLine(subj);


            Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair caKey25519 = KeyGenerator.GenerateEcKeyPair("curve25519", s_secureRandom.Value);
            Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair caKey      = KeyGenerator.GenerateEcKeyPair("secp256r1", s_secureRandom.Value);
            Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair eeKey      = KeyGenerator.GenerateRsaKeyPair(2048, s_secureRandom.Value);


            string publicKey = null;

            // id_rsa.pub
            using (System.IO.TextWriter textWriter = new System.IO.StringWriter())
            {
                Org.BouncyCastle.OpenSsl.PemWriter pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(textWriter);
                pemWriter.WriteObject(eeKey);
                pemWriter.Writer.Flush();

                publicKey = textWriter.ToString();
            } // End Using textWriter

            System.Console.WriteLine(publicKey);


            // https://social.msdn.microsoft.com/Forums/vstudio/de-DE/8d49a681-22c6-417f-af3c-8daebd6f10dd/signierung-eines-hashs-mit-ellipticcurve-crypto?forum=visualcsharpde
            // https://stackoverflow.com/questions/22963581/reading-elliptic-curve-private-key-from-file-with-bouncycastle/41947163
            // PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(pkcs8key);

            // The EC PARAMETERS block in your file is an accident of the way openssl ecparam - genkey works by default;
            // it is not needed or used as part of the actual key and you can omit it by specifying - noout
            // which is admittedly somewhat unobvious.
            // The actual key structure('hidden' in the base64/ DER data) for EC(DSA / DH)
            // does contain some parameter info which RSA doesn't but DSA does.
            PrivatePublicPemKeyPair keyPair = KeyImportExport.GetPemKeyPair(caKey25519);

            // PrivatePublicPemKeyPair keyPair = PrivatePublicPemKeyPair.ImportFrom("", "");


            Org.BouncyCastle.X509.X509Certificate caCert      = GenerateCertificate(caName, caName, caKey.Private, caKey.Public, s_secureRandom.Value);
            Org.BouncyCastle.X509.X509Certificate eeCert      = GenerateCertificate(caName, eeName, caKey.Private, eeKey.Public, s_secureRandom.Value);
            Org.BouncyCastle.X509.X509Certificate ee25519Cert = GenerateCertificate(caName, eeName25519, caKey25519.Private, caKey25519.Public, s_secureRandom.Value);


            bool caOk    = ValidateSelfSignedCert(caCert, caKey.Public);
            bool eeOk    = ValidateSelfSignedCert(eeCert, caKey.Public);
            bool ee25519 = ValidateSelfSignedCert(eeCert, caKey.Public);

            PfxGenerator.CreatePfxFile("example.pfx", caCert, caKey.Private, null);

            // System.IO.File.WriteAllBytes("fileName", caCert.Export(X509ContentType.Pkcs12, PfxPassword));

            // https://info.ssl.com/how-to-der-vs-crt-vs-cer-vs-pem-certificates-and-how-to-conver-them/
            // The file extensions .CRT and .CER are interchangeable.
            // If your server requires that you use the .CER file extension, you can change the extension
            // http://www.networksolutions.com/support/what-is-the-difference-between-a-crt-and-a-cer-file/
            // https://stackoverflow.com/questions/642284/apache-with-ssl-how-to-convert-cer-to-crt-certificates
            // File extensions for cryptographic certificates aren't really as standardized as you'd expect.
            // Windows by default treats double - clicking a.crt file as a request to import the certificate
            // So, they're different in that sense, at least, that Windows has some inherent different meaning
            // for what happens when you double click each type of file.

            // One is a "binary" X.509 encoding, and the other is a "text" base64 encoding that usually starts with "-----BEGIN CERTIFICATE-----".
            // into the Windows Root Certificate store, but treats a.cer file as a request just to view the certificate.
            // CER is an X.509 certificate in binary form, DER encoded
            // CRT is a binary X.509 certificate, encapsulated in text (base-64) encoding
            // Most systems accept both formats, but if you need to you can convert one to the other via openssl
            // Certificate file should be PEM-encoded X.509 Certificate file:
            // openssl x509 -inform DER -in certificate.cer -out certificate.pem
            using (System.IO.Stream f = System.IO.File.Open("ca.cer", System.IO.FileMode.Create))
            {
                byte[] buf = caCert.GetEncoded();
                f.Write(buf, 0, buf.Length);
                f.Flush();
            }

            using (System.IO.Stream fs = System.IO.File.Open("ee.cer", System.IO.FileMode.Create))
            {
                byte[] buf = eeCert.GetEncoded();
                fs.Write(buf, 0, buf.Length);
                fs.Flush();
            } // End Using fs

            using (System.IO.Stream fs = System.IO.File.Open("ee25519.cer", System.IO.FileMode.Create))
            {
                byte[] buf = ee25519Cert.GetEncoded();
                fs.Write(buf, 0, buf.Length);
                fs.Flush();
            } // End Using fs

            // new System.Text.ASCIIEncoding(false)
            // new System.Text.UTF8Encoding(false)
            using (System.IO.Stream fs = System.IO.File.Open("ee.crt", System.IO.FileMode.Create))
            {
                using (System.IO.StreamWriter sw = new System.IO.StreamWriter(fs, System.Text.Encoding.ASCII))
                {
                    byte[] buf = eeCert.GetEncoded();
                    string pem = ToPem(buf);

                    sw.Write(pem);
                } // End Using sw
            }     // End Using fs

            using (System.IO.Stream fs = System.IO.File.Open("ee25519.crt", System.IO.FileMode.Create))
            {
                using (System.IO.StreamWriter sw = new System.IO.StreamWriter(fs, System.Text.Encoding.ASCII))
                {
                    byte[] buf = ee25519Cert.GetEncoded();
                    string pem = ToPem(buf);

                    sw.Write(pem);
                } // End Using sw
            }     // End Using fs

            Org.BouncyCastle.Asn1.X509.X509Name subject = eeName25519;
        } // End Sub Test
コード例 #10
0
        // https://gist.github.com/Venomed/5337717aadfb61b09e58
        // https://www.powershellgallery.com/packages/Posh-ACME/2.2.0/Content/Private%5CNew-Csr.ps1
        public static string CreateSignatureRequest(
            Org.BouncyCastle.Asn1.X509.X509Name subject
            , Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair caKey25519
            , Org.BouncyCastle.Security.SecureRandom secureRandom)
        {
            Org.BouncyCastle.Crypto.ISignatureFactory signatureFactory;

            Org.BouncyCastle.Crypto.AsymmetricKeyParameter publicKey  = caKey25519.Public;
            Org.BouncyCastle.Crypto.AsymmetricKeyParameter signingKey = caKey25519.Private;


            if (signingKey is Org.BouncyCastle.Crypto.Parameters.ECPrivateKeyParameters)
            {
                signatureFactory = new Org.BouncyCastle.Crypto.Operators.Asn1SignatureFactory(
                    Org.BouncyCastle.Asn1.X9.X9ObjectIdentifiers.ECDsaWithSha256.ToString(),
                    signingKey);
            }
            else
            {
                signatureFactory = new Org.BouncyCastle.Crypto.Operators.Asn1SignatureFactory(
                    Org.BouncyCastle.Asn1.Pkcs.PkcsObjectIdentifiers.Sha256WithRsaEncryption.ToString(),
                    signingKey);
            }

            System.Collections.Generic.Dictionary <Org.BouncyCastle.Asn1.DerObjectIdentifier, Org.BouncyCastle.Asn1.X509.X509Extension> extensions =
                new System.Collections.Generic.Dictionary <Org.BouncyCastle.Asn1.DerObjectIdentifier, Org.BouncyCastle.Asn1.X509.X509Extension>()
            {
                {
                    Org.BouncyCastle.Asn1.X509.X509Extensions.BasicConstraints,
                    new Org.BouncyCastle.Asn1.X509.X509Extension(
                        true
                        , new Org.BouncyCastle.Asn1.DerOctetString(new Org.BouncyCastle.Asn1.X509.BasicConstraints(false))
                        )
                },
                {
                    Org.BouncyCastle.Asn1.X509.X509Extensions.KeyUsage,
                    new Org.BouncyCastle.Asn1.X509.X509Extension(true,
                                                                 new Org.BouncyCastle.Asn1.DerOctetString(
                                                                     new Org.BouncyCastle.Asn1.X509.KeyUsage(
                                                                         Org.BouncyCastle.Asn1.X509.KeyUsage.DigitalSignature
                                                                         | Org.BouncyCastle.Asn1.X509.KeyUsage.KeyEncipherment
                                                                         | Org.BouncyCastle.Asn1.X509.KeyUsage.DataEncipherment
                                                                         | Org.BouncyCastle.Asn1.X509.KeyUsage.NonRepudiation
                                                                         )
                                                                     )
                                                                 )
                },
                {
                    Org.BouncyCastle.Asn1.X509.X509Extensions.ExtendedKeyUsage,
                    new Org.BouncyCastle.Asn1.X509.X509Extension(false,
                                                                 new Org.BouncyCastle.Asn1.DerOctetString(
                                                                     new Org.BouncyCastle.Asn1.X509.ExtendedKeyUsage(
                                                                         Org.BouncyCastle.Asn1.X509.KeyPurposeID.IdKPServerAuth,
                                                                         Org.BouncyCastle.Asn1.X509.KeyPurposeID.IdKPClientAuth
                                                                         )
                                                                     )
                                                                 )
                },
            };


            // Asn1Set attributes = null;
            Org.BouncyCastle.Asn1.Asn1Set attributes =
                new Org.BouncyCastle.Asn1.DerSet(
                    new Org.BouncyCastle.Asn1.Pkcs.AttributePkcs(
                        Org.BouncyCastle.Asn1.Pkcs.PkcsObjectIdentifiers.Pkcs9AtExtensionRequest
                        , new Org.BouncyCastle.Asn1.DerSet(new Org.BouncyCastle.Asn1.X509.X509Extensions(extensions))
                        )
                    );


            Org.BouncyCastle.Pkcs.Pkcs10CertificationRequest csr =
                new Org.BouncyCastle.Pkcs.Pkcs10CertificationRequest(
                    signatureFactory,
                    subject,
                    publicKey,
                    attributes,
                    signingKey
                    );



            System.Text.StringBuilder csrPem = new System.Text.StringBuilder();

            Org.BouncyCastle.OpenSsl.PemWriter csrPemWriter =
                new Org.BouncyCastle.OpenSsl.PemWriter(new System.IO.StringWriter(csrPem));

            csrPemWriter.WriteObject(csr);
            csrPemWriter.Writer.Flush();
            string signingRequest = csrPem.ToString();

            csrPem.Clear();
            csrPem = null;


            // System.IO.File.WriteAllText("request.csr", signingRequest, System.Text.Encoding.ASCII);

            CertificationRequestReader.ReadCertificationRequest(signingRequest);

            // csr.GetDerEncoded();
            System.Console.WriteLine(signingRequest);
            return(signingRequest);
        } // End Sub CreateSignatureRequest