Azure网站中的站点无法处理X509Certificate2

时间:2013-09-23 12:37:24

标签: c# azure azure-web-sites x509certificate2

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

任何人都可以帮助我理解它为什么会发生以及如何解决它?

6 个答案:

答案 0 :(得分:75)

我猜你找到了一个解决方法,但是如果其他人正在努力解决这个问题,我在另一个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);

答案 1 :(得分:5)

Azure网站现在支持将证书安装到证书存储区。你有机会拍摄吗?

详细信息:http://azure.microsoft.com/blog/2014/10/27/using-certificates-in-azure-websites-applications/

答案 2 :(得分:0)

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

您可能必须升级到托管服务才能在高架环境中运行并执行此工作。

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

答案 3 :(得分:0)

我遇到了完全相同的问题,并且花了很多时间修复它。 在你提到最后一次堆栈调用的文章是函数 LoadCertFromFile ,但在你(和我的)情况下它是 LoadCertFromBlob

所以我找了LoadCertFromBlob并发现了这个:

Why does X509Certificate2 sometimes fail to create from a blob?

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

答案 4 :(得分:0)

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

我在https://vmplace.eu/

中使用了这种方法

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

您也可以参考此项目:https://github.com/onovotny/SignService

mvpbuzz

答案 5 :(得分:0)

我按照the official documentation的说明解决了这个问题。不确定以前是否曾经有过这种选择,但现在已经知道了,而且易于使用/实施。

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

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

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;
    }
}
  1. 我使用以下方法将以前上传的.pfx证书加载到我的应用中:
from pynput.keyboard import Key, Controller
import threading

flag = True    
def gfg2():
    flag = False
    keyboard.press(Key.enter)


timer = threading.Timer(5.0, gfg2)
timer.start()
while flag:
    chip = input()