Azure,应用服务,从字符串创建 X509Certificate2 对象

Azure, App-service, create X509Certificate2 object from string

在 Azure 中拥有应用服务,并使用 AzureServiceManagementAPI,我正在下载包含每个订阅的管理证书的文件。

我尝试创建 X509Certificate2 对象时,如何使用文件中的证书字符串。

string cerStr = subscription.Attribute("ManagementCertificate").Value;
X509Certificate2 x509 = new X509Certificate2(Convert.FromBase64String(cerStr), string.Empty, X509KeyStorageFlags.MachineKeySet)

X509Certificate2 的构造函数抛出异常

Access denied.

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)

由于没有人回答过这个问题,我会尝试着去做。如有错误请指正,但我认为问题出在下面这行代码:

new X509Certificate2(Convert.FromBase64String(cerStr), string.Empty, X509KeyStorageFlags.MachineKeySet) 

这行代码将尝试将新证书添加到虚拟机的证书存储中。运行时使用的所有证书都需要托管在某个地方的商店中。这不是一个好主意,因为托管应用程序服务的虚拟机的证书存储不是您应该存储任何内容的东西,它是基础架构的一部分,在您使用应用程序服务时与您无关。

您需要做的是通过 Azure 门户上传证书(如果它们还没有)。为此,我最终重新使用了一个已经存在的 SSL 证书。完成后,您可以在代码中检索该证书。您需要在 Azure 门户中的 "Application Settings" 键下为您的应用服务添加一个新的应用设置,名称为 WEBSITE_LOAD_CERTIFICATES。该值应该是证书的指纹。

要检索证书,您应该这样做:

public async Task<X509Certificate2> GetCertificate(string certificateThumbprint)
{
    var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
    store.Open(OpenFlags.ReadOnly);
    var cert = store.Certificates.OfType<X509Certificate2>()
        .FirstOrDefault(x => x.Thumbprint == certificateThumbprint);
    store.Close();
    return cert;
}

您可以通过使用 azure 资源浏览器浏览您的订阅来获取证书的指纹 https://resources.azure.com/

正如 Fredrik 提到的,问题是由于代码

X509Certificate2 x509 = new X509Certificate2(Convert.FromBase64String(cerStr), string.Empty, X509KeyStorageFlags.MachineKeySet)

在Azure WebApp中,如果我们尝试使用证书,我们需要从Azure门户上传证书。在 Azure WebApp 应用程序中添加带有指纹值的 WEBSITE_LOAD_CERTIFICATES。更多详细信息请参考blog.

用于访问证书的 Web 应用程序,来自博客的代码片段

    static void Main(string[] args)
    {
      X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
      certStore.Open(OpenFlags.ReadOnly);
      X509Certificate2Collection certCollection = certStore.Certificates.Find(
                                 X509FindType.FindByThumbprint,
                                 // Replace below with your cert's thumbprint
                                 “E661583E8FABEF4C0BEF694CBC41C28FB81CD870”,
                                 false);
      // Get the first cert with the thumbprint
      if (certCollection.Count > 0)
      {
        X509Certificate2 cert = certCollection[0];
        // Use certificate
        Console.WriteLine(cert.FriendlyName);
      }
      certStore.Close();
    }