【问题标题】:signing using Generated RSA KeyPair Bouncy Castle使用 Generated RSA KeyPair Bouncy Castle 进行签名
【发布时间】:2017-04-11 15:27:50
【问题描述】:

我正在尝试生成 pfx 证书并使用 c# 进行签名 我已经使用以下代码使用 Bouncy castle 库成功地将 CSR 和私钥生成为 pem 格式

 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);
        }
    }

然后我签署了 CSR 并获得了 pem 证书并将其放在私钥 pem 旁边,然后使用以下代码将其保存到 pfx 文件中

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();
    }

我的问题是当我尝试使用我生成的 PFX 文件进行签名时,出现以下错误 “指定的算法无效”

签名代码

 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;
    }

【问题讨论】:

    标签: java c# cryptography bouncycastle private-key


    【解决方案1】:

    终于找到答案了 我不得不将签名方法的代码更改为

     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;
        }
    

    【讨论】:

    • 感谢您的反馈,但是如果您需要先对数据进行编码然后解码,那么似乎还有其他问题(如果密钥在智能卡或 HSM 中,则上述代码将永远无法工作)。可能一开始就不允许密钥签署证书?这由证书中的密钥使用位决定。
    猜你喜欢
    • 2012-04-25
    • 1970-01-01
    • 2011-07-12
    • 1970-01-01
    • 2015-03-22
    • 1970-01-01
    • 2012-07-05
    • 2016-10-01
    • 1970-01-01
    相关资源
    最近更新 更多