本文介绍了自2017年中以来是否在Azure应用服务(Azure网站)上提供X509Certificate2?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一个.NET Framework 4.7应用程序,该应用程序允许用户上传PFX或PKCS#12格式的X.509证书(认为:"SSL证书"(包括私钥)),然后将证书加载到 System.Security.Cryptography.X509Certificates.X509Certificate2
实例.由于我的应用程序代码还需要重新导出证书,因此我指定了 X509KeyStorageFlags.Exportable
选项.
在生产Web服务器上的IIS下运行时,未加载用于运行 w3wp.exe
的身份的Windows用户配置文件,因此我未指定 UserKeySet
标志.
字符串filePassword = ...Byte [] userProvidedCertificateFile = ...using(X509Certificate2 cert = new X509Certificate2(rawData:userProvidedCertificateFile,password:filePassword,keyStorageFlags:X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet){...}
2017年初,我将此代码部署到了Azure App Service(又名Azure网站)实例,并且工作正常-最初失败后,因为我确实设置了 UserKeySet
标志(就像Azure App Services一样)无法加载用户配置文件证书存储.
但是,自2017年中以来(可能在5月或6月左右),我的应用程序已停止运行-我假定Azure应用服务已移至更新的系统(尽管Kudu报告我的应用程序在Windows Server 2012上运行(:访问被拒绝.".
- 因此,诸如
UserKeySet
和 UserKeySet之类的值|MachineKeySet
和 Exportable
将起作用.
导出证书需要 X509KeyStorageFlags.Exportable
-与所有其他环境相同. 因此,看来 WEBSITE_LOAD_CERTIFICATES
似乎可行-但仅当加载到 X509Certificate2
实例中的证书具有与 WEBSITE_LOAD_CERTIFICATES
中指定的相同的指纹时,代码>.
有什么办法解决这个问题吗?
解决方案
我想了更多关于 WEBSITE_LOAD_CERTIFICATES
似乎有何改变的想法-但我对此真的感到很有趣 仅适用于指定的证书指纹.
因此,我将 WEBSITE_LOAD_CERTIFICATES
值更改为虚拟指纹-任意40个字符的Base16字符串,然后重新运行了测试-并且即使指纹与证书无关,它仍然有效我当时在工作.
似乎简单地定义了 WEBSITE_LOAD_CERTIFICATES
将使Azure网站能够使用 X509Certificate
和 X509Certificate2
-即使加载的证书是从未安装到任何系统范围的或用户配置文件的证书存储中,甚至从未从其中检索到该文件(如MMC.exe的证书管理单元中所示).
似乎在任何地方都没有记录这种行为,所以我在这里提到它.
我已与Azure支持人员联系.
关于我在年中发现的行为变化-很可能我确实为我们正在使用的测试证书设置了 WEBSITE_LOAD_CERTIFICATES
.当我在今年6月下旬进行新部署时,我必须重置应用程序设置,该设置删除了 WEBSITE_LOAD_CERTIFICATES
并因此破坏了 X509Certificate2
实例.
TL; DR:
- 在
portal.azure.com
中打开您的Azure应用服务(Azure网站)刀片- 转到应用程序设置页面
- 滚动到应用设置
- 添加一个新的输入键:
WEBSITE_LOAD_CERTIFICATES
,并为其提供一个虚拟(伪造,伪造,随机生成的)值. -
X509Certificate2(Byte [],String,X509KeyStorageFlags)
构造函数现在可以使用,但请注意:-
keyStorageFlags:X509KeyStorageFlags.MachineKeySet
将失败,并显示拒绝访问" - 所有其他
keyStorageFlags
值,包括 MachineKeySet |UserKeySet
将成功(即 MachineKeySet
本身将失败,但是将 MachineKeySet
与其他位组合使用将起作用)
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.
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 )
{
...
}
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.
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
"The system cannot find the file specified."CryptographicException
"Access denied."
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.
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:
- 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
.
- Running under IIS on a production server (not an Azure App Service) where the
w3wp.exe
user-profile is not loaded:- 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."
- Running under Azure App Service, without
WEBSITE_LOAD_CERTIFICATES
defined:- 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.
- Running under Azure App Service, with
WEBSITE_LOAD_CERTIFICATES
defined as the thumbprint of the certificate that was uploaded:- 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.
- Exporting certificates requires
X509KeyStorageFlags.Exportable
- same as all other environments.
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?
解决方案
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.
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.
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.
I've contacted Azure support about this.
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.
TL;DR:
- Open your Azure App Service (Azure Website) blade in
portal.azure.com
- Go to the Application settings page
- Scroll to App settings
- Add a new entry key:
WEBSITE_LOAD_CERTIFICATES
, and provide a dummy (fake, made-up, randomly-generated) value for it. - 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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!