Search code examples
jwtrsa.net-core-3.1

How to create RsaSecurityKey from Public/Private Key Pair


How can I Create RsaSecurityKey from Public/Private Key Pair?

I need to create JWT ID token

My sample Key value pair is given in the method:

public string GetIdTokenStringNew(Dictionary<string, object> inputClaims, string publicKey, string privateKey )
    {
        string result = null;
        try
        {
            var tokenHandler = new JwtSecurityTokenHandler();                

            publicKey = @"-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANPCGYnVEa1jQPMSHXST8NVIrcAYZcWr
..............
-----END PUBLIC KEY-----
";

            privateKey = @"-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIBrzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIa3E4RUhvGGwCAggA
MB0GCWCGSAFlAwQBKgQQnfLhTMhpN7BE0A+viaWeWwSCAWD2yFBSGAP6boVzCOqg
41IoRHrZHgTQVbySuruav5nM3eMe3psHD0C4Tbyj4av3UnD2/ebZz8f9IiObJ45a
................................................................
....
-----END ENCRYPTED PRIVATE KEY-----";


            List<Claim> claims = new List<Claim>();

            foreach (var o in inputClaims)
            {
                string val = null;
                if (o.Value != null)
                {
                    Type t = o.Value.GetType();
                    bool isDict = t.IsGenericType /*&& t.GetGenericTypeDefinition() == typeof(Dictionary<,>)*/;
                    if (isDict)
                    {
                        val = JsonSerializer.Serialize(o.Value);
                    }
                    else
                    {
                        val = o.Value.ToString();
                    }
                }
                claims.Add(new Claim(o.Key, val));
            }

            var rsaParameters = new RSAParameters();// it should be from public /private key               
            var securitykey = new RsaSecurityKey(rsaParameters);
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(claims),
                Expires = DateTime.UtcNow.AddSeconds(60 * 5),
                SigningCredentials = new SigningCredentials(securitykey, SecurityAlgorithms.RsaSha256),
                Audience = "....",
                Issuer = "..."
            };
            var additionalheader = new Dictionary<string, object>
            {
                { "kid", "***" }
            };
            tokenDescriptor.AdditionalHeaderClaims = additionalheader;                
            var token = tokenHandler.CreateToken(tokenDescriptor);
            if (token != null && token is JwtSecurityToken)
            {
                result = (token as JwtSecurityToken).RawData;
            }
        }
        catch (Exception ex)
        {

        }
        return result;
    }

Solution

  • Following is my code for generating ID token

      public string GetIdTokenString(List<Claim> claims)
            {
                string result = null;
    
                try
                {
                    //IdentityModelEventSource.ShowPII = true;
                    RSA rSA = RsaKeyAsPerContent();
                    RsaSecurityKey securitykey = new RsaSecurityKey(rSA)
                    {
                        KeyId = ObjEntity.ShortCode
                    };
    
                    var tokenDescriptor = new SecurityTokenDescriptor
                    {
                        Subject = new ClaimsIdentity(claims),
                        Expires = DateTime.UtcNow.AddSeconds(ObjInitialRequest.ExpiresIn),
                        Audience = ObjEntity.ClientId,
                        Issuer = SystemLevelOneTimeLoadedProperties.GetSpecificWellKnownValue("issuer"),//from well known configuration issuer
                        SigningCredentials = new SigningCredentials(securitykey, SecurityAlgorithms.RsaSha256),
                        IssuedAt = DateTime.UtcNow
                    };
    
                    var tokenHandler = new JwtSecurityTokenHandler
                    {
                        SetDefaultTimesOnTokenCreation = false
                    };
                    var token = tokenHandler.CreateJwtSecurityToken(tokenDescriptor);
                    if (token != null)
                    {
                        result = token.RawData;
                    }
                }
                catch (Exception ex)
                {
                    Logger.Fatal(ex, ex);
                }
                return result;
            }
    
            private RSA RsaKeyAsPerContent()
            {
                //https://csfieldguide.org.nz/en/interactives/rsa-key-generator/
                //https://travistidwell.com/jsencrypt/demo/
                RSA rSA = RSA.Create();
                bool isPkcsEncryptedPrivateKey = ObjEntity.PrivateKey.Contains("BEGIN ENCRYPTED PRIVATE KEY");
                bool isPkcsprivateKey = ObjEntity.PrivateKey.Contains("BEGIN PRIVATE KEY");
                if (isPkcsEncryptedPrivateKey)
                {
                    var privateKey = ObjEntity.PrivateKey.Replace("-----BEGIN ENCRYPTED PRIVATE KEY-----", string.Empty).Replace("-----END ENCRYPTED PRIVATE KEY-----", string.Empty);
                    privateKey = privateKey.Replace(Environment.NewLine, string.Empty);
                    var privateKeyBytes = Convert.FromBase64String(privateKey);
                    byte[] privateKeyPasswordBytes = Encoding.UTF8.GetBytes(passwordfromsomeconfig);
                    rSA.ImportEncryptedPkcs8PrivateKey(privateKeyPasswordBytes, privateKeyBytes, out int _);
                }
                else if (isPkcsprivateKey)
                {
                    var privateKey = ObjEntity.PrivateKey.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 = ObjEntity.PrivateKey.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;
            }
    

    any suggestion for improvement is welcome