.net 框架中的 ImportPkcs8PrivateKey 和 ImportRSAPrivateKey 替代方案

ImportPkcs8PrivateKey and ImportRSAPrivateKey alternative in .net framework

在 .net core 3.1 中,我使用 ImportPkcs8PrivateKey 和 ImportRSAPrivateKey 按照以下函数导入一些 RSA 私钥

 private RSA RsaKeyAsPerContent()
        {
            //https://csfieldguide.org.nz/en/interactives/rsa-key-generator/
            //https://travistidwell.com/jsencrypt/demo/
            RSA rSA = RSA.Create();
            string privateKeyContent = "...."
            bool isPkcsprivateKey = privateKeyContent.Contains("BEGIN PRIVATE KEY");
            if (isPkcsprivateKey)
            {
                var privateKey = privateKeyContent.Replace("-----BEGIN PRIVATE KEY-----", string.Empty).Replace("-----END PRIVATE KEY-----", string.Empty);
                privateKey = privateKey.Replace(Environment.NewLine, string.Empty);
                var privateKeyBytes = Convert.FromBase64String(privateKey);
                rSA.ImportPkcs8PrivateKey(privateKeyBytes, out int _);
            }
            else
            {
                var privateKey = privateKeyContent.Replace("-----BEGIN RSA PRIVATE KEY-----", string.Empty).Replace("-----END RSA PRIVATE KEY-----", string.Empty);
                privateKey = privateKey.Replace(Environment.NewLine, string.Empty);
                var privateKeyBytes = Convert.FromBase64String(privateKey);
                rSA.ImportRSAPrivateKey(privateKeyBytes, out int _);
            }
            return rSA;
        }

现在我需要传统 .net Framework 4.6/4.7 版中的相同导入功能,但它不可用 知道我如何在 .net 框架中做到这一点

以下是.net framework 4.6中使用的

 private static RSA RsaKeyAsPerContent()
        {
            RSA rSA = RSA.Create();

            string privateKeyFromConfig = ConfigurationManager.AppSettings["privateKey"];
            rSA.ImportParameters(ImportPrivateKey(privateKeyFromConfig));
            return rSA;
        }

        public static RSAParameters ImportPrivateKey(string pem)
        {
            PemReader pr = new PemReader(new StringReader(pem));
            RsaPrivateCrtKeyParameters privKey = (RsaPrivateCrtKeyParameters)pr.ReadObject();
            RSAParameters rp = new RSAParameters();
            rp.Modulus = privKey.Modulus.ToByteArrayUnsigned();
            rp.Exponent = privKey.PublicExponent.ToByteArrayUnsigned();
            rp.P = privKey.P.ToByteArrayUnsigned();
            rp.Q = privKey.Q.ToByteArrayUnsigned();
            rp.D = ConvertRSAParametersField(privKey.Exponent, rp.Modulus.Length);
            rp.DP = ConvertRSAParametersField(privKey.DP, rp.P.Length);
            rp.DQ = ConvertRSAParametersField(privKey.DQ, rp.Q.Length);
            rp.InverseQ = ConvertRSAParametersField(privKey.QInv, rp.Q.Length);

           
            return rp;
        }

        private static byte[] ConvertRSAParametersField(BigInteger n, int size)
        {
            byte[] bs = n.ToByteArrayUnsigned();
            if (bs.Length == size)
                return bs;
            if (bs.Length > size)
                throw new ArgumentException("Specified size too small", "size");
            byte[] padded = new byte[size];
            Array.Copy(bs, 0, padded, size - bs.Length, bs.Length);
            return padded;
        }

您可以尝试以下方法。它已经在 .net framework 4.8 上进行了测试,它使用了第 3 方包“BouncyCastle.Crypto”。

   public static RSACryptoServiceProvider ImportPrivateKey(string pem) {
        PemReader pr = new PemReader(new StringReader(pem));
        AsymmetricCipherKeyPair KeyPair = (AsymmetricCipherKeyPair)pr.ReadObject();
        RSAParameters rsaParams = 
        DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)KeyPair.Private);

        RSACryptoServiceProvider csp = new RSACryptoServiceProvider();// cspParams);
        csp.ImportParameters(rsaParams);
        return csp;
    }

详情可参考https://gist.github.com/ststeiger/f4b29a140b1e3fd618679f89b7f3ff4a