我正在使用jose-jwt库,并希望使用RS256算法在C#中创建加密的JWT进行加密.我没有密码学的经验,所以请原谅我的无知.我在文档中看到以下示例:
var payload = new Dictionary<string, object>()
{
{ "sub", "mr.x@contoso.com" },
{ "exp", 1300819380 }
};
var privateKey=new X509Certificate2("my-key.p12", "password", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet).PrivateKey as RSACryptoServiceProvider;
string token=Jose.JWT.Encode(payload, privateKey, JwsAlgorithm.RS256);
Run Code Online (Sandbox Code Playgroud)
它显示了p12文件的使用,但我如何使用下面表格的RSA密钥文件?我正在查看X509Certificate2的文档,但我看不到RSA私钥的选项.它似乎只接受PKCS7,我理解为公钥.
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
-----END RSA PRIVATE KEY-----
Run Code Online (Sandbox Code Playgroud)
最后,文档中列出的两个选项有什么区别,我如何在两者之间做出选择?
- - - - - - - - - - - - - 选项1 - - - - - …
我有一个字符串形式的令牌,我下载了公共证书并从中创建了一个公钥,如下所示。
但我不确定如何使用这么多信息进行验证。
我找到了适用于 C# 和 .NET 的解决方案,但没有找到适用于 Java 的解决方案。请注意,我没有 jks 文件或私钥。
FileInputStream fin = new FileInputStream("d://public.crt");
CertificateFactory f = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate)f.generateCertificate(fin);
PublicKey pk = certificate.getPublicKey();
Run Code Online (Sandbox Code Playgroud) 我有一些这样的代码,我认为它失败了,因为它使用非对称 RS256 但具有“SymmetricSecurityKey()”。令牌是从https://jwt.io/手工生成的
\n\xce\xbb cat Program.cs\n\xef\xbb\xbfusing System;\nusing System.IdentityModel.Tokens.Jwt;\nusing System.Text;\nusing System.Linq;\nusing Microsoft.IdentityModel.Tokens;\nusing System.Security.Cryptography;\n\nnamespace jwttest\n{\n class Program\n {\n static void Main(string[] args)\n {\n string jwt = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.POstGetfAytaZS82wHcjoTyoqhMyxXiWdR7Nn7A29DNSl0EiXLdwJ6xC6AfgZWF1bOsS_TuYI3OG85AmiExREkrS6tDfTQ2B3WXlrr-wp5AokiRbz3_oB4OxG-W9KcEEbDRcZc0nH3L7LzYptiy1PtAylQGxHTWZXtGz4ht0bAecBgmpdgXMguEIcoqPJ1n3pIWk_dUZegpqx0Lka21H6XxUTxiy8OcaarA8zdnPUnV6AmNP3ecFawIFYdvJB_cm-GvpCSbr8G8y_Mllj8f4x9nBH8pQux89_6gUY618iYv7tuPWBFfEbLxtF2pZS6YC1aSfLQxeNe8djT9YjpvRZA";\n var pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnzyis1ZjfNB0bBgKFMSvvkTtwlvBsaJq7S5wA+kzeVOVpVWwkWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHcaT92whREFpLv9cj5lTeJSibyr/Mrm/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIytvHWTxZYEcXLgAXFuUuaS3uF9gEiNQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0e+lf4s4OxQawWD79J9/5d3Ry0vbV3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWbV6L11BWkpzGXSW4Hv43qa+GSYOD2QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9MwIDAQAB";\n var rawKey = Encoding.ASCII.GetBytes(pubKey);\n\n var tokenHandler = new JwtSecurityTokenHandler();\n // var rsa = ?\n tokenHandler.ValidateToken(jwt, new TokenValidationParameters {\n IssuerSigningKey = new SymmetricSecurityKey(rawKey)\n },\n out SecurityToken validatedToken);\n }\n }\n}\n\nC:\\src\\jwttest (cgt-test-5 -> origin)\n\xce\xbb dotnet run\n[2020-08-18T23:41:05.7108585-07:00 Info] raw=System.Byte[] [392]\nUnhandled exception. Microsoft.IdentityModel.Tokens.SecurityTokenInvalidSignatureException: IDX10503: …Run Code Online (Sandbox Code Playgroud) 我有一个由 AWS ALB 使用 OpenID 连接器创建的 JWT。我需要在我的 C# 应用程序中验证令牌。但我很难让它发挥作用。
它应该分 3 个步骤进行:
(https://public-keys.auth.elb.' + region + '.amazonaws.com/' + key id)这是我得到的 JWT:
eyJ0eXAiOiJKV1QiLCJraWQiOiJjODE4ZTcxNi01OTAxLTQzOWQtOWFlZC1lYmRMODAyYjZkYTkiLCJhbGciOiJFUzI1NiIsImlzcyI6Imh0dHBzOi8vc2llbWVucy1xYS0wMDA2OS5ldS5hdXRoMC5 jb20vIiwiY2xpZW50IjoiMndsS3k0YlRXbGpZWm9KYXZRSVFqVTE3OUprVG4zNDAiLCJzaWduZXIiOiJhcm46YXdzOmVsYXN0aWNsb2FkYmFsYW5jaW5nOmV1LWNlbnRyYWwtMTo0ODU2ODM0OD CXOTY6bG9hZGJhbGFuY2VyL2FwcC9maW5kLXRlc3QtYWxiLzU3YzBmMWYzZjg0YzZjMjEiLCJleHAiOjE1NzU1NDMwMzN9.eyJzdWIiOiJvYXV0aDJ8bWFpbi10ZW5hbnQtb2lkY3xzYW1sc HxTaWVtZW5zfFowMDJFSk5VIiwiZ2l2ZW5fbmFtZSI6IlJhcGhhZWwiLCJmYW1pbHlfbmFtZSI6IlNjaG5haXRsIiwibmlja25hbWUiOiJSYXBoYWVsIiwibmFtZSI6IlJhcGhhZWwgU2NobmFpd GwiLCJwaWN0dXJlIjoiaHR0chHM6Ly9zLmdyYXZhdGFyLmNvbS9hdmF0YXIvODkzNWVlY2QzMDc2ZTAyMTQ5ODE2MTZmZjBkZTRkZjI_cz00ODAmcj1wZyZkPWh0dHBzJTNBJTJGJTJGY2RuLMF1 dGgwLmNvbSUyRmF2YXRhcnMlMkZyYS5wbmciLCJ1cGRhdGVkX2F0IjoiMjAxOS0xMi0wNVQxMDo0ODozMy4wNjhaIiwiZXhwIjoxNTc1NTQzMDMzLCJpc3MiOiJodHRwczovL3NpZW1lbnMtcWEtMDAwN jkuZXUuYXV0aDAuY29tLyJ9.M39aPefXmaDGzaDd0qHcQHMhvugTVN4i4pyvGJ-7fayewU9vZdtKvSzFF9rVal8GEz7HKTr_auqMw9HemOWyag==
因此,密钥 ID 为:c818e716-5901-439d-9aed-ebdf802b6da9
公钥:
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENARdEGaEpfgHph3440UodVsQdqxi
PYz+l1aEcz+Bivr6emXDnor1nET94dbPqYxk+vtUHGkgOb44VPEZUe4ijQ==
-----END PUBLIC KEY-----
Run Code Online (Sandbox Code Playgroud)
我尝试使用以下方法验证代码:
System.IdentityModel.Tokens.Jwt命名空间。但我无法将公钥作为字符串提供给 ValidationParameters。我遵循了与此答案类似的方法/sf/answers/3630685761/。感觉很复杂而且容易出错。由于一整天后我无法让它工作,我决定转向提供相同功能的 nuget 包之一。Jose.JWT.Decode(__token, publicKeyPem, Jose.JwsAlgorithm.ES256)
出现以下错误:
错误:脚本执行失败。[ArgumentException] EcdsaUsingSha 算法期望密钥为 …
我有一个带有 ASP.NET Core 后端的 iOS 应用程序,它使用 IdentityUser 令牌,它可以使用用户名/密码登录来检索令牌,如下所示:
var result = await _signInManager.PasswordSignInAsync(model.Username, model.Password, isPersistent: true, lockoutOnFailure: true);
if (result.Succeeded)
{
return Ok(result);
}
Run Code Online (Sandbox Code Playgroud)
但现在我想添加“使用 Apple 登录”的选项,这在应用程序端很容易完成,在 Apple 验证用户后,我们会得到一个已签名并包含电子邮件地址的 IdentityToken (JWT)。这看起来很简单,我可以将该 IdentityToken 传递回我的 API 并通过使用以下方法检查签名来验证它是否有效:https : //stackoverflow.com/a/34423434/1999217
但据我了解(以及到期),Apple 提供的 IdentityToken 只能使用一次并转换为新令牌(在我的情况下为 Microsoft.AspNetCore.Identity 令牌)。
我怎样才能做到这一点?一旦我验证了 IdentityToken 并且我相信请求用户拥有传入的电子邮件地址,那么我可以检索 ApplicationUser 和 Microsoft.AspNetCore.Identity.UserManager 似乎有一个方法 SignInAsync() 但它的返回类型不是 IdentityResult 作为预期所以它没有帮助。
我还查看了 ExternalLoginProvider 方法,但它依赖于我认为不适合这种情况的回调,因为我有一个可以信任的令牌。
我正在考虑使用电子邮件地址并进行即时密码重置,但感觉很狡猾。就像是:
var user = await _userManager.FindByEmailAsync(email);
var token = await _userManager.GeneratePasswordResetTokenAsync(user);
var result = await _userManager.ResetPasswordAsync(user, token, RandomPassword());
Run Code Online (Sandbox Code Playgroud)
因为这与身份验证有关,所以我觉得安全总比抱歉好。我想我的问题的核心是:这很狡猾吗?有没有更好的方法来获得只有电子邮件的 IdentityResult?