RS256签名的JWT中的无效签名

RS256签名的JWT中的无效签名

本文介绍了.NET:RS256签名的JWT中的无效签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要创建一个Json Web令牌并使用不对称符号对其进行签名RS256算法.用于签名的密钥应取自X509证书,并由接收者使用公钥进行验证.

I need to create a Json Web Token and signing it with an asymetricRS256 algorithm. The key used for signing should be taken from aX509 certificate and be validated by the receiver using the public key.

使用HMAC和密码可以正常工作,但是使用代码创建的JWT下面列出的内容会在 https://jwt.io

Using HMAC and password works fine, but the JWT created with the codelisted below, produces constantlyI an "Invalid signature" at https://jwt.io

我在这里浏览了很多帖子,发现了很多有用的提示,但是都没有解决我的问题.也许我在理解上仍然有问题.

I got through many postings here, found a lot of usefull hints but none of them solved my problem. Maybe I've still a problem in understanding.

我知道,软件包System.IdentityModel.Tokens.Jwt实际上提供了我所需的一切,但我想了解自己在做错什么.

I know, the package System.IdentityModel.Tokens.Jwt actually provides all I need,but I want to understand what I'm doing wrong.

        // Get certificate from local store
        X509Store store = new X509Store(StoreLocation.CurrentUser);
        store.Open(OpenFlags.ReadOnly);
        X509Certificate2 x509Cert = (from X509Certificate2 c in store.Certificates where c.SubjectName.Name == $"CN={userName}" select c).First();

        if (x509Cert == null)
        {
            return string.Empty;
        }

        // Setup header
        var header = new { typ = "JWT", alg = "RS256" };
        var headerEncoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header)));

        // Setup payload/claims
        var payload = new
        {
            unique_name = $"{userName}@myCompany.com",
            role = "User",
            iss = x509Cert.Issuer,
            aud = "https://dev.myCompany.com",
            nbf = (Int32)DateTime.Now.Subtract(new DateTime(1970, 1, 1)).TotalSeconds,
            exp = (Int32)DateTime.Now.AddMinutes(5).Subtract(new DateTime(1970, 1, 1)).TotalSeconds,
            jti = Guid.NewGuid(),
            x5t = x509Cert.Thumbprint
        };
        var payloadEncoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload)));

        // ... and sign, using the RSACertificateExtensions
        var rsa = x509Cert.GetRSAPrivateKey();
        var signed = rsa.SignData(Encoding.UTF8.GetBytes($"{headerEncoded}.{payloadEncoded}"),
                                     HashAlgorithmName.SHA256,
                                     RSASignaturePadding.Pss);

        var signatureEncoded = Convert.ToBase64String(signed);

        return $"{headerEncoded}.{payloadEncoded}.{signatureEncoded}";
    }

推荐答案

构建令牌时会出错:

  • 对于RS256,使用RSASignaturePadding.Pkcs1而不是RSASignaturePadding.Pss

需要base64url编码,而不是base64.用

It is needed base64url encoding, not base64. Change Convert.ToBase64String(bytes) with

 Convert.ToBase64String(bytes)
       .TrimEnd(padding).Replace('+', '-').Replace('/', '_');

使用static readonly char[] padding = { '=' };参见

这篇关于.NET:RS256签名的JWT中的无效签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-26 05:12