在我的应用程序中,我配置了数据保护机制,以将生成的密钥存储在系统上的文件中:
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"C:keys"));
它正在起作用。在我的"keys"目录中生成了一个文件,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<key id="7139a96c-1d75-468f-a343-1d0d363650a7" version="1">
<creationDate>2019-04-22T14:27:34.9530001Z</creationDate>
<activationDate>2019-04-22T14:27:34.9359888Z</activationDate>
<expirationDate>2019-07-21T14:27:34.9359888Z</expirationDate>
<descriptor deserializerType="Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60">
<descriptor>
<encryption algorithm="AES_256_CBC" />
<validation algorithm="HMACSHA256" />
<masterKey p4:requiresEncryption="true" xmlns:p4="http://schemas.asp.net/2015/03/dataProtection">
<!-- Warning: the key below is in an unencrypted form. -->
<value>JzykGRqFcYWq3MPQAyuXe4IlEGrj62ghnCEMMuv0YzRKmHjzlfSOcbnk7+cJpDGe0PLKfCwcNPfOKplqu1xfDg==</value>
</masterKey>
</descriptor>
</descriptor>
</key>
现在我不明白一件事。我正在使用AES_256_CBC算法,但密钥的长度是 88 个字符而不是 32 个字符。
所以我发现密钥是使用 base64 编码的。解码后,我们有以下密钥:
"'<¤qªÜÃÐ+{%jãëh!!f2ëôc4Jxóôq¹äïç ¤1ÐòÊ|,4÷Î*j»_">
但它有 66 个字符而不是 32 个字符。如何获取 32 位 AES 对称密钥,因为我不明白 ASP.NET Core 如何保存此密钥。
我将非常感谢任何帮助。
密钥环中的"masterKey"值实际上似乎是一个 64 字节的密钥派生密钥 (KDK(,而不是一个简单的 base64 AES 密钥。
https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/implementation/subkeyderivation?view=aspnetcore-2.2
这意味着可以从此 KDK 派生 AES 子项。这就是默认的 ManagedAuthenticatedEncryptor.cs 实现的方式。
如果我能找到或编写一个独立的密钥提取器函数,我会在这里添加它(除非有人打败我(。
希望对您有所帮助!
编辑 1:
经过五天的工作,我已经能够将AspNetCore代码库的各个部分破解成这个怪物。如果可以正确获取 AAD 值,这将从 KDK 中提取 AES 和 SHA256 密钥,然后解密 ASPNetCore 共享 cookie 有效负载。
为了帮助你,我编写了一个实现,用于在 Azure 密钥保管库中存储数据保护密钥环。我在这里写了博客:
将ASP.NET 核心数据保护密钥环存储在 Azure 密钥保管库中
但是,问题是为什么您需要在字节/base64 级别处理各个键?要将它们存储在其他地方,您只需实现IXmlRepository接口,使用它非常简单。无需处理原始密钥字节。