【发布时间】:2014-09-25 12:29:01
【问题描述】:
我正在开发非常简单的桌面(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:无法为 SSL/TLS 建立安全通道,权限为“url(我更改了这个)”。 ---> 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 证书存储区使用它。这可能吗?或者我必须将证书密码存储在某个地方(我不知道在哪里,因为我认为它不是很安全,而且这个证书非常机密)。 感谢您的帮助:)
【问题讨论】:
-
可能您的用户没有证书私钥的权限。如果运行该进程的用户具有对私钥的读取权限,请检查 mmc 控制台。
-
Grzegorz 看起来你救了我的命。看起来这正是我的问题! :) 我会测试它并写下它是否可以工作! :)