首页 > 解决方案 > 如何在 C# 中使用带有私钥的 RS512 算法创建 JWT?

问题描述

我需要使用 RS512 和作为字符串值的私钥创建 JWT。我尝试了以下方法:

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

但它让我下一个错误:

        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

我听说我应该使用RS512RsaSecurityKey而不是SymmetricSecurityKeyRS512,但我找不到如何使用带私钥的。

谢谢!

标签: c#.netjwt

解决方案


如果有人在这个问题上苦苦挣扎,你可以尝试这样做(我正在使用 BouncyCastle 和 jose-jwt 库):

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@email.com"));
        claims.Add(new Claim("iss", "user"));
        claims.Add(new Claim("exp", "1671231233"));
        claims.Add(new Claim("iat", "1516239022"));

        return CreateToken(claims, privateKey);
    }
}

推荐阅读