JWT 加密的密钥管理 (ASP.NET Core 5)

时间:2021-03-11 20:07:58

标签: c# encryption jwt

我需要一些有关 ASP.NET Core 5 中 JWT 加密的帮助。具体来说,这更多是关于密钥管理,我被困在这里。

令牌的创建由单独的 WebAPI 完成,而令牌验证应由服务器完成。因此,我需要在两个实例之间交换密钥。此外,使用的键应按定义的时间间隔轮换。因此我通过 .AddDataProtected() 添加了一个密钥库,它已经生成了密钥并且可以工作。

我看到了三个选项,其中至少有两个可能是错误的(或者至少是次优的):

  • 选项 1:使用密钥库中的当前默认密钥为所有用户加密所有令牌,直到它过期(如果从安全角度来看没有异议,这将是最容易管理的)。< /li>
  • 选项 2:为密钥库中的每个用户创建一个单独的密钥(我不确定密钥库是否适用于此)。
  • 选项 3:为每个用户生成随机密钥,然后使用密钥库中的默认密钥对它们进行加密,然后将它们加密存储(我认为很难处理)。

也许我缺少一个选项 4。也许我只是对源头一无所知,或者我已经陷入了某些事情,因为我已经修修补补了好几天了。

这是我的 SecurityTokenDescriptor 的源代码摘录:

SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor()
{
    // ...
    EncryptingCredentials =
        new EncryptingCredentials(
            new SymmetricSecurityKey(mySecretKey) { KeyId = "MySecretKeyId" },
            SecurityAlgorithms.Aes256KW,
            SecurityAlgorithms.Aes256CbcHmacSha512)
    // ...
};

所以它专门针对 EncryptionCredentials,而不是用于签名的密钥。

在我的密钥库中,会自动生成这样的默认密钥:

<?xml version="1.0" encoding="utf-8"?>
<key id="539676e1-708a-4201-a854-f5313664d38b" version="1">
  <creationDate>2021-03-12T06:57:50.60916Z</creationDate>
  <activationDate>2021-03-12T06:57:50.599208Z</activationDate>
  <expirationDate>2021-03-19T06:57:50.599208Z</expirationDate>
  <descriptor deserializerType="Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60">
    <descriptor>
      <encryption algorithm="AES_256_CBC" />
      <validation algorithm="HMACSHA512" />
      <encryptedSecret decryptorType="Microsoft.AspNetCore.DataProtection.XmlEncryption.DpapiXmlDecryptor, Microsoft.AspNetCore.DataProtection, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60" xmlns="http://schemas.asp.net/2015/03/dataProtection">
        <encryptedKey xmlns="">
          <!-- This key is encrypted with Windows DPAPI. -->
          <value>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAFWCzAu76wUqeZ7cRU+pUkgAAAAACAAAAAAAQZgAAAAEAACAAAACCrJTUNPrpp+PIxD0TUq1Ij+666NHst38HKnFDuCjrvQAAAAAOgAAAAAIAACAAAACWT76SAg9Olp3nPt67K+aiYzo/KEH9KeGcAbZI1nOHVVABAADLoF6CVryp6A7oMgGa3xg9R8pjnoWC+b2QECXlg2F89uXPbE4kQjdmbir2K7ISgYxK2kPuhaNZQGKg6cROrj3q6wiWYCxjkk/jzdZRrcj4EHGL05CuWUwKLfpwtMHcUYhPY3kcLbiX1D8X/BHXUDqfjNfs0LGwiW658ymUFBTIWXXw1Ovg8P07cWTzRKcEVT/UOIWVVS5ripRwlRaJlpMbI2G1/QUgoFJ6hs8pjwiqMQL/P+51ePENdgxQbl+U/PGp+BgjNxbLGzNvLky/ROZpWCiGUHzEQyTGd4rRs2vy7nfFhLg/Zn1UB+6Q9tQ4amrWRZKkR4S5NJQ1kUv8gEqYjzHMv/V1vLVSD5kxZiegu3cE5AX8LHPV9Y9eNZTQeRFN4h7nPA4qiguVdcLEhGI99L4viG39gnYdBq8krlWCr5RcEqVy3q2lroAQHNixomJAAAAASHv5OVaUuGdDp+KO14+0rBEjr3xMDZaaBiwo8drV7G53uvK4mhO1DSeNJVakJdtZIfOwYJS9S3WknLaTxlBWLg==</value>
        </encryptedKey>
      </encryptedSecret>
    </descriptor>
  </descriptor>
</key>

如果密钥的期限到期,密钥库会自动为我创建一个新的(默认)密钥并保留前任,但另外还用于进一步的解密任务。但是,从此时起,将使用新的默认密钥创建新请求。

我指的是这个Microsoft document

通过 DataProtection 我得到两个接口组:

  • IKeyManager(用于管理密钥库的密钥环)
  • IDataProtectionProvider / IDataProtector(使用密钥库中的默认密钥加密/解密数据)

这反过来又让我想到了上述三个选项。我正在尝试以某种方式将所有这些信息整合在一起,以构建一个合理且实用的令牌工作流程。

我现在应该直接在 SecurityTokenDescriptor 的 EncryptingCredentials 中使用密钥库中的默认密钥(通过 IKeyManager),还是应该通过 IKeyManager.CreateNewKey() 为每个用户/令牌创建一个新密钥。或者只是使用 IDataProtector 来保护令牌密钥并单独存储它们?

我将非常感谢任何形式的帮助!谢谢!

0 个答案:

没有答案