【问题标题】:Site in Azure Websites fails processing of X509Certificate2Azure 网站中的站点无法处理 X509Certificate2
【发布时间】:2013-09-28 08:37:20
【问题描述】:

我在 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)

谁能帮我理解它发生的原因以及如何解决它?

【问题讨论】:

    标签: c# azure azure-web-app-service x509certificate2


    【解决方案1】:

    我按照the official documentation 的说明解决了这个问题。不确定这是否是以前的选项,但现在可以,而且很容易使用/实施。

    1. 首先,我将 .pfx 证书上传到我的 Azure 应用服务,并在要求输入密码时输入了密码。已复制指纹。

    2. 然后我从 Azure 控制台中运行了以下命令(我只添加了一个指纹)。这很重要,因为它使您的应用能够访问证书:

    az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings WEBSITE_LOAD_CERTIFICATES=<comma-separated-certificate-thumbprints>
    
    1. 我使用以下方法将之前上传的 .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;
        }
    }
    

    【讨论】:

      【解决方案2】:

      在 Azure 网站/Web 应用程序/移动应用程序中 - 您必须使用应用服务计划来导入 SSL 证书 - 所以它不应该是免费或共享的。您不仅可以导入 SSL 证书,还可以导入示例代码签名证书并在 signtool 或 PowerShell 中使用它。

      我在https://vmplace.eu/使用了这个方法

      如果您尝试使用免费或共享计划,则会收到错误消息 - 因此在这些计划中的 Azure 中存在其他版本的 .NET 框架。

      你也可以参考这个项目:https://github.com/onovotny/SignService

      mvpbuzz

      【讨论】:

        【解决方案3】:

        Azure 网站现在具有将证书安装到证书存储的本机支持。你试过了吗?

        详情在这里:http://azure.microsoft.com/blog/2014/10/27/using-certificates-in-azure-websites-applications/

        【讨论】:

        • 那个链接拯救了我的一天。非常感谢!
        • 像魅力一样工作
        • 旧门户中管理网站的部分已被弃用。
        【解决方案4】:

        我猜你找到了解决方法,但如果其他人正在为此苦苦挣扎,我在另一个 SO 问题中找到了答案:

        How can constructing an X509Certificate2 from a PKCS#12 byte array throw CryptographicException("The system cannot find the file specified.")?

        神奇的是指定 X509KeyStorageFlags 存储标志。示例:

        var myCertificae = new X509Certificate2(
            certificateData,
            securePasswordString,
            X509KeyStorageFlags.MachineKeySet | 
            X509KeyStorageFlags.PersistKeySet | 
            X509KeyStorageFlags.Exportable);
        

        【讨论】:

        • 谢谢。这也帮助了我在 webjob 实例中。我收到错误:由于退出代码 -1073740940,作业失败
        • 这是出现此错误号 1073740940 的唯一搜索结果。当我将它作为 Web 作业运行时,没有附加错误,只是存在代码。非常感谢@ThomasEdmondson 让我发疯。
        • 这对我在 Azure Web 应用程序上起到了作用,谢谢!这应该是公认的答案。
        • 这应该是答案
        • 顺便说一句:您可以为securePasswordString传入一个空值。我从 Azure KeyVault 中提取了一个完整的 PPK 证书,它给了我一个 cer=byte[],但没有密码。这对我有用。
        【解决方案5】:

        我遇到了完全相同的问题,并且花了好几个小时来解决它。 在您提到的最后一个堆栈调用的文章中,函数是 LoadCertFromFile,但在您(和我)的情况下,它是 LoadCertFromBlob

        所以我查找了 LoadCertFromBlob 并找到了这个:

        Why does X509Certificate2 sometimes fail to create from a blob?

        解决方案是进入 IIS 并将应用程序池标识从“ApplicationPoolIdentity”更改为“LocalService”,以便将证书加载到正确的本地文件夹中。

        【讨论】:

        • 不,我不从 blob 加载证书,而是从字节数组加载它。是的,您是对的,问题出在应用程序池身份的访问权限上。但是我在 Azure 网站中部署了我的应用程序。我无法更改 IIS 那里的应用程序池标识。因此,我将其移至托管服务。
        • 我说的是您报告的异常中的“_LoadCertFromBlob”调用。
        • 或者您可以坚持使用应用程序身份,但将 Load User Profile 设置为 true。
        【解决方案6】:

        Azure 网站在共享环境中运行。我假设证书的构造函数正在尝试在实例上创建一些临时信息并且它没有权限。

        您可能必须升级到托管服务才能在提升的环境中运行并执行这项工作。

        另外,您是否验证过密码正确?如果不需要密码,则至少必须将 string.Empty 传递给构造函数。传入 NULL 值也会导致此异常。

        【讨论】:

        • 我们寻找解决方案没有成功。因此,我们将应用程序移至托管服务。
        猜你喜欢
        • 1970-01-01
        • 2023-03-12
        • 1970-01-01
        • 2016-04-27
        • 1970-01-01
        • 1970-01-01
        • 2012-11-23
        • 1970-01-01
        • 2019-02-09
        相关资源
        最近更新 更多