C#JWT Vertification

时间:2016-07-12 19:03:46

标签: c# jwt

我试图在网站上进行firebase auth(c#)。我需要验证登录令牌。

我正确获取令牌,如果我使用令牌和令牌中的公钥转到https://jwt.io/,则返回签名有效。

我的问题是我无法弄清楚如何在c#中验证令牌。

我有以下代码,我在令牌和公钥中发送(没有--- BEGIN证书和最终证书 - )。

我收到错误的序列大小错误:3 参数名称:seq

我使用充气城堡作为加密。我不知道我哪里出错了。我试图改变它的一切都没有用。

如果有任何帮助,我将不胜感激。

谢谢。

public static string Decode(string token,string key, bool verify = true)
    {
        //  HttpContext.Current.Response.Write(key);
        //   HttpContext.Current.Response.End();
        string[] parts = token.Split('.');
        string header = parts[0];
        string payload = parts[1];
        byte[] crypto = Base64UrlDecode(parts[2]);

        string headerJson = Encoding.UTF8.GetString(Base64UrlDecode(header));
        JObject headerData = JObject.Parse(headerJson);

        string payloadJson = Encoding.UTF8.GetString(Base64UrlDecode(payload));
        JObject payloadData = JObject.Parse(payloadJson);

        if (verify)
        {
            var keyBytes = Convert.FromBase64String(key); // your key here

            AsymmetricKeyParameter asymmetricKeyParameter = PublicKeyFactory.CreateKey(keyBytes);
            RsaKeyParameters rsaKeyParameters = (RsaKeyParameters)asymmetricKeyParameter;
            RSAParameters rsaParameters = new RSAParameters();
            rsaParameters.Modulus = rsaKeyParameters.Modulus.ToByteArrayUnsigned();
            rsaParameters.Exponent = rsaKeyParameters.Exponent.ToByteArrayUnsigned();
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.ImportParameters(rsaParameters);

            SHA256 sha256 = SHA256.Create();
            byte[] hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(parts[0] + '.' + parts[1]));

            RSAPKCS1SignatureDeformatter rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa);
            rsaDeformatter.SetHashAlgorithm("SHA256");
            if (!rsaDeformatter.VerifySignature(hash, FromBase64Url(parts[2])))
                throw new ApplicationException(string.Format("Invalid signature"));
        }

        return payloadData.ToString();
    }

    private static byte[] FromBase64Url(string base64Url)
    {
        string padded = base64Url.Length % 4 == 0
            ? base64Url : base64Url + "====".Substring(base64Url.Length % 4);
        string base64 = padded.Replace("_", "/")
                                .Replace("-", "+");
        return Convert.FromBase64String(base64);
    }

    // from JWT spec
    private static byte[] Base64UrlDecode(string input)
    {
        var output = input;
        output = output.Replace('-', '+'); // 62nd char of encoding
        output = output.Replace('_', '/'); // 63rd char of encoding
        switch (output.Length % 4) // Pad with trailing '='s
        {
            case 0: break; // No pad chars in this case
            case 1: output += "==="; break; // Three pad chars
            case 2: output += "=="; break; // Two pad chars
            case 3: output += "="; break; // One pad char
            default: throw new System.Exception("Illegal base64url string!");
        }
        var converted = Convert.FromBase64String(output); // Standard base64 decoder
        return converted;
    }

1 个答案:

答案 0 :(得分:0)

.NET中有非常好的预定义库来支持应用程序中的JWT。 System.IdentityModel.Tokens.Jwt和Microsoft.IdentityModel.Tokens有很多有用的东西。我最近在WebAPI应用程序中实现了JWT令牌创建和身份验证。我这样写是为了验证JWT。

using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.Tokens;

public class JwtTokenValidator
    {
        public ClaimsPrincipal ValidateToken(string jwtToken)
        {
            SecurityToken securityToken;
            var validationParameters = new TokenValidationParameters()
            {
                ValidIssuer = "ValidTokenIssuerName",
                ValidAudience = "ValidTokenAudienceName",
                ValidateIssuerSigningKey = true,
                ValidateAudience = true,
                ValidateIssuer = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.Default.GetBytes("ValidTokenSigningKey"))
            };

        var recipientTokenHandler = new JwtSecurityTokenHandler();
        var claimsPrincipal = recipientTokenHandler.ValidateToken(jwtToken, validationParameters, out securityToken);
        return claimsPrincipal;
    }
} 

您需要根据您的应用程序更新上述字符串详细信息和有效详细信息,用于创建JWT。 我也在分享我编写的代码,用于从AuthenticationTicket创建JWT。我希望它会有所帮助。

using System;
using System.IdentityModel.Tokens.Jwt;
using System.Text;
using Microsoft.IdentityModel.Tokens;
using Microsoft.Owin.Security;

public class JwtTokenFormatter : ISecureDataFormat<AuthenticationTicket>
    {
        private readonly JwtSecurityTokenHandler _tokenHandler;
        public JwtTokenFormatter()
        {
            _tokenHandler = new JwtSecurityTokenHandler();

        }
        public string Protect(AuthenticationTicket data)
        {
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Audience = "ValidTokenAudienceName",
                Issuer = "ValidTokenIssuerName",
                IssuedAt = DateTime.UtcNow,
                NotBefore = DateTime.UtcNow,
                Expires = DateTime.UtcNow.AddHours(24),
                Subject = data.Identity,
                SigningCredentials =
                    new SigningCredentials(
                        new SymmetricSecurityKey(Encoding.Default.GetBytes("ValidTokenSigningKey")),
                        SecurityAlgorithms.HmacSha256Signature)
            };

            return _tokenHandler.CreateEncodedJwt(tokenDescriptor);
        }

        public AuthenticationTicket Unprotect(string protectedText)
        {
            throw new NotImplementedException();
        }
    }