Azure 网站中的站点无法处理 X509Certificate2
本文关键字:处理 X509Certificate2 站点 网站 Azure | 更新日期: 2023-09-27 18:32:36
我在 Azure 网站(不是托管服务)中有站点,我需要在那里处理带有私钥的 .pfx 证书。
var x509Certificate2 = new X509Certificate2(certificate, password);
但我面临着以下异常:
System.Security.Cryptography.CryptographicException: The system cannot find the file specified.
at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
at System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromBlob(Byte[] rawData, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx)
at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob(Byte[] rawData, Object password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
在文章 http://blog.tylerdoerksen.com/2013/08/23/pfx-certificate-files-and-windows-azure-websites/中,我发现发生这种情况是因为默认情况下系统使用用户的本地目录来存储密钥。但 Azure 网站没有本地用户配置文件目录。在同一篇文章中,作者建议使用X509KeyStorageFlags.MachineKeySet
标志。
var x509Certificate2 = new X509Certificate2(certificate, password, X509KeyStorageFlags.MachineKeySet);
但现在我还有其他例外:
System.Security.Cryptography.CryptographicException: Access denied.
at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
at System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromBlob(Byte[] rawData, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx)
at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob(Byte[] rawData, Object password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
任何人都可以帮助我了解为什么会发生这种情况以及如何解决它吗?
我想你找到了解决方法,但如果其他人正在为此苦苦挣扎,我在另一个 SO 问题中找到了答案:
如何从 PKCS#12 字节数组构造 X509Certificate2 抛出加密异常("系统找不到指定的文件。
神奇的是指定 X509KeyStorageFlags 存储标志。例:
var myCertificae = new X509Certificate2(
certificateData,
securePasswordString,
X509KeyStorageFlags.MachineKeySet |
X509KeyStorageFlags.PersistKeySet |
X509KeyStorageFlags.Exportable);
网站现在具有将证书安装到证书存储的本机支持。 你试过了吗?
详情请见:http://azure.microsoft.com/blog/2014/10/27/using-certificates-in-azure-websites-applications/
Azure 网站在共享环境中运行。我假设证书的构造函数正在尝试在实例上创建一些临时信息,并且它没有权限.
您可能需要升级到托管服务才能在提升的上下文中运行并执行此工作.
另外,您是否验证了密码是否正确?如果它不需要密码,则至少必须传递字符串。为构造函数清空。传入 NULL 值也会导致此异常。
我遇到了完全相同的问题,并且花费了很多时间来修复它。在您提到的文章中,最后一个堆栈调用是针对函数 LoadCertFromFile,但在您(和我的)案例中,它是 LoadCertFromBlob。
所以我寻找LoadCertFromBlob并找到了这个:
为什么 X509Certificate2 有时无法从 Blob 创建?
解决方案是进入 IIS 并将应用程序池标识从"ApplicationPoolIdentity"更改为"LocalService",以便将证书加载到正确的本地文件夹中。
在 Azure 网站/Web 应用/移动应用中 - 必须使用应用服务计划来导入 SSL 证书 - 因此它不应该是免费或共享的。您不仅可以导入 SSL 证书,还可以导入示例代码签名证书,并在签名工具或从 PowerShell 中使用它。
我在 https://vmplace.eu/中使用了这种方法
如果尝试使用免费或共享计划,则会收到错误 - 因此在这些计划的 Azure 中,有其他版本的 .NET 框架。
您也可以参考此项目:https://github.com/onovotny/SignService
MVPBUZZ
我按照官方文档中的说明解决了这个问题。不确定这以前是否是一个选项,但现在是,并且易于使用/实现。
-
首先,我将 .pfx 证书上传到我的 Azure 应用服务,并在要求输入密码时输入密码。已复制指纹。
-
然后,我从 Azure 控制台内部运行以下命令(我只添加了一个指纹)。这很重要,因为它使应用能够访问证书:
az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings WEBSITE_LOAD_CERTIFICATES=<comma-separated-certificate-thumbprints>
- 我使用以下方法将以前上传的 .pfx 证书加载到我的应用程序中:
public X509Certificate2 GetAzureCertificate(string thumbprint, bool validOnly)
{
using (var certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser))
{
certStore.Open(OpenFlags.ReadOnly);
var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, validOnly);
var cert = certCollection.OfType<X509Certificate2>().FirstOrDefault();
if (cert == null)
{
throw new Exception($"Cert not found. Total cert count : {certStore.Certificates.Count}.");
}
return cert;
}
}