Search code examples
c#.netrsa

ImportPkcs8PrivateKey and ImportRSAPrivateKey alternative in .net framework


in .net core 3.1 I am using ImportPkcs8PrivateKey and ImportRSAPrivateKey for some RSA private Key import as per following function

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

now I need same import functionality in traditional .net framework version 4.6/4.7 but it is not available Any idea how can i do it in .net framework


Solution

  • Following is been used in .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;
            }