1

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;
    }
Alexander Farber
  • 21,519
  • 75
  • 241
  • 416
Kamran Shahid
  • 3,954
  • 5
  • 48
  • 93

1 Answers1

3

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

Kamran Shahid
  • 3,954
  • 5
  • 48
  • 93