"CryptographicException:指定了无效的提供者类型"仅在WebAPI项目中 [英] "CryptographicException: Invalid provider type specified" only in WebAPI project

查看:45
本文介绍了"CryptographicException:指定了无效的提供者类型"仅在WebAPI项目中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有以下代码,可使用本地计算机上安装的证书访问KeyVault中的机密:

I have the following code for accessing a secret in KeyVault using a certificate installed on the local machine:

static readonly string certThumbprint = "1234...";
static readonly string clientId = "1234...";

static void Main(string[] args)
{
    X509Certificate2 certificate = FindCertificateByThumbprint(certThumbprint);
    ClientAssertionCertificate assertionCert = new ClientAssertionCertificate(clientId, certificate);

    var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(
            (authority, resource, scope) => GetAccessToken(authority, resource, scope, assertionCert)));


    string url = "https://myvault.vault.azure.net/";
    var result = keyVaultClient.GetSecretAsync(url, "mySecret").Result;
}

private static X509Certificate2 FindCertificateByThumbprint(string certificateThumbprint)
{
    if (certificateThumbprint == null)
    {
        throw new System.ArgumentNullException("CertificateThumbprint");
    }

    StoreLocation[] storeLocations = (StoreLocation[])Enum.GetValues(typeof(StoreLocation));

    foreach (StoreLocation location in storeLocations)
    {
        foreach (StoreName storeName in (StoreName[])
            Enum.GetValues(typeof(StoreName)))
        {
            X509Store store = new X509Store(storeName, location);

            store.Open(OpenFlags.ReadOnly);

            X509Certificate2Collection certCollection = store.Certificates.Find(X509FindType.FindByThumbprint, certificateThumbprint, false);

            if (certCollection != null && certCollection.Count != 0)
            {
                foreach (X509Certificate2 cert in certCollection)
                {
                    if (cert.HasPrivateKey)
                    {
                        store.Close();
                        return cert;
                    }
                }
            }
        }
    }
    throw new Exception($"Could not find the certificate with thumbprint {certificateThumbprint} in any certificate store.");
}

private static async Task<string> GetAccessToken(string authority, string resource, string scope, ClientAssertionCertificate assertionCert)
{
    Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext context = new Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext(authority, TokenCache.DefaultShared);
    AuthenticationResult result = await context.AcquireTokenAsync(resource, assertionCert).ConfigureAwait(false);

    return result.AccessToken;
}

在安装了以下软件包的.Net Framework 4.7.2控制台应用程序中,此方法可以正常工作:

This works fine in my .Net Framework 4.7.2 console app with the following packages installed:

  <ItemGroup>
    <PackageReference Include="Microsoft.Azure.KeyVault">
      <Version>3.0.5</Version>
    </PackageReference>
    <PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory">
      <Version>5.2.8</Version>
    </PackageReference>
    <PackageReference Include="System.Security.Cryptography.X509Certificates">
      <Version>4.3.2</Version>
    </PackageReference>
  </ItemGroup>

但是,当我在WebAPI项目(.Net Framework 4.7.2)上运行完全相同的代码时,出现以下错误:

However, when I run the exact same code on my WebAPI project (.Net Framework 4.7.2), I get the following error:

"ClassName": "System.Security.Cryptography.CryptographicException",
"Message": "Invalid provider type specified.\r\n"

根据Nuget的说明,我安装的软件包是相同版本:

The packages I've installed are the same version according to Nuget:

<Reference Include="Microsoft.Azure.KeyVault, Version=3.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
  <HintPath>..\packages\Microsoft.Azure.KeyVault.3.0.5\lib\net461\Microsoft.Azure.KeyVault.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory, Version=5.2.8.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
  <HintPath>..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.5.2.8\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.1.2, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
  <HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
  <Private>True</Private>
  <Private>True</Private>
</Reference>
  

我猜想其他软件包正在引起冲突,并解决了所需库之一的某些错误版本,但是我不确定如何诊断和解决问题.解决.

I guess that some other package is causing a conflict and resolving some incorrect version of one of the needed libraries but I'm unsure how to diagnose & resolve.

推荐答案

此异常的最可能原因是证书的私钥存储在现代的CNG密钥存储提供程序中,而不是传统的CAPI加密服务提供程序中.在做出此响应时,Azure Key Vault已与CNG发生兼容性问题,因此,您应尝试生成新证书并选择旧版CAPI CSP来存储密钥材料.

The most likely reason for this exception is that certificate's private key is stored in modern CNG Key Storage Provider rather than legacy CAPI Cryptographic Service Provider. At the moment of this response Azure Key Vault has known compatibility issues with CNG, so you should try to generate a new certificate and select legacy CAPI CSP to store key material.

这篇关于"CryptographicException:指定了无效的提供者类型"仅在WebAPI项目中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆