本文介绍了自 2017 年中以来 Azure 应用服务(Azure 网站)上的 X509Certificate2?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a .NET Framework 4.7 application that allows users to upload X.509 certificates in PFX or PKCS#12 format (think: "SSL certificates" with the private key included), it then loads the certificate into a System.Security.Cryptography.X509Certificates.X509Certificate2 instance. As my application code also needs to re-export the certificate I specify the X509KeyStorageFlags.Exportable option.

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

When running under IIS on my production web-server, the Windows user-profile for the identity that w3wp.exe runs under is not loaded, so I do not specify the UserKeySet flag.

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 应用服务一样不加载用户配置文件证书存储.

In early 2017 I deployed this code to an Azure App Service (aka Azure Website) instance and it worked okay - after initially failing because I did have the UserKeySet flag set (as Azure App Services do not load a user-profile certificate store.

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

However, since mid-2017 (possibly around May or June) my application has stopped working - I assume the Azure App Service was moved to an updated system (though Kudu reports my application is running on Windows Server 2012 (NT 6.2.9200.0).

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

It currently fails with two error messages that varied depending on input:

  • CryptographicException "系统找不到指定的文件."
  • CryptographicException访问被拒绝."
  • CryptographicException "The system cannot find the file specified."
  • CryptographicException "Access denied."

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

I wrote an extensive test-case that tries different combinations of X509Certificate2 constructor arguments, as well as with and without the WEBSITE_LOAD_CERTIFICATES Azure application setting.

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

Here are my findings when working with an uploaded PFX/PKCS#12 certificate file that contains a private key and does not have password-protection:

  • 在我的开发箱上运行在 IIS Express 下:
    • 无论 X509KeyStorageFlags 值如何,加载证书文件始终成功.
    • 导出证书文件至少需要 X509KeyStorageFlags.Exportable.
    • Running under IIS Express on my development box:
      • Loading the certificate file always succeeds, regardless of X509KeyStorageFlags value.
      • Exporting the certificate file requires at least X509KeyStorageFlags.Exportable.
      • 加载证书文件需要 X509KeyStorageFlags.UserKeySet 设置,否则总是成功.
      • 导出证书文件至少需要 X509KeyStorageFlags.Exportable,否则总是成功,否则失败并显示Key not valid for use in specified state".
      • Loading the certificate file requires that X509KeyStorageFlags.UserKeySet is not set, but otherwise always succeeds.
      • Exporting the certificate file requires at least X509KeyStorageFlags.Exportable, but otherwise always succeeds, otherwise it fails with "Key not valid for use in specified state."
      • 加载设置了 MachineKeySetUserKeySet 设置为 not 的证书失败,并出现 CryptographicException:访问被拒绝."
      • 使用任何其他 keyStorageFlags 值加载证书,包括 UserKeySet |机键集 |可导出 或仅DefaultKeySet 失败并出现CryptographicException:系统找不到指定的文件."
      • 由于我根本无法加载证书,因此无法测试导出证书.
      • Loading the certificate with MachineKeySet set and UserKeySet is not set fails with a CryptographicException: "Access denied."
      • Loading the certificate with any other keyStorageFlags value, including values like UserKeySet | MachineKeySet | Exportable or just DefaultKeySet fails with a CryptographicException: "The system cannot find the file specified."
      • As I was not able to load the certificate at all I could not test exporting certificates.
      • 使用 MachineKeySet UserKeySet 加载证书 设置,失败并出现 CryptographicException:访问被拒绝.".
        • UserKeySetUserKeySet 这样的值 |MachineKeySetExportable 将起作用.
        • Loading the certificate with MachineKeySet and UserKeySet is not set, fails with CryptographicException: "Access denied." .
          • So values like UserKeySet and UserKeySet | MachineKeySet and Exportable will work.

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

          So it seems that WEBSITE_LOAD_CERTIFICATES seems to work - but only if the certificate being loaded into an X509Certificate2 instance has the same thumbprint as specified in WEBSITE_LOAD_CERTIFICATES.

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

          Is there any way around this?

          推荐答案

          我想了更多关于 WEBSITE_LOAD_CERTIFICATES 似乎有所作为 - 但我有一种有趣的感觉 真的 仅使用指定的证书指纹.

          I thought more about how WEBSITE_LOAD_CERTIFICATES seems to make a difference - but I had a funny feeling about it really only working with the certificate thumbprint that's specified.

          所以我将 WEBSITE_LOAD_CERTIFICATES 值更改为虚拟指纹 - 任意 40 个字符的 Base16 字符串,然后重新运行我的测试 - 即使指纹与证书无关,它也能正常工作我正在合作.

          So I changed the WEBSITE_LOAD_CERTIFICATES value to a dummy thumbprint - an arbitrary 40-character Base16 string, and re-ran my test - and it worked, even though the thumbprint had no relation to the certificate I was working with.

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

          It seems that simply having WEBSITE_LOAD_CERTIFICATES defined will enable the the Azure website's ability to use X509Certificate and X509Certificate2 - even if the loaded certificate is never installed into, or even retrieved from, any systemwide or user-profile certificate store (as seen in the Certificates snap-in for MMC.exe).

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

          This behaviour does not seem to be documented anywhere, so I'm mentioning it here.

          我已就此联系 Azure 支持.

          I've contacted Azure support about this.

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

          Regarding the behavioural change I noticed at mid-year - it's very likely that I did have WEBSITE_LOAD_CERTIFICATES originally set for a testing certificate we were using. When I made a new deployment later in the year around June I must have reset the Application settings which removed the WEBSITE_LOAD_CERTIFICATES and so broke X509Certificate2 instances.

          1. portal.azure.com
          2. 中打开您的 Azure 应用服务(Azure 网站)刀片
          3. 转到应用设置页面
          4. 滚动到应用设置
          5. 添加一个新的条目键:WEBSITE_LOAD_CERTIFICATES,并为其提供一个虚拟(伪造的、虚构的、随机生成的)值.
          6. X509Certificate2(Byte[], String, X509KeyStorageFlags) 构造函数现在可以工作,但请注意:
            • keyStorageFlags: X509KeyStorageFlags.MachineKeySet 将失败并显示访问被拒绝"
            • 所有其他 keyStorageFlags 值,包括 MachineKeySet |UserKeySet 会成功(即 MachineKeySet 本身会失败,但 MachineKeySet 与其他位设置一起使用会起作用.
          1. Open your Azure App Service (Azure Website) blade in portal.azure.com
          2. Go to the Application settings page
          3. Scroll to App settings
          4. Add a new entry key: WEBSITE_LOAD_CERTIFICATES, and provide a dummy (fake, made-up, randomly-generated) value for it.
          5. The X509Certificate2( Byte[], String, X509KeyStorageFlags ) constructor will now work, but note:
            • keyStorageFlags: X509KeyStorageFlags.MachineKeySet will fail with "Access denied"
            • All other keyStorageFlags values, including MachineKeySet | UserKeySet will succeed (i.e. MachineKeySet by itself will fail, but MachineKeySet used in conjunction with other bits set will work).

          这篇关于自 2017 年中以来 Azure 应用服务(Azure 网站)上的 X509Certificate2?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-12 22:21