C# 服务帐户无法从windows证书存储加载X509证书

C# 服务帐户无法从windows证书存储加载X509证书,c#,asp.net,ssl,x509certificate2,C#,Asp.net,Ssl,X509certificate2,总之,我遇到了一个问题,即运行ASP.NET web表单应用程序(.NET Framework 4.6.1)的服务帐户无法从windows 2012 R2服务器上的个人存储加载X509Certificate(.pfx)。下面是我如何将证书导入证书存储的 我使用服务帐户(域\用户名)登录到服务器,使用mmc管理单元将证书导入当前用户个人证书存储(请参见最后的屏幕截图) 这是我用来在C#中加载证书的代码。但是证书 是空的 public X509Certificate2 Load()

总之,我遇到了一个问题,即运行ASP.NET web表单应用程序(.NET Framework 4.6.1)的服务帐户无法从windows 2012 R2服务器上的个人存储加载X509Certificate(.pfx)。下面是我如何将证书导入证书存储的 我使用服务帐户(域\用户名)登录到服务器,使用mmc管理单元将证书导入当前用户个人证书存储(请参见最后的屏幕截图)

这是我用来在C#中加载证书的代码。但是证书 是空的

    public X509Certificate2 Load()
    {
        X509Certificate2 x509Certificate = null;
        var store = new X509Store(StoreName.My,StoreLocation.CurrentUser);
        string thumbPrint = StripTheSpacesAndMakeItUpper(ConfigurationManager.AppSettings["pfxthumbPrint"]);
        store.Open(OpenFlags.ReadOnly);
        var certCollection = store.Certificates;
        foreach (var x509 in certCollection)
        {
            if (x509.Thumbprint.Equals(thumbPrint))
            {
                x509Certificate = x509;
                break;
            }
        }
        store.Close();
        return x509Certificate; 
    } 

    private string StripTheSpacesAndMakeItUpper(string thumbPrint)
    {
        if(!string.IsNullOrWhiteSpace(thumbPrint))
        {
            return Regex.Replace(thumbPrint, @"\s|\W", "").ToUpper();
        }
        return thumbPrint;
    } 
关于方法加载返回null的原因有什么建议吗?

]


我不知道您如何设置
ConfigurationManager.AppSettings[“pfxthumbPrint”]
的值。我猜您双击了CurrentUser存储中的证书,并从“详细信息”选项卡复制了指纹,对吗?如果是这种情况,您还从指纹的开头复制了一个不可见字符


最悲哀的是,这个角色(我不知道它是什么)在app.config/web.config中不可见。摆脱if的唯一方法是
删除带有指纹第一个字符的第一个引号字符,然后再次手动键入它们。或者删除整个指纹和引号,如果愿意,再键入一次。

我不知道如何设置
ConfigurationManager.AppSettings[“pfxthumbPrint”]
的值。我猜您双击了CurrentUser存储中的证书,并从“详细信息”选项卡复制了指纹,对吗?如果是这种情况,您还从指纹的开头复制了一个不可见字符

最悲哀的是,这个角色(我不知道它是什么)在app.config/web.config中不可见。摆脱if的唯一方法是
删除带有指纹第一个字符的第一个引号字符,然后再次手动键入它们。或者删除整个指纹和引号,并根据需要再次键入它们。

而不是

if (x509.Thumbprint.Equals(x509CertificateFriendlyName))
难道不是吗

 if (x509.Thumbprint.Equals(thumbPrint))

另外,您似乎将
x509Certificate
声明为局部变量,然后放弃它。您是否打算将该值指定给实例变量?我甚至没有看到
return
语句

此外,您没有处理您的店铺,尽管这可能不是问题的原因

这里有一个解决这些问题的不同版本,它还将消除配置条目中的任何不可见字符(请参阅pepo的答案了解原因)

公共X509Certificate2加载()
{
var thumbPrintFromConfig=ConfigurationManager.AppSettings[“pfxthumbPrint”]
var thumbPrint=Regex.Replace(thumbPrintFromConfig.ToUpper(),“[^A-F0-9],”);//仅保留十六进制数字
返回负载(指纹);
}
私有X509Certificate2加载(字符串指纹)
{
使用(var store=new X509Store(StoreName.My,StoreLocation.CurrentUser))
{
打开(OpenFlags.ReadOnly);
var cert=存储
.证书
第()类
.其中(x=>x.指纹==指纹)
.Single();
store.Close();
返回证书;
} 
}
而不是

if (x509.Thumbprint.Equals(x509CertificateFriendlyName))
难道不是吗

 if (x509.Thumbprint.Equals(thumbPrint))

另外,您似乎将
x509Certificate
声明为局部变量,然后放弃它。您是否打算将该值指定给实例变量?我甚至没有看到
return
语句

此外,您没有处理您的店铺,尽管这可能不是问题的原因

这里有一个解决这些问题的不同版本,它还将消除配置条目中的任何不可见字符(请参阅pepo的答案了解原因)

公共X509Certificate2加载()
{
var thumbPrintFromConfig=ConfigurationManager.AppSettings[“pfxthumbPrint”]
var thumbPrint=Regex.Replace(thumbPrintFromConfig.ToUpper(),“[^A-F0-9],”);//仅保留十六进制数字
返回负载(指纹);
}
私有X509Certificate2加载(字符串指纹)
{
使用(var store=new X509Store(StoreName.My,StoreLocation.CurrentUser))
{
打开(OpenFlags.ReadOnly);
var cert=存储
.证书
第()类
.其中(x=>x.指纹==指纹)
.Single();
store.Close();
返回证书;
} 
}

我可以确认这可能就是问题所在。我曾经花了将近5个小时试图弄清楚发生了什么,这就是问题所在。您可以使用十六进制编辑器观察字符。我可以确认这可能是问题所在。我曾经花了将近5个小时试图弄清楚发生了什么,这就是问题所在。您可以使用十六进制编辑器观察字符。John WU,在根据您的输入更改代码后,我必须将IIS上应用程序池设置上的LoadUserProfile设置为True。然后它像charmFYI一样工作,您可以使用
store.Certificates.Find(X509FindType.FindByThumbprint,thumbPrint,True)
而不是手动查找指纹。另外,由于
Dispose
方法调用
close
方法,因此在释放存储之前无需关闭它。John WU,在根据您的输入更改代码后,我必须将IIS上应用程序池设置上的LoadUserProfile设置为True。然后它像charmFYI一样工作,您可以使用
store.Certificates.Find(X509FindType.FindByThumbprint,thumbPrint,true)
而不是手动查找指纹。此外,由于
Dispose
方法调用
close
方法,因此在释放存储之前无需关闭存储。