0

i want to generate jwt token which should be verified by google firebase. below is my code to generate jwt token, it works fine until i change algorithm to "RsaSha256Signature" it then gives me error

"Exception: 'System.InvalidOperationException: Crypto algorithm 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' not supported in this context. "

If i dont change it and use it as "HmacSha256Signature" it works fine

            var plainTextSecurityKey = "-----BEGIN PRIVATE KEY-----;
            var signingKey = new InMemorySymmetricSecurityKey(Encoding.UTF8.GetBytes(plainTextSecurityKey));
            var signingCredentials = new SigningCredentials(signingKey,
                SecurityAlgorithms.HmacSha256Signature, SecurityAlgorithms.Sha256Digest);

            var claimsIdentity = new ClaimsIdentity(new List<Claim>()
        {
            new Claim(ClaimTypes.NameIdentifier, email),
            new Claim(ClaimTypes.Role, role),
        }, "Custom");

            var securityTokenDescriptor = new SecurityTokenDescriptor()
            {
                AppliesToAddress = "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
                TokenIssuerName = "serviceemail",
                Subject = claimsIdentity,
                SigningCredentials = signingCredentials,
            };

            var tokenHandler = new JwtSecurityTokenHandler();
            var plainToken = tokenHandler.CreateToken(securityTokenDescriptor);
            var signedAndEncodedToken = tokenHandler.WriteToken(plainToken);

            var tokenValidationParameters = new TokenValidationParameters()
            {
                ValidAudiences = new string[]
            {
                "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
                "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
            },
                ValidIssuers = new string[]
            {
                "service email",
                "service email"
            },
                IssuerSigningKey = signingKey
            };

            SecurityToken validatedToken;
            tokenHandler.ValidateToken(signedAndEncodedToken,
                tokenValidationParameters, out validatedToken);

            return validatedToken.ToString();
Hammad Bukhari
  • 73
  • 3
  • 14

1 Answers1

1

Your signingKey is not a RSA key, so you can not use RsaSha256Signature. HmacSha256Signature works because you are creating a HMAC symmetric key with a fixed passphrase

var plainTextSecurityKey = "-----BEGIN PRIVATE KEY-----;
var signingKey = new InMemorySymmetricSecurityKey(Encoding.UTF8.GetBytes(plainTextSecurityKey));
var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256Signature, SecurityAlgorithms.Sha256Digest);

I am not expert in C#, but probably you need something like this

 // NOTE: Replace this with your actual RSA public/private keypair!
 var provider = new RSACryptoServiceProvider(2048);
 var parameters = provider.ExportParameters(true);

 // Build the credentials used to sign the JWT
 var signingKey = new RsaSecurityKey(parameters);
 var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.RsaSha256);

you will need a keystore which contains your private and public key. Note that HMAC is a symmetric algorithm and the key to sign and verify is the same, but RSA needs a keypair

Community
  • 1
  • 1
pedrofb
  • 37,271
  • 5
  • 94
  • 142