简体   繁体   中英

signing using Generated RSA KeyPair Bouncy Castle

i am trying to generate pfx certificate and sign with using c# i have successfully generated the CSR and Private key into pem format using Bouncy castle library using the following code

 private void GeneratePkcs10
        (string domainName, string companyName, string division, string city, string state,
         string countryIso2Characters, string email, RootLenght rootLength, out string csr, out string privateKey)
    {
        csr = null;
        privateKey = null;

        try
        {
            var rsaKeyPairGenerator = new RsaKeyPairGenerator();

            // Note: the numbers {3, 5, 17, 257 or 65537} as Fermat primes.
            // NIST doesn't allow a public exponent smaller than 65537, since smaller exponents are a problem if they aren't properly padded.
            // Note: the default in openssl is '65537', i.e. 0x10001.
            var genParam = new RsaKeyGenerationParameters
                (BigInteger.ValueOf(0x10001), new SecureRandom(), (int)rootLength, 256);

            rsaKeyPairGenerator.Init(genParam);




            AsymmetricCipherKeyPair pair = rsaKeyPairGenerator.GenerateKeyPair();
            var attributes = new Dictionary<DerObjectIdentifier, string>
                    {
                        { X509Name.CN, domainName },
                        { X509Name.O, companyName },
                        { X509Name.L, city },
                        { X509Name.ST, state },
                        { X509Name.C, countryIso2Characters }
                    };

            if (division != null)
            {
                attributes.Add(X509Name.OU, division);
            }

            if (email != null)
            {
                attributes.Add(X509Name.EmailAddress, email);
            }

            var subject = new X509Name(attributes.Keys.ToList(), attributes);

            var pkcs10CertificationRequest = new Pkcs10CertificationRequest
                (PkcsObjectIdentifiers.Sha256WithRsaEncryption.Id, subject, pair.Public, null, pair.Private);

            csr = Convert.ToBase64String(pkcs10CertificationRequest.GetEncoded());

            string certificateRequest = "-----BEGIN CERTIFICATE REQUEST-----" + Environment.NewLine;
            // TxtPkcSvalue.Text; 
            IEnumerable<string> csrData = ChunksUpto(csr, 63);

            for (int i = 0; i < csrData.ToArray().Length; i++)
            {
                certificateRequest += csrData.ToArray()[i] + Environment.NewLine; ;
            }

            certificateRequest += "-----END CERTIFICATE REQUEST-----" + Environment.NewLine;

            File.WriteAllText("E:/CSR.txt", certificateRequest);

            string pemObject = GetPEMStringFromRSAKeyPair(pair);
            File.WriteAllText("E:/PrivateKey.pem", pemObject);


            string publicpemObject = GetPublicPEMStringFromRSAKeyPair(pair);
            File.WriteAllText("E:/PublicKey.pem", publicpemObject);

            MessageBox.Show("CSR Generated Successfully");

        }
        catch (Exception ex)
        {
            // Note: handles errors on the page. Redirect to error page.
            MessageBox.Show(ex.Message);
        }
    }

then then i signed the CSR and got pem certificate and placed it next to the private key pem then saved it into pfx file using the following code

private void SavePFX()
    {
        StreamReader sr = File.OpenText(@"E:/PrivateKey.pem");
        PemReader pemReader = new PemReader(sr);


        Pkcs12Store store = new Pkcs12StoreBuilder().Build();
        X509CertificateEntry[] chain = new X509CertificateEntry[1];
        AsymmetricCipherKeyPair privKey = null;

        object o;
        while ((o = pemReader.ReadObject()) != null)
        {
            if (o is X509Certificate)
            {
                chain[0] = new X509CertificateEntry((X509Certificate)o);
            }
            else if (o is AsymmetricCipherKeyPair)
            {
                privKey = (AsymmetricCipherKeyPair)o;
            }
        }

        store.SetKeyEntry("test", new AsymmetricKeyEntry(privKey.Private), chain);
        FileStream p12file = File.Create("localhost.p12");
        store.Save(p12file, "12345".ToCharArray(), new SecureRandom());
        p12file.Close();
    }

my issue is when i am trying to sign using the PFX file i generated, i got the below error "invalid algorithm specified"

signing code

 public byte[] SignData(string subject, byte[] data, string hashAlgorithm)
    {
        X509Certificate2 certificate = GetCertificatesFromFolderPath(subject);
        var privateKey = certificate.PrivateKey as RSACryptoServiceProvider;
        if (!certificate.HasPrivateKey)
            throw new Exception("The certificate does not have a private key");
        switch (hashAlgorithm)
        {
            case "SHA-256":
                hashAlgorithm = "SHA256";
                break;
            case "SHA-1":
                hashAlgorithm = "SHA1";
                break;
        }
        if (privateKey != null) return privateKey.SignData(data, CryptoConfig.MapNameToOID("SHA256"));

        return null;
    }

finally i figured out the answer , i had to change the code for the signing method to

 public byte[] SignData(string subject, byte[] data, string hashAlgorithm)
    {
        X509Certificate2 certificate = GetCertificatesFromFolderPath(subject);
        var privateKey = new RSACryptoServiceProvider();
        if (!certificate.HasPrivateKey)
            throw new Exception("The certificate does not have a private key");
        switch (hashAlgorithm)
        {
            case "SHA-256":
                hashAlgorithm = "SHA256";
                break;
            case "SHA-1":
                hashAlgorithm = "SHA1";
                break;
        }

            privateKey.FromXmlString(certificate.PrivateKey.ToXmlString(true));

            return privateKey.SignData(data, CryptoConfig.MapNameToOID("SHA256"));



        return null;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM