c# - 使用服务器和客户端证书的 WCF 加密/解密
问题描述
我创建了一个服务,在我托管服务的服务器上会有一个私有证书,并且客户端将拥有它的公钥。并且客户端将有一个不同的私钥,他们将在其中加密他们发送到我创建的端点的消息,并且我有它的公钥,我将使用它来解密消息。到目前为止我在服务器配置文件中的内容。
所以这个负责处理将托管服务的主要私有证书。我不确定在哪里/如何将证书的公钥放在客户端拥有/使用私钥加密消息的位置。
任何帮助将非常感激。
<?xml version="1.0"?>
<configuration>
<appSettings>
</appSettings>
<system.web>
<httpRuntime maxRequestLength="2147483647"/>
<compilation debug="false" strict="false" explicit="true" targetFramework="4.5.2"/>
<pages controlRenderingCompatibilityVersion="4.0"/>
<customErrors mode="Off"/>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="basicHttpEndPointBinding">
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="wcfJNet.ServiceBehavior" name="wcfJNetService">
<endpoint address="" binding="basicHttpBinding"
bindingConfiguration="basicHttpEndPointBinding"
contract="IJNetService">
<identity>
<dns value="xxxxxx" />
</identity>
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="wcfJNet.ServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceCredentials>
<serviceCertificate findValue="0000xx000" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySerialNumber"/>
<clientCertificate>
<authentication certificateValidationMode="PeerOrChainTrust"/>
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
解决方案
很好,你对SSL证书的工作机制有了深入的了解。请参考以下链接。
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/message-security-with-a-certificate-client
客户端和服务器端自动协商公钥通信期间的证书,以使用对方的公钥加密消息并使用私钥解密肥皂消息。因此,我们不需要手动编程此过程。在本地证书存储中安装彼此的证书就足够了。
如果我们使用消息安全模式对客户端进行身份验证,我们需要使用该service credential
部分来配置服务证书。就像你所做的一样。
<serviceCredentials>
<serviceCertificate findValue="0000xx000" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySerialNumber"/>
<clientCertificate>
<authentication certificateValidationMode="PeerOrChainTrust"/>
</clientCertificate>
</serviceCredentials>
在客户端,一般我们需要指定两个证书,一个是服务证书,另一个是客户端证书。
//message security, we need to specify both the default certificate and the client certificate.
ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient(); client.ClientCredentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.LocalMachine, StoreName.Root, X509FindType.FindByThumbprint, "cbc81f77ed01a9784a12483030ccd497f01be71c");
client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, "9b8db0dfe615458ace0ae9e89fcb983c5d16f633");
try
{
var result = client.SayHello();
Console.WriteLine(result);
}
catch (Exception)
{
throw;
}
至于证书之间的信任关系,在客户端,我们需要将服务器证书安装在 中LocalCA
,而在服务器端,我们需要根据认证方式在特定位置安装客户端证书。默认情况下安装在LocalCA
.
//this is default authentication mode.
sh.Credentials.ClientCertificate.Authentication.CertificateValidationMode= System.ServiceModel.Security.X509CertificateValidationMode.ChainTrust;
如果有什么我可以帮忙的,请随时告诉我。
推荐阅读
- c# - HTTPClient Post 返回错误请求 400
- python - Python-can - can.Logger 监听器问题
- android - Android Studio 谷歌地图无法加载
- html - 如何从我的主域的任何子域提供相同的静态内容?
- c++ - 类内的模板方法返回一个未定义的引用
- node.js - 有没有办法在node.js中使用带有读取流的ffprobe(fluent-ffmpeg)输入?
- firebase - 通过 #onNewToken 和 #getToken 检索的令牌之间的区别
- amazon-web-services - Amazon SageMaker:客户错误:二进制文本分类的训练未成功完成
- javascript - 由 js 发出的 php 文件上传信号
- mysql - 如何在 python 3 中将类对象列表“保存”到我的程序中?