我需要一些有关 ASP.NET Core 5 中 JWT 加密的帮助。具体来说,这更多是关于密钥管理,我被困在这里。
令牌的创建由单独的 WebAPI 完成,而令牌验证应由服务器完成。因此,我需要在两个实例之间交换密钥。此外,使用的键应按定义的时间间隔轮换。因此我通过 .AddDataProtected()
添加了一个密钥库,它已经生成了密钥并且可以工作。
我看到了三个选项,其中至少有两个可能是错误的(或者至少是次优的):
也许我缺少一个选项 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 我得到两个接口组:
这反过来又让我想到了上述三个选项。我正在尝试以某种方式将所有这些信息整合在一起,以构建一个合理且实用的令牌工作流程。
我现在应该直接在 SecurityTokenDescriptor 的 EncryptingCredentials 中使用密钥库中的默认密钥(通过 IKeyManager),还是应该通过 IKeyManager.CreateNewKey() 为每个用户/令牌创建一个新密钥。或者只是使用 IDataProtector 来保护令牌密钥并单独存储它们?
我将非常感谢任何形式的帮助!谢谢!