使用Mono的WCF证书安全性

使用Mono的WCF证书安全性,wcf,mono,certificate,Wcf,Mono,Certificate,我正在尝试将现有的应用程序迁移到Mono(v2.10.2) 因此,我创建了一个带有BasicHttpBinding和消息安全性的测试WCF服务。客户机与.NET完美配合,但在与Mono一起运行时失败 客户端工厂的实例化如下所示: //var certificate = CertificateUtil.GetCertificate(StoreLocation.LocalMachine, // StoreName.My, X509FindType.FindBySubjectDistingui

我正在尝试将现有的应用程序迁移到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();
//var certificate=CertificateUtil.GetCertificate(StoreLocation.LocalMachine,
//StoreName.My,X509FindType.findbysubjectdistrignifiedname,CertName,true);
var证书=新的X509Certificate2(“certificate.pfx”、“密码”);
var binding=新的BasicHttpBinding();
binding.Security.Mode=BasicHttpSecurityMode.Message;
binding.Security.Message.ClientCredentialType=BasicHttpMessageCredentialType.Certificate;
var epa=新端点地址(
新Uri(“http://localhost:53076/Service1.svc"),
新X509CertificateEndpointIdentity(证书));
var工厂=新渠道工厂(绑定,epa);
factory.Credentials.ServiceCertificate.DefaultCertificate=证书;
factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode=X509CertificateValidationMode.None;
factory.Credentials.ServiceCertificate.Authentication.RevocationMode=X509RevocationMode.NoCheck;
factory.Credentials.ClientCertificate.Certificate=证书;
var client=factory.CreateChannel();
在Mono中,应用程序在CreateChannel内失败,引发异常:

System.InvalidOperationException:绑定不支持契约“IService1”允许的任何通道类型

我在Mono源代码中进行了调试,发现问题在于AsymmetricSecurityBindingElement.InitiatorTokenParameter==null

我是Mono的新手,也许你可以给我指一份涉及这个主题的文档/教程

更新:


在konrad.kruczynski的帮助下,证书对象现在有了私钥。例外情况仍然是一样的。因此这不是证书存储问题。

是的,在Windows上创建的证书通常不包含私钥。它们可以在某种缓存中找到。您应该能够使用指令创建带有私钥的证书
X509Certificate2
应该可以毫无问题地使用该文件。您也可以尝试上述步骤。如果有任何问题,就写下来

另外值得一提的是,在Linux上以这种方式创建的证书在Windows上也能完美运行

更新:

我不确定我是否正确理解了你的评论。您可以使用如下代码加载PFX证书:

var myCert = new X509Certificate2("filename.pfx", "password");

给定包含密钥的证书,它对我有效。

我认为证书是可以的,因为它在运行.NET时工作得非常好。但我不确定Mono证书存储是否与Windows证书存储的行为相同。在第二个链接中,它们使用ssl。但我的问题是消息安全中的客户端证书。是的,当然,读取证书文件很容易!这允许我读取带有私钥的证书,但例外情况仍然相同。也许有人可以告诉我一种比在证书存储中搜索证书更好的读取证书的方法。从PFX文件读取它们将是我的目的,我会认为这是一个错误。值得添加到bugzilla中,它们有时会很快得到修复。我在mono邮件列表中发布了相同的问题。消息安全性不受官方支持。所以我不会从mono邮件列表中得到帮助。我有完全相同的需求,所以我对你在这里的成功很感兴趣。