問題描述
我已經使用 JSONWebToken
npm 模塊生成了一個 jwt:
I have used JSONWebToken
npm module to generate a jwt:
var jwt = require('jsonwebtoken');
var payload = {
"iss": "https://secure.example.com/",
"exp": 1410819380,
"http://example.com/orgnum": "987987987",
"http://example.com/user": "me@example.com"
};
var token = jwt.sign(payload, 'secret');
console.log(token);
這給了我以下輸出:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL3NlY3VyZS5leGFtcGxlLmNvbS8iLCJleHAiOjE0MTA4MTkzODAsImh0dHA6Ly9leGFtcGxlLmNvbS9vcmdudW0iOiI5ODc5ODc5ODciLCJodHRwOi8vZXhhbXBsZS5jb20vdXNlciI6Im1lQGV4YW1wbGUuY29tIiwiaWF0IjoxNDA4Mzk0Mjk2fQ.5X5LTg4wxDF2p49xtsRcG4S9Yk4qSfW1tMEU0AquBhc
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL3NlY3VyZS5leGFtcGxlLmNvbS8iLCJleHAiOjE0MTA4MTkzODAsImh0dHA6Ly9leGFtcGxlLmNvbS9vcmdudW0iOiI5ODc5ODc5ODciLCJodHRwOi8vZXhhbXBsZS5jb20vdXNlciI6Im1lQGV4YW1wbGUuY29tIiwiaWF0IjoxNDA4Mzk0Mjk2fQ.5X5LTg4wxDF2p49xtsRcG4S9Yk4qSfW1tMEU0AquBhc
由于我沒有指定我想要什么算法,所以它使用 SHA256.
Since I'm not specifying what algorithm I want, it uses SHA256.
現在,我嘗試在 c# 中驗證這一點.這并不容易......
Now, I try to verify this in c#. That didn't turn out easy...
我得到一個關于密鑰大小的異常:
I get an exception about the key size:
IDX10603:System.IdentityModel.Tokens.InMemorySymmetricSecurityKey"不能少于:128"位.參數導航:key.KeySize實際大小為 48.
IDX10603: The 'System.IdentityModel.Tokens.InMemorySymmetricSecurityKey' cannot have less than: '128' bits. Parameternavn: key.KeySize The actual size was 48.
我嘗試擴展密鑰,創建對稱密鑰時出現新錯誤:
I I try to extend the key, I get a new error when creating the symmetric key:
Base-64 字符數組或字符串的長度無效
Invalid length for a Base-64 char array or string
我認為這與我告訴 .net 代碼有關我的密鑰的方式有關.由于 SymmetricKeyIssuerSecurityTokenProvider
構造函數參數被命名為 base64Key
,我嘗試對我的密鑰進行 Base64Url 編碼:
I recon this has something to do with the way I'm telling the .net code about my key. Since the SymmetricKeyIssuerSecurityTokenProvider
constructor parameter is named base64Key
, I have tryed to Base64Url-encode my key:
var secret = Base64UrlEncoder.Encode("secret");
TokenValidationParameters validationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
IssuerSigningTokens = new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret).SecurityTokens
};
那么,我在這里缺少什么?
為什么 jsonwebtoken
可以使用短鍵生成和驗證記事本,而 .net 不能?
為什么 .net 不能接受我給它的密鑰?
So, what are I missing here?
Why can jsonwebtoken
generate and validate jots with short keys while .net can not?
And why can't .net accept the keys I give it?
這是完整的 .net 代碼,其中包含一個用長密鑰簽名的記事本:
Here's the complete .net code with a jot signed with a long key:
var jwtToken =
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL3NlY3VyZS5leGFtcGxlLmNvbS8iLCJleHAiOjE0MTA4MTkzODAsImh0dHA6Ly9leGFtcGxlLmNvbS9vcmdudW0iOiI5ODc5ODc5ODciLCJodHRwOi8vZXhhbXBsZS5jb20vdXNlciI6Im1lQGV4YW1wbGUuY29tIiwiaWF0IjoxNDA4Mzk1NjY4fQ.ZceiiEO_Mn5_GZp5D_r68VTT33fbocn1BTTznD6u3cs";
var secret = Base64UrlEncoder.Encode("super duper secret with some more on top");
TokenValidationParameters validationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
IssuerSigningTokens = new SymmetricKeyIssuerSecurityTokenProvider("issuer", secret).SecurityTokens
};
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler()
{
Configuration = new SecurityTokenHandlerConfiguration()
{
CertificateValidationMode = X509CertificateValidationMode.None
}
};
SecurityToken validatedToken;
var claimsPrincipal = tokenHandler.ValidateToken(jwtToken, validationParameters, out validatedToken);
return claimsPrincipal.Claims;
更新:
我在這段代碼中只使用了微軟的東西.我正在使用 Owin
包 Microsoft.Owin.Security.Jwt
版本 2.1.0
和 System.IdentityModel.Tokens.Jwt
版本 4.0.0-RC2
.
I'm only using Microsoft-stuff in this code. I'm using the Owin
packages Microsoft.Owin.Security.Jwt
version 2.1.0
with System.IdentityModel.Tokens.Jwt
version 4.0.0-RC2
.
那里有多篇博文指出您需要手動更新 System.IdentityModel.Tokens.Jwt
包.
There are multiple blog posts out there stating that you'll need to manually update the System.IdentityModel.Tokens.Jwt
package.
推薦答案
我不確定您使用的是什么 API,因為 official Microsoft one 不包含您正在使用的屬性.我的猜測是,您使用的是過時的版本.
I'm not sure what API you are using, since the official Microsoft one does not contain the properties that you are using. My guess would be, you are using an outdated version.
我從這個 Nuget 包中獲取了 API.這是對我有用的代碼:
I took the API from this Nuget package. And this is the code, that worked for me:
using System;
using System.Collections.Generic;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.Security.Claims;
using System.ServiceModel.Security.Tokens;
using System.Text;
namespace SO25372035
{
class Program
{
static void Main()
{
const string tokenString = @"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL3NlY3VyZS5leGFtcGxlLmNvbS8iLCJleHAiOjE0MTA4MTkzODAsImh0dHA6Ly9leGFtcGxlLmNvbS9vcmdudW0iOiI5ODc5ODc5ODciLCJodHRwOi8vZXhhbXBsZS5jb20vdXNlciI6Im1lQGV4YW1wbGUuY29tIiwiaWF0IjoxNDA4NDE5NTQwfQ.jW9KChUTcgXMDp5CnTiXovtQZsN4X-M-V6_4rzu8Zk8";
JwtSecurityToken tokenReceived = new JwtSecurityToken(tokenString);
byte[] keyBytes = Encoding.UTF8.GetBytes("secret");
if (keyBytes.Length < 64 && tokenReceived.SignatureAlgorithm == "HS256")
{
Array.Resize(ref keyBytes, 64);
}
TokenValidationParameters validationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
AudienceUriMode = AudienceUriMode.Never,
SigningToken = new BinarySecretSecurityToken(keyBytes),
};
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(tokenReceived, validationParameters);
IEnumerable<Claim> a = claimsPrincipal.Claims;
foreach (var claim in a)
{
Console.WriteLine(claim);
}
}
}
}
請注意,我必須調整包含密鑰的數組的大小,以便密鑰長度通過驗證.看來 HMAC 的密鑰長度始終等于塊大小,并且對于 SHA256,它是 512 位.有 MinimumSymmetricKeySizeInBits定義 SimmetricKey 最小長度的靜態屬性,但它似乎不能設置為小于 128.
Note, that I had to resize the array containing the key so that key length passes the validation. It appears that they key length for HMAC is always equal to the block size, and for SHA256 it's 512 bits. There is MinimumSymmetricKeySizeInBits static property that defines the minimum length of a SimmetricKey, but it appears it can't be set to be less than 128.
這篇關于無法使用 .NET 驗證 JSON Web 令牌 - 密鑰太短的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!