c# - ES 512 JWT token 验证

标签 c# jwt elliptic-curve ecdsa

我正在尝试使用字符串格式的公钥验证 ES512 jwt token :

我正在尝试模仿为 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,但在获取 key 时遇到困难

        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(); 

与上述方法一起使用时,获取 key 时会出错:

CngKey cngKey = CngKey.Import(key, CngKeyBlobFormat.EccPublicBlob);

我使用的公钥和 token 如下: 公钥:

MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBgc4HZz+/fBbC7lmEww0AO3NK9wVZ PDZ0VEnsaUFLEYpTzb90nITtJUcPUbvOsdZIZ1Q8fnbquAYgxXL5UgHMoywAib47 6MkyyYgPk0BXZq3mq4zImTRNuaU9slj9TVJ3ScT3L1bXwVuPJDzpr5GOFpaj+WwM Al8G7CqwoJOsW7Kddns=

token :

eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzUxMiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE1NjUwOTk2ODgsImV4cCI6MTU5ODE4OTg4NSwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDozNTg4Iiwic3ViIjoiaHR0cDovL2xvY2FsaG9zdDo1MDM3NiIsImZpcnN0bmFtZSI6IkFydmluZCIsImxhc3RuYW1lIjoiS3VtYXIiLCJFbWFpbCI6ImFydmluZC5rdW1hckBzdHJlYW1hbWcuY29tIiwiSWQiOiIxMDEifQ.AVwAJeY44lKrnywnDs7CdUOu3gli2cGafSJ6iP3zT7lkZpd2QnL0k54aVmPVxAGuN5dDnzbYmMTdRl5u2QE92ccOAHrcf5yA2gsvhhAGuDAAeh6Io4VU7v5TOTvwWGRb-ubgdjUvagA_HSJOyeXvFR16_M_MzGfDnXfg02sj4y9VFjDr

最佳答案

ES512使用带有 P-521 和 SHA-512 的 ECDSA。

P-521 的公钥( secp521r1 ,第 2.6.1 章)的大小为 2 x 66 = 132未压缩形式的字节(前字节 0x04 )。 MS 指定 P-521 的公钥,值为 0x35534345 .

因此 key 必须按如下方式生成:

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了解实现细节。

关于c# - ES 512 JWT token 验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62553216/

相关文章:

c# - 验证 JWT 出现奇怪的 “Unable to match key kid” 错误

javascript - 引用错误: Users is not defined

python - 椭圆曲线暴力破解

c# - 在 Controller (ASP.NET Core)中进行 DI 时如何在 SignalR 中使用 Clients.Caller 和 Clients.Others?

c# - 取消 PreviewKeyDown

c# - 如何使用反射从多级继承类中获取 protected friend 属性?

java - 从主体访问电子邮件 ID,其中身份验证在 Azure Active Directory 中完成

java - 用于可视化和实现椭圆曲线加密的工具

python-2.7 - Python——用于椭圆曲线的 Matplotlib 与 sympy solve()

c# - 有没有办法在 ASP Net/ASP Net Core 中使用 URL 路径段中的参数