Reputation: 501
I need to create JWT using RS512 and private key which is string value. I tried the following way:
var privateKey = @"-----BEGIN PRIVATE KEY----- {some string data} -----END PRIVATE KEY-----";
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(privateKey));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.RsaSha512);
var header = new JwtHeader(credentials);
var now = DateTime.UtcNow;
var payload = new JwtPayload
{
{ "iss", "1198bef0-a0d52731-706e-4936-be46-1ae4b2b2e9bd" },
{ "iat", now },
{ "exp", now.AddMinutes(30) }
};
var secToken = new JwtSecurityToken(header, payload);
var handler = new JwtSecurityTokenHandler();
var tokenString = handler.WriteToken(secToken);
But it gets me the next error:
NotSupportedException: IDX10634: Unable to create the SignatureProvider.
Algorithm: 'RS512', SecurityKey: 'Microsoft.IdentityModel.Tokens.SymmetricSecurityKey, KeyId: '', InternalId: '546ecdc1-0c87-40b4-905e-88d3bfc032c3'.'
is not supported. The list of supported algorithms is available here: https://aka.ms/IdentityModel/supported-algorithms
I heard that I should use RsaSecurityKey
instead of SymmetricSecurityKey
for RS512, but I couldn't find how to use one with private key.
Thanks!
Upvotes: 0
Views: 3374
Reputation: 21
In case if someone is struggling with this issue, you can try to do like this (I am using BouncyCastle and jose-jwt libraries):
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Security.Cryptography;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
using Jose;
public class Token
{
public string CreateToken(List<Claim> claims, string privateRsaKey)
{
RSAParameters rsaParams;
using (var tr = new StringReader(privateRsaKey))
{
var pemReader = new PemReader(tr);
var keyPair = pemReader.ReadObject() as RsaPrivateCrtKeyParameters;
if (keyPair == null)
{
throw new Exception("Could not read RSA private key");
}
var privateRsaParams = keyPair;
rsaParams = DotNetUtilities.ToRSAParameters(privateRsaParams);
}
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.ImportParameters(rsaParams);
Dictionary<string, object> payload = claims.ToDictionary(k => k.Type, v => (object)v.Value);
return Jose.JWT.Encode(payload, rsa, JwsAlgorithm.RS512);
}
}
public string GetJwtToken()
{
string privateKey = @"-----BEGIN PRIVATE KEY-----{YOUR SECURED DATA}-----END PRIVATE KEY-----";
var claims = new List<Claim>();
claims.Add(new Claim("sub", "[email protected]"));
claims.Add(new Claim("iss", "user"));
claims.Add(new Claim("exp", "1671231233"));
claims.Add(new Claim("iat", "1516239022"));
return CreateToken(claims, privateKey);
}
}
Upvotes: 2
Reputation: 3991
Updated Loading RSA Key by using BouncyCastle library
public static RsaSecurityKey PrivateKeyFromPem(string keyPairPem)
{
PemReader pemReader = new PemReader(new StringReader(keyPairPem));
AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
RsaPrivateCrtKeyParameters privateKeyParameters = (RsaPrivateCrtKeyParameters)keyPair.Private;
RSAParameters rsaParameters = DotNetUtilities.ToRSAParameters(privateKeyParameters);
return new RsaSecurityKey(rsaParameters);
}
public static void Main()
{
var privateKey = @"-----BEGIN PRIVATE KEY----- {some string data} -----END
PRIVATE KEY-----";
DateTime now = DateTime.Now;
var payload = new JwtPayload
{
{ "iss", "1198bef0-a0d52731-706e-4936-be46-1ae4b2b2e9bd" },
{ "iat", now },
{ "exp", now.AddMinutes(30) }
};
var credentials =new SigningCredentials(
PrivateKeyFromPem(privateKey),
SecurityAlgorithms.RsaSha512
);
var header = new JwtHeader(signingCredentials: credentials);
var jst = new JwtSecurityToken(header, payload);
var tokenHandler = new JwtSecurityTokenHandler();
string assertion = tokenHandler.WriteToken(jst);
Console.WriteLine(assertion);
}
you can go to https://jwt.io/ and check the result with your public an privet keys. extract from this article hope find it useful.
Upvotes: 0