问题描述
在App Service中调用外部服务API时需要携带客户端证书,而多次调用的情况下会出现WindowsCryptographicException Keyset does not exist异常。
错误Tarce:
Exception: Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Keyset does not exist at Internal.NativeCrypto.CapiHelper.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer) at System.Security.Cryptography.RSACryptoServiceProvider.get_SafeProvHandle() at System.Security.Cryptography.RSACryptoServiceProvider.get_SafeKeyHandle() at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 keySize, CspParameters parameters, Boolean useDefaultKeySize) at System.Security.Cryptography.RSACryptoServiceProvider..ctor(CspParameters parameters) at Internal.Cryptography.Pal.CertificatePal.<>c.<GetRSAPrivateKey>b__66_0(CspParameters csp) at Internal.Cryptography.Pal.CertificatePal.GetPrivateKey[T](Func`2 createCsp, Func`2 createCng) at Internal.Cryptography.Pal.CertificatePal.GetRSAPrivateKey() at Internal.Cryptography.Pal.CertificateExtensionsCommon.GetPrivateKey[T](X509Certificate2 certificate, Predicate`1 matchesConstraints) at xxxxxxxx.Paylink.WeChatPay.WeChatPayOptions.GetCertificateInfo()
问题分析
当在App Service中上传证书后,可以通过Kudu站点来查看证书是否存在。在Currentuser\My目录下则使用以下PowerShell指令:
Get-ChildItem Cert:\currentuser\My\
通过PowerShell命令查看证书是否存在,并没有能解决App Service中的 “WindowsCryptographicException Keyset does not exist” 问题,只是说从侧面证明当前实例中是否有证书。如果没有,那么错误非常明显,就需要在实例中安装证书。
但是如果证书还是存在,而错误情况依旧,通过多次验证发现于启用了App Service多实例有关。 虽然没有证明为什么在多实例的情况下出现证书获取不到的情况,但是当使用App Service单实例后,问题不在发生。
个人猜想:是否时在代码中加载证书时候的代码在多实例的情况下,某一个实例出现没有加载到证书的情况而导致。
PS: 记录App Service上出现的证书问题,以待未来再次遇见而参考。有新的发现在更新博文。
For more details, you could refer to the links below.