【问题标题】:Associating an X509Certificate2 certificate with a private key in .NET将 X509Certificate2 证书与 .NET 中的私钥相关联
【发布时间】:2019-09-18 08:59:31
【问题描述】:

我正在尝试使用以下代码创建 X509Certificate2 对象:https://stackoverflow.com/a/9250034/5589417

如何获取证书公钥对应的私钥?

我有这些加解密方法:

    public static byte[] Encrypt(byte[] plainBytes, X509Certificate2 cert)
    {
        RSACryptoServiceProvider publicKey = (RSACryptoServiceProvider)cert.PublicKey.Key;
        byte[] encryptedBytes = publicKey.Encrypt(plainBytes, false);
        return encryptedBytes;
    }

    public static byte[] Decrypt(byte[] encryptedBytes, X509Certificate2 cert)
    {
        RSACryptoServiceProvider privateKey = (RSACryptoServiceProvider)cert.PrivateKey;
        byte[] decryptedBytes = privateKey.Decrypt(encryptedBytes, false);
        return decryptedBytes;
    }

当我使用 Decrypt 方法时,我得到一个用于 privateKey 的 NullReferenceException。

【问题讨论】:

    标签: c# x509certificate


    【解决方案1】:

    我们必须为证书实例手动设置PrivateKey 属性。我还更新了您使用过时方法链接和删除的旧答案的代码:

    static void Main(string[] args)
    {
        var cert = GenerateCertificate("localhost");
    
        byte[] ciphertext = Encrypt(Encoding.ASCII.GetBytes("Hello world!"), cert);
        byte[] plaintext = Decrypt(ciphertext, cert);
    
        Console.WriteLine(Encoding.ASCII.GetString(plaintext));
    }
    
    static X509Certificate2 GenerateCertificate(string certName)
    {
        var secureRandom = new SecureRandom(new CryptoApiRandomGenerator());
        var keypairgen = new RsaKeyPairGenerator();
        // RSA key size = 1024 bits
        keypairgen.Init(new KeyGenerationParameters(secureRandom, 1024));
    
        var keypair = keypairgen.GenerateKeyPair();
    
        var gen = new X509V3CertificateGenerator();
        // we will use SHA256 signature
        var signatureFactory = new Asn1SignatureFactory("SHA256WITHRSA", keypair.Private, secureRandom);
    
        var CN = new X509Name("CN=" + certName);
        var SN = BigInteger.ProbablePrime(120, new Random());
    
        gen.SetSerialNumber(SN);
        gen.SetSubjectDN(CN);
        gen.SetIssuerDN(CN);
        gen.SetNotAfter(DateTime.MaxValue);
        gen.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0)));
        gen.SetPublicKey(keypair.Public);
    
        var newCert = gen.Generate(signatureFactory);
    
        var x509cert = new X509Certificate2(DotNetUtilities.ToX509Certificate(newCert));
        var rsa = RSA.Create();
        var publicKey = (RsaKeyParameters)keypair.Public;
        var privateKey = (RsaPrivateCrtKeyParameters)keypair.Private;
        var parameters = new RSAParameters
        {
            Modulus = publicKey.Modulus.ToByteArrayUnsigned(),
            Exponent = publicKey.Exponent.ToByteArrayUnsigned(),
    
            P = privateKey.P.ToByteArrayUnsigned(),
            Q = privateKey.Q.ToByteArrayUnsigned(),
            DP = privateKey.DP.ToByteArrayUnsigned(),
            DQ = privateKey.DQ.ToByteArrayUnsigned(),
            InverseQ = privateKey.QInv.ToByteArrayUnsigned(),
            D = privateKey.Exponent.ToByteArrayUnsigned(),
        };
        rsa.ImportParameters(parameters);
        // at this point X509Certificate2 will check if PrivateKey matches PublicKey
        x509cert.PrivateKey = rsa;
    
        return x509cert;
    }
    
    public static byte[] Encrypt(byte[] plainBytes, X509Certificate2 cert)
    {
        RSACryptoServiceProvider publicKey = (RSACryptoServiceProvider)cert.PublicKey.Key;
        byte[] encryptedBytes = publicKey.Encrypt(plainBytes, false);
        return encryptedBytes;
    }
    
    public static byte[] Decrypt(byte[] encryptedBytes, X509Certificate2 cert)
    {
        RSACryptoServiceProvider privateKey = (RSACryptoServiceProvider)cert.PrivateKey;
        byte[] decryptedBytes = privateKey.Decrypt(encryptedBytes, false);
        return decryptedBytes;
    }
    

    【讨论】:

      猜你喜欢
      • 2013-08-30
      • 1970-01-01
      • 2017-03-23
      • 1970-01-01
      • 2016-12-30
      • 2011-10-08
      • 2015-10-15
      • 2015-08-26
      • 2022-01-02
      相关资源
      最近更新 更多