我正在尝试将现有应用程序迁移到Mono(v2.10.2)。

因此,我创建了一个具有BasicHttpBinding和消息安全性的测试WCF服务。客户端可以与.NET完美配合,但是与Mono一起运行时会失败。

客户端工厂的实例如下:

//var certificate = CertificateUtil.GetCertificate(StoreLocation.LocalMachine,
//    StoreName.My, X509FindType.FindBySubjectDistinguishedName, CertName, true);
var certificate = new X509Certificate2("certificate.pfx", "password");

var binding = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.Message;
binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.Certificate;

var epa = new EndpointAddress(
    new Uri("http://localhost:53076/Service1.svc"),
    new X509CertificateEndpointIdentity(certificate));

var factory = new ChannelFactory<IService1>(binding, epa);
factory.Credentials.ServiceCertificate.DefaultCertificate = certificate;
factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
factory.Credentials.ServiceCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;
factory.Credentials.ClientCertificate.Certificate = certificate;

var client = factory.CreateChannel();

在Mono中,应用程序在CreateChannel中失败并引发异常:

System.InvalidOperationException:绑定(bind)不支持合同'IService1'允许的任何通道类型。

我调试了Mono的源代码,发现问题是AsymmetricSecurityBindingElement.InitiatorTokenParameter == null。

我是Mono的新手,也许您可​​以向我介绍涵盖此主题的文档/教程。

更新:

借助konrad.kruczynski,证书对象现在具有私钥。例外仍然是相同的。因此,这不是证书存储问题。

最佳答案

是的,在Windows上创建的证书通常不包含私钥。可以在某种缓存中找到它们。您应该能够使用this指令使用私钥创建证书。 X509Certificate2应该可以正常使用该文件。您也可以尝试使用here描述的过程。如有任何问题,只需写。
还值得补充的是,以这种方式在Linux上创建的证书也可以在Windows上完美地工作。
更新:
我不确定我是否正确理解您的评论。您可以使用以下代码加载PFX证书:

var myCert = new X509Certificate2("filename.pfx", "password");
给定证书包含密钥,它对我有用。

09-10 07:29
查看更多