public string SignWithPrivateKey(string data, bool write_algo_as_prefix = false, bool use_indent = false, string algorithm = "SHA256")
        {
            try
            {
                var rsa           = RSA.Create() as RSACryptoServiceProvider;
                var rsaParameters = PemUtils.ToRSAParameters(PrivateKey);
                rsa.ImportParameters(rsaParameters);

                var sha  = new SHA256CryptoServiceProvider();
                var hash = sha.ComputeHash(Encoding.UTF8.GetBytes(data));
                var id   = CryptoConfig.MapNameToOID(algorithm);
                var sig  = rsa.SignHash(hash, id);

                var prefix = String.Empty;
                if (write_algo_as_prefix)
                {
                    prefix = $"{algorithm}:\n";
                }

                if (use_indent)
                {
                    return(prefix + Convert.ToBase64String(sig, Base64FormattingOptions.InsertLineBreaks));
                }

                return(prefix + Convert.ToBase64String(sig));
            }
            catch (Exception ex)
            {
                throw new Exception("Data could not signing.", ex);
            }
        }
        protected RSACryptoServiceProvider GetRsaProvider()
        {
            var rsaParameters = new RSAParameters();

            if (HasPrivateKey)
            {
                rsaParameters = PemUtils.ToRSAParameters(PrivateKey);
            }
            else
            {
                rsaParameters = PemUtils.ToRSAParameters(PublicKey);
            }
            var rsa = new RSACryptoServiceProvider();

            rsa.ImportParameters(rsaParameters);
            return(rsa);
        }
        public static X509Certificate2 AddPemPrivateKeyToCertificate(X509Certificate2 certificate, byte[] privateKeyBuffer, string password = null)
        {
            try
            {
                var keyPair       = ReadPrivateKey(privateKeyBuffer, password != null ? new PasswordFinder(password) : null);
                var rsaPrivateKey = PemUtils.ToRSA(keyPair.Private as RsaPrivateCrtKeyParameters);
#if NETCOREAPP2_0 || NETCOREAPP2_1
                certificate = certificate.CopyWithPrivateKey(rsaPrivateKey);
#else
                certificate = certificate.CopyWithPrivateKey(keyPair, password);
#endif
                return(certificate);
            }
            catch (Exception ex)
            {
                logger.Error(ex, $"The Method \"{nameof(AddPemPrivateKeyToCertificate)}\" has failed.");
                return(null);
            }
        }
        public static X509Certificate2 GenerateSelfSignedCertificate(string subjectName, string issuerName, int keyStrength)
        {
            try
            {
                // Generating Random Numbers
                var randomGenerator = new VmpcRandomGenerator();
                var random          = new SecureRandom(randomGenerator);

                // The Certificate Generator
                var certificateGenerator = new X509V3CertificateGenerator();

                // Serial Number
                var serialNumber = BigInteger.ProbablePrime(128, new Random());
                certificateGenerator.SetSerialNumber(serialNumber);

                // Signature Algorithm
                var signatureAlgorithm = "SHA512WithRSA";
                certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm);

                // Issuer and Subject Name
                var subjectDN = new X509Name(subjectName);
                var issuerDN  = new X509Name(issuerName);
                certificateGenerator.SetIssuerDN(issuerDN);
                certificateGenerator.SetSubjectDN(subjectDN);

                // Valid For
                var notBefore = DateTime.UtcNow.Date.AddYears(-1);
                var notAfter  = notBefore.AddYears(10);
                certificateGenerator.SetNotBefore(notBefore);
                certificateGenerator.SetNotAfter(notAfter);

                // Subject Public Key
                var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
                var keyPairGenerator        = new RsaKeyPairGenerator();
                keyPairGenerator.Init(keyGenerationParameters);

                if (userKeyPair == null)
                {
                    userKeyPair = keyPairGenerator.GenerateKeyPair();
                }

                certificateGenerator.SetPublicKey(userKeyPair.Public);

                //Extented
                certificateGenerator.AddExtension(X509Extensions.SubjectKeyIdentifier, false,
                                                  new SubjectKeyIdentifierStructure(userKeyPair.Public));
                certificateGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier, false,
                                                  new AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory
                                                                             .CreateSubjectPublicKeyInfo(userKeyPair.Public)));
                var valueData = Encoding.ASCII.GetBytes("Client");
                certificateGenerator.AddExtension("1.3.6.1.5.5.7.13.3", false, valueData);

                // Generating the Certificate
                var issuerKeyPair = userKeyPair;

                // selfsign certificate
                var certificate = certificateGenerator.Generate(userKeyPair.Private, random);

                // correcponding private key
                var info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(userKeyPair.Private);

                // merge into X509Certificate2
                var x509 = new X509Certificate2(certificate.GetEncoded());

                var seq = (Asn1Sequence)Asn1Object.FromByteArray(info.ParsePrivateKey().GetDerEncoded());
                if (seq.Count != 9)
                {
                    throw new Exception("malformed sequence in RSA private key");
                }

                var rsa       = RsaPrivateKeyStructure.GetInstance(seq);
                var rsaparams = new RsaPrivateCrtKeyParameters(rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent,
                                                               rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2,
                                                               rsa.Coefficient);
#if NETCOREAPP2_0 || NETCOREAPP2_1
                x509 = x509.CopyWithPrivateKey(PemUtils.ToRSA(rsaparams));
#endif
                return(x509);
            }
            catch (Exception ex)
            {
                logger.Error(ex, $"The Method \"{nameof(GenerateSelfSignedCertificate)}\" has failed.");
                return(null);
            }
        }