使用 AzukeKeyVault 密钥签署 JWT

Signing JWT with AzukeKeyVault Key

我必须使用存储在 AzukeKeyVault 中的密钥对 JWT 进行签名,但很难使其正常工作,我目前使用的解决方案无法正常工作,或者正在使用 Secrets 而不是密钥来存储 RSA 密钥(除非我错了,RSA 密钥应该存储为 Secret?)

        JwtSecurityToken jwt = new JwtSecurityToken(jwtHeader, jwtPayload);
        string encodedJwt = jwt.EncodedHeader + "." + jwt.EncodedPayload;
        byte[] encodedJwtBytes = Encoding.UTF8.GetBytes(encodedJwt);
        KeyOperationResult signature = await keyVaultClient.SignAsync(keyId, "RS256", new SHA256CryptoServiceProvider().ComputeHash(encodedJwtBytes));
        string jwtString = encodedJwt + "." + Base64UrlEncoder.Encode(signature.Result);

如果要签署jwt,我们应该使用azure key vault key。具体操作方法请参考以下代码

  1. 创建服务主体。

  2. 配置 sp

    的访问策略
  3. 代码

           #create rsa key
            var clientId = "42e0d080-****c522d988c4";
            var secret = "Gbx2eK64i***.ClJDfQpIjoae:";
            var tenant = "e4c9ab4e-bd2***0ba2a757fb";
            var creds = new ClientSecretCredential(tenant, clientId, secret);
            var keyClient = new KeyClient(new Uri("https://jimkey02.vault.azure.net/"), creds);
            string rsaKeyName = "testkey";
            var rsaKey = new CreateRsaKeyOptions(rsaKeyName, hardwareProtected: false)
            {
                KeySize = 2048,
            };
            await keyClient.CreateRsaKeyAsync(rsaKey);
            
            #sign
             var claimsToSign = new[]
            {
              new Claim("sub", "1234567890"),
              new Claim("name", "John Doe")
            };

            var token = new JwtSecurityToken(

                claims: claimsToSign
            );

            var header = Base64UrlEncoder.Encode(JsonConvert.SerializeObject(new Dictionary<string, string>()
            {
                  {JwtHeaderParameterNames.Alg, "RS256" },
                  {JwtHeaderParameterNames.Typ, "JWT"}
             }));

            var byteData = Encoding.UTF8.GetBytes(header + "." + token.EncodedPayload);
            var hasher = new SHA256CryptoServiceProvider();
            var digest = hasher.ComputeHash(byteData);
             KeyVaultKey key = await keyClient.GetKeyAsync(rsaKeyName);
            var cryptClient = new CryptographyClient(key.Id, creds);
            var signature = await cryptClient.SignAsync("RS256", digest);
            var fullJwt = $"{header}.{token.EncodedPayload}.{Base64UrlEncoder.Encode(signature.Signature)}";
            Console.WriteLine(fullJwt);

            var kid = key.Key.Id.Substring(key.Key.Id.LastIndexOf('/') + 1);

            var jsonString = JsonConvert.SerializeObject(key.Key);
            var jk = new Microsoft.IdentityModel.Tokens.JsonWebKey(jsonString)
            {
                Kid = kid
            };