C#WCF与客户端证书通信

时间:2014-09-25 12:29:01

标签: c# .net wcf security ssl

我正在开发非常简单的桌面(win窗体)应用程序,它通过HTTPS协议上的WCF服务与服务器通信。 每个使用此应用程序的客户端都可以上传客户端证书(每个客户端都是唯一的),用于通信。

我想要实现的目标是什么: 1.用户将“上传”证书到我的桌面应用程序,应用程序获取证书并以编程方式将证书保存到Windows证书库,这是我的代码:

[SecurityCritical]
public CertificateInfoDto GetCertificateInfoAndImportToStore(string fullPath, SecureString password)
    {
        if (string.IsNullOrEmpty(fullPath))
        {
            throw new ArgumentNullException("fullPath");
        }

        if (!File.Exists(fullPath))
        {
            throw new ArgumentException(string.Concat("No file present on ", fullPath));
        }

        try
        {
            byte[] rawBytes = this.GetCertificateContent(fullPath);
            var certificate = new X509Certificate2(rawBytes, password, X509KeyStorageFlags.Exportable);
            this.EnsureImport(certificate);
         }
   // some error handling etc, and end of method.


[SecurityCritical]
private void EnsureImport(X509Certificate2 certificate)
{
   X509Store store = null;
   try
   {
      store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
      store.Open(OpenFlags.ReadWrite);
      store.Add(certificate);
   }

在我的应用程序设置文件中,我只存储证书序列号。 2.现在,当我将证书上传到Windows商店时,我想将它用于wcf通信,所以我的代码如下:

var client = new SomeWcfServiceProxy();
client.ClientCredentials.ClientCertificate.SetCertificate(
            StoreLocation.CurrentUser,
            StoreName.My,
            X509FindType.FindBySerialNumber,
            certificateSerialNumber);

最后,这是我的问题,当我尝试在代理上调用某个方法时,生病得到一个异常: System.ServiceModel.Security.SecurityNegotiationException:无法为具有权限'url(我更改此项)'的SSL / TLS建立安全通道。 ---> System.Net.WebException:请求已中止:无法创建SSL / TLS安全通道。

但令我困惑的是,当我创建这样的代理客户端时:

var client = new SomeWcfServiceProxy();
var clientCertificate = new X509Certificate2(@"C:\U\BB\certificate.pfx", "password");
client.ClientCredentials.ClientCertificate.Certificate = clientCertificate;

一切都像魅力一样! 所以有我的问题:我不希望在任何地方存储客户端证书密码,我想通过Windows证书存储区上传它,然后只从Windows证书存储区使用它。这可能吗?或者我必须在某处存储证书密码(我不知道在哪里,因为我认为它不是很安全,而且这个证书非常非常机密)。 感谢您的帮助:))

1 个答案:

答案 0 :(得分:1)

毕竟,我需要这个:

var certificate = new X509Certificate2(rawBytes, password, X509KeyStorageFlags.UserKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);

现在证书导入恰到好处,可以毫无问题地用于通信