【问题标题】:X509Certificate2 on Azure App Services (Azure Websites) since mid-2017?自 2017 年中以来 Azure 应用服务(Azure 网站)上的 X509Certificate2?
【发布时间】:2021-06-06 16:38:07
【问题描述】:

我有一个 .NET Framework 4.7 应用程序,它允许用户上传 PFX 或 PKCS#12 格式的 X.509 证书(想想:包含私钥的“SSL 证书”),然后将证书加载到 @987654321 @ 实例。由于我的应用程序代码还需要重新导出证书,因此我指定了 X509KeyStorageFlags.Exportable 选项。

在我的生产网络服务器上的 IIS 下运行时,w3wp.exe 在其下运行的身份的 Windows 用户配置文件未加载,因此我没有指定 UserKeySet 标志。

String filePassword = ...
Byte[] userProvidedCertificateFile = ...

using( X509Certificate2 cert = new X509Certificate2( rawData: userProvidedCertificateFile, password: filePassword, keyStorageFlags: X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet )
{
    ...
}

在 2017 年初,我将此代码部署到 Azure 应用服务(又名 Azure 网站)实例,它工作正常 - 在最初失败后,因为我确实设置了 UserKeySet 标志(因为 Azure 应用服务不加载用户 -配置文件证书存储。

但是,自 2017 年年中(可能在 5 月或 6 月左右)以来,我的应用程序已停止工作 - 我假设 Azure 应用程序服务已移至更新的系统(尽管 Kudu 报告我的应用程序正在 Windows Server 2012 上运行 (NT 6.2.9200.0 )。

它目前失败并显示两条因输入而异的错误消息:

  • CryptographicException "系统找不到指定的文件。"
  • CryptographicException "访问被拒绝。"

我编写了一个广泛的测试用例,尝试了 X509Certificate2 构造函数参数的不同组合,以及使用和不使用 WEBSITE_LOAD_CERTIFICATES Azure 应用程序设置。

以下是我在处理上传的 PFX/PKCS#12 证书文件时的发现,该文件包含私钥且没有密码保护:

  • 在我的开发盒上运行在 IIS Express 下:
    • 无论X509KeyStorageFlags 值如何,加载证书文件始终成功。
    • 导出证书文件至少需要X509KeyStorageFlags.Exportable
  • 在未加载 w3wp.exe 用户配置文件的生产服务器(不是 Azure 应用服务)上的 IIS 下运行:
    • 加载证书文件需要设置X509KeyStorageFlags.UserKeySet,否则总是成功。
    • 导出证书文件至少需要X509KeyStorageFlags.Exportable,否则总是成功,否则失败并显示“Key not valid for use in specified state”。
  • 在 Azure 应用服务下运行,未定义 WEBSITE_LOAD_CERTIFICATES
    • 加载设置了MachineKeySet 并且设置了UserKeySet 的证书失败并显示CryptographicException:“访问被拒绝。”
    • 使用任何其他keyStorageFlags 值(包括UserKeySet | MachineKeySet | Exportable 或仅DefaultKeySet 之类的值)加载证书失败,并显示CryptographicException:“系统找不到指定的文件。”
    • 由于我根本无法加载证书,因此无法测试导出证书。
  • 在 Azure 应用服务下运行,WEBSITE_LOAD_CERTIFICATES 定义为已上传证书的指纹:
    • 使用MachineKeySet UserKeySet 加载证书 设置,失败并显示CryptographicException:“访问被拒绝。” .
      • 因此,UserKeySetUserKeySet | MachineKeySetExportable 等值将起作用。
    • 导出证书需要X509KeyStorageFlags.Exportable - 与所有其他环境相同。

因此,WEBSITE_LOAD_CERTIFICATES 似乎可以工作 - 但前提是加载到 X509Certificate2 实例中的证书具有与 WEBSITE_LOAD_CERTIFICATES 中指定的相同的指纹。

有没有办法解决这个问题?

【问题讨论】:

    标签: azure azure-web-app-service x509certificate


    【解决方案1】:

    我想了更多关于 WEBSITE_LOAD_CERTIFICATES 似乎如何产生影响 - 但我有一种有趣的感觉真的只使用指定的证书指纹。

    因此,我将 WEBSITE_LOAD_CERTIFICATES 值更改为虚拟指纹 - 任意 40 个字符的 Base16 字符串,然后重新运行我的测试 - 尽管指纹与我正在使用的证书无关,但它仍然有效。

    似乎只要定义了WEBSITE_LOAD_CERTIFICATES,Azure 网站就能够使用X509CertificateX509Certificate2——即使加载的证书从未安装到任何系统范围或用户配置文件中,甚至从未从中检索到证书存储(如 MMC.exe 的证书管理单元中所示)。

    这种行为似乎没有记录在任何地方,所以我在这里提到它。

    我已就此联系 Azure 支持。

    关于我在年中注意到的行为变化 - 我很可能确实为我们使用的测试证书设置了 WEBSITE_LOAD_CERTIFICATES。当我在今年晚些时候在 6 月左右进行新部署时,我必须重置 应用程序设置,它删除了 WEBSITE_LOAD_CERTIFICATES 并因此破坏了 X509Certificate2 实例。

    TL;DR:

    1. portal.azure.com 中打开您的 Azure 应用服务(Azure 网站)刀片
    2. 转到应用程序设置页面
    3. 滚动到应用设置
    4. 添加一个新的输入键:WEBSITE_LOAD_CERTIFICATES,并为其提供一个虚拟(伪造、虚构、随机生成)值。
    5. X509Certificate2( Byte[], String, X509KeyStorageFlags ) 构造函数现在可以工作,但请注意:
      • keyStorageFlags: X509KeyStorageFlags.MachineKeySet 将失败并显示“拒绝访问”
      • 所有其他keyStorageFlags 值,包括MachineKeySet | UserKeySet 都会成功(即MachineKeySet 本身会失败,但MachineKeySet 与其他位设置一起使用会起作用)。

    【讨论】:

    • 这对我有用,谢谢! p.s.以下构造函数也可以工作:X509Certificate2("fileName.pfx", "password")
    • 疯了,你是怎么发现这个的。我偶然发现了这个和奇怪的例外,如果没有这个答案,我永远不会卖掉。
    猜你喜欢
    • 2013-09-28
    • 1970-01-01
    • 1970-01-01
    • 2015-12-03
    • 2014-07-05
    • 2012-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多