【问题标题】:ASP.NET Core - Data protectionASP.NET Core - 数据保护
【发布时间】:2026-02-16 01:00:02
【问题描述】:

在我的应用程序中,我已配置数据保护机制以将生成的密钥存储在系统上的文件中:

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 编码的。解码后我们有以下密钥:

"'

但它有 66 个字符而不是 32 个。如何获取 32 位 AES 对称密钥,因为我不明白 ASP.NET Core 是如何保存这个密钥的。

如果有任何帮助,我将不胜感激。

【问题讨论】:

  • 是的!我正在尝试通过 Redis 保留密钥,但我找不到关于反序列化结构的任何文档。 Convert.FromBase64String(key) 产生一个 64 字节的值,但 AES_256_CBC 仅适用于 32 字节的密钥?

标签: asp.net-core cryptography aes encryption-symmetric data-protection


【解决方案1】:

密钥环中的“masterKey”值似乎实际上是一个 64 字节的密钥派生密钥 (KDK),而不是简单的 base64 AES 密钥。

https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/implementation/subkeyderivation?view=aspnetcore-2.2

这意味着您可以从此 KDK 派生 AES 子密钥。这就是默认的ManagedAuthenticatedEncryptor.cs 实现的方式。

如果我能找到或编写一个独立的密钥提取器函数,我会在此处添加它(除非有人击败我)。

希望有帮助!

编辑1:

经过五天的工作,我已经能够将AspNetCore codebase 的各个部分组合成this monstrosity。如果您可以正确获取 AAD 值,这将从 KDK 中提取 AES 和 SHA256 密钥,然后解密 ASPNetCore 共享 cookie 有效负载。

【讨论】:

    【解决方案2】:

    为了帮助您,我编写了一个将 Data Proteciton 密钥环存储在 Azure Key Vault 中的实现。我在这里写了一篇博客:

    Storing the ASP.NET Core Data Protection Key Ring in Azure Key Vault

    但是,问题是为什么您需要在字节/base64 级别处理各个键?要将它们存储在其他地方,您只需实现 IXmlRepository 接口并且使用它非常简单。无需处理原始密钥字节。

    【讨论】: