ES 512 jwt 令牌验证
ES 512 jwt token verification
我正在尝试使用 public 字符串格式的密钥来验证 ES512 jwt 令牌:
我正在尝试模仿为 ES256 编写的示例
是这样的:
// The code for ES256
public static void VerifyES512Jwt(string token,string publicKey)
{
byte[] publicKeyBytes = Convert.FromBase64String(publicKey);
string[] parts = token.Split('.');
string header = parts[0];
string payload = parts[1];
string signature = parts[2];
var keyType = new byte[] { 0x45, 0x43, 0x53, 0x31 };
var keyLength = new byte[] { 0x20, 0x00, 0x00, 0x00 };
var key = keyType.Concat(keyLength).Concat(publicKeyBytes.Skip(publicKeyBytes.Length - 64)).ToArray();
CngKey cngKey = CngKey.Import(key, CngKeyBlobFormat.EccPublicBlob);
// the purpose is to get ECDsaCng and verify the payload data
ECDsaCng eCDsaCng = new ECDsaCng(cngKey);
bool result = eCDsaCng.VerifyData(payload, signatureBytes);
}
我正在尝试将此代码用于 ES512,但在获取密钥时卡住了
var keyType = new byte[] { 0x45, 0x43, 0x53, 0x31 };
var keyLength = new byte[] { 0x20, 0x00, 0x00, 0x00 };
var key = keyType.Concat(keyLength).Concat(publicKeyBytes.Skip(publicKeyBytes.Length - 64)).ToArray();
当与上面一起使用时,它会在获取密钥时出错:
CngKey cngKey = CngKey.Import(key, CngKeyBlobFormat.EccPublicBlob);
我使用的public密钥和令牌如下:
public 键:
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBgc4HZz+/fBbC7lmEww0AO3NK9wVZ
PDZ0VEnsaUFLEYpTzb90nITtJUcPUbvOsdZIZ1Q8fnbquAYgxXL5UgHMoywAib47
6MkyyYgPk0BXZq3mq4zImTRNuaU9slj9TVJ3ScT3L1bXwVuPJDzpr5GOFpaj+WwM
Al8G7CqwoJOsW7Kddns=
令牌:
eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzUxMiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE1NjUwOTk2ODgsImV4cCI6MTU5ODE4OTg4NSwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDozNTg4Iiwic3ViIjoiaHR0cDovL2xvY2FsaG9zdDo1MDM3NiIsImZpcnN0bmFtZSI6IkFydmluZCIsImxhc3RuYW1lIjoiS3VtYXIiLCJFbWFpbCI6ImFydmluZC5rdW1hckBzdHJlYW1hbWcuY29tIiwiSWQiOiIxMDEifQ.AVwAJeY44lKrnywnDs7CdUOu3gli2cGafSJ6iP3zT7lkZpd2QnL0k54aVmPVxAGuN5dDnzbYmMTdRl5u2QE92ccOAHrcf5yA2gsvhhAGuDAAeh6Io4VU7v5TOTvwWGRb-ubgdjUvagA_HSJOyeXvFR16_M_MzGfDnXfg02sj4y9VFjDr
ES512 将 ECDSA 与 P-521 和 SHA-512 结合使用。
P-521 的 public 键 (secp521r1, chap. 2.6.1) has a size of 2 x 66 = 132
bytes in uncompressed form (front byte 0x04
). MS specifies the public key for P-521 with the value 0x35534345
.
因此必须按如下方式生成密钥:
var keyType = new byte[] { 0x45, 0x43, 0x53, 0x35 };
var keyLength = new byte[] { 0x42, 0x00, 0x00, 0x00 };
var key = keyType.Concat(keyLength).Concat(publicKeyBytes.Skip(publicKeyBytes.Length - 132)).ToArray();
要签名的数据是header和有效负载(均为Base64url编码)包括分隔符(.
)。签名也是 Base64url 编码的。因此必须按如下方式执行验证:
byte[] headerPayloadBytes = Encoding.UTF8.GetBytes(header + "." + payload);
byte[] signatureBytes = Base64UrlDecode(signature);
bool verified = eCDsaCng.VerifyData(headerPayloadBytes, signatureBytes, HashAlgorithmName.SHA512);
Base64UrlDecode
完成 Base64url 解码,参见例如here 了解实施细节。
我按照@Topaco 的建议生成了密钥,并将其与身份模型的 JwtSecurityTokenHandler 一起使用,并且成功了。
由于某些原因,我尝试使用的功能无法正常工作:
工作代码如下:
public static bool ValidateEcdsa512JwtToken(string token, string publicKey)
{
ECDsa pubKey = LoadPublicKey(publicKey);
var securityTokenHandler = new JwtSecurityTokenHandler();
var validationParameters = new TokenValidationParameters()
{
ValidateAudience = false,
ValidateIssuer = false,
IssuerSigningKey = new ECDsaSecurityKey(pubKey)
};
SecurityToken stoken;
var claims = securityTokenHandler.ValidateToken(token, validationParameters, out stoken);
var verified=claims.Identity.IsAuthenticated;
return verified;
}
private static ECDsa LoadPublicKey(string publicKey)
{
byte[] publicKeyBytes = Convert.FromBase64String(publicKey);
var keyType = new byte[] { 0x45, 0x43, 0x53, 0x35 };
var keyLength = new byte[] { 0x42, 0x00, 0x00, 0x00 };
var key = keyType.Concat(keyLength).Concat(publicKeyBytes.Skip(publicKeyBytes.Length - 132)).ToArray();
CngKey cngKey = CngKey.Import(key, CngKeyBlobFormat.EccPublicBlob);
ECDsaCng eCDsaCng = new ECDsaCng(cngKey);
eCDsaCng.HashAlgorithm = CngAlgorithm.ECDsaP521;
return eCDsaCng;
}
我正在尝试使用 public 字符串格式的密钥来验证 ES512 jwt 令牌:
我正在尝试模仿为 ES256 编写的示例 是这样的:
// The code for ES256
public static void VerifyES512Jwt(string token,string publicKey)
{
byte[] publicKeyBytes = Convert.FromBase64String(publicKey);
string[] parts = token.Split('.');
string header = parts[0];
string payload = parts[1];
string signature = parts[2];
var keyType = new byte[] { 0x45, 0x43, 0x53, 0x31 };
var keyLength = new byte[] { 0x20, 0x00, 0x00, 0x00 };
var key = keyType.Concat(keyLength).Concat(publicKeyBytes.Skip(publicKeyBytes.Length - 64)).ToArray();
CngKey cngKey = CngKey.Import(key, CngKeyBlobFormat.EccPublicBlob);
// the purpose is to get ECDsaCng and verify the payload data
ECDsaCng eCDsaCng = new ECDsaCng(cngKey);
bool result = eCDsaCng.VerifyData(payload, signatureBytes);
}
我正在尝试将此代码用于 ES512,但在获取密钥时卡住了
var keyType = new byte[] { 0x45, 0x43, 0x53, 0x31 };
var keyLength = new byte[] { 0x20, 0x00, 0x00, 0x00 };
var key = keyType.Concat(keyLength).Concat(publicKeyBytes.Skip(publicKeyBytes.Length - 64)).ToArray();
当与上面一起使用时,它会在获取密钥时出错:
CngKey cngKey = CngKey.Import(key, CngKeyBlobFormat.EccPublicBlob);
我使用的public密钥和令牌如下: public 键:
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBgc4HZz+/fBbC7lmEww0AO3NK9wVZ PDZ0VEnsaUFLEYpTzb90nITtJUcPUbvOsdZIZ1Q8fnbquAYgxXL5UgHMoywAib47 6MkyyYgPk0BXZq3mq4zImTRNuaU9slj9TVJ3ScT3L1bXwVuPJDzpr5GOFpaj+WwM Al8G7CqwoJOsW7Kddns=
令牌:
eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzUxMiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE1NjUwOTk2ODgsImV4cCI6MTU5ODE4OTg4NSwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDozNTg4Iiwic3ViIjoiaHR0cDovL2xvY2FsaG9zdDo1MDM3NiIsImZpcnN0bmFtZSI6IkFydmluZCIsImxhc3RuYW1lIjoiS3VtYXIiLCJFbWFpbCI6ImFydmluZC5rdW1hckBzdHJlYW1hbWcuY29tIiwiSWQiOiIxMDEifQ.AVwAJeY44lKrnywnDs7CdUOu3gli2cGafSJ6iP3zT7lkZpd2QnL0k54aVmPVxAGuN5dDnzbYmMTdRl5u2QE92ccOAHrcf5yA2gsvhhAGuDAAeh6Io4VU7v5TOTvwWGRb-ubgdjUvagA_HSJOyeXvFR16_M_MzGfDnXfg02sj4y9VFjDr
ES512 将 ECDSA 与 P-521 和 SHA-512 结合使用。
P-521 的 public 键 (secp521r1, chap. 2.6.1) has a size of 2 x 66 = 132
bytes in uncompressed form (front byte 0x04
). MS specifies the public key for P-521 with the value 0x35534345
.
因此必须按如下方式生成密钥:
var keyType = new byte[] { 0x45, 0x43, 0x53, 0x35 };
var keyLength = new byte[] { 0x42, 0x00, 0x00, 0x00 };
var key = keyType.Concat(keyLength).Concat(publicKeyBytes.Skip(publicKeyBytes.Length - 132)).ToArray();
要签名的数据是header和有效负载(均为Base64url编码)包括分隔符(.
)。签名也是 Base64url 编码的。因此必须按如下方式执行验证:
byte[] headerPayloadBytes = Encoding.UTF8.GetBytes(header + "." + payload);
byte[] signatureBytes = Base64UrlDecode(signature);
bool verified = eCDsaCng.VerifyData(headerPayloadBytes, signatureBytes, HashAlgorithmName.SHA512);
Base64UrlDecode
完成 Base64url 解码,参见例如here 了解实施细节。
我按照@Topaco 的建议生成了密钥,并将其与身份模型的 JwtSecurityTokenHandler 一起使用,并且成功了。 由于某些原因,我尝试使用的功能无法正常工作: 工作代码如下:
public static bool ValidateEcdsa512JwtToken(string token, string publicKey)
{
ECDsa pubKey = LoadPublicKey(publicKey);
var securityTokenHandler = new JwtSecurityTokenHandler();
var validationParameters = new TokenValidationParameters()
{
ValidateAudience = false,
ValidateIssuer = false,
IssuerSigningKey = new ECDsaSecurityKey(pubKey)
};
SecurityToken stoken;
var claims = securityTokenHandler.ValidateToken(token, validationParameters, out stoken);
var verified=claims.Identity.IsAuthenticated;
return verified;
}
private static ECDsa LoadPublicKey(string publicKey)
{
byte[] publicKeyBytes = Convert.FromBase64String(publicKey);
var keyType = new byte[] { 0x45, 0x43, 0x53, 0x35 };
var keyLength = new byte[] { 0x42, 0x00, 0x00, 0x00 };
var key = keyType.Concat(keyLength).Concat(publicKeyBytes.Skip(publicKeyBytes.Length - 132)).ToArray();
CngKey cngKey = CngKey.Import(key, CngKeyBlobFormat.EccPublicBlob);
ECDsaCng eCDsaCng = new ECDsaCng(cngKey);
eCDsaCng.HashAlgorithm = CngAlgorithm.ECDsaP521;
return eCDsaCng;
}