问题描述
我需要创建一个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中的无效签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!