仅使用公钥使用WCF使用web服务
我正在使用WCF使用第三方的web服务。我有一个通过仅使用公钥使用WCF使用web服务,wcf,x509,Wcf,X509,我正在使用WCF使用第三方的web服务。我有一个通过ClientCredentials.ClientCertificate.SetCertificate方法附加的PFX证书文件。我使用的是“消息安全版本”WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10 一切正常。现在,第三方的证书即将过期,因此他们已颁发了新证书。然而,这次它是一个P7B文
ClientCredentials.ClientCertificate.SetCertificate
方法附加的PFX证书文件。我使用的是“消息安全版本”WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10
一切正常。现在,第三方的证书即将过期,因此他们已颁发了新证书。然而,这次它是一个P7B文件,只有公钥
当我尝试使用此证书时,我得到一个NotSupportedException
,并显示消息“X.509证书中不存在私钥。”
我的代码中没有任何部分提供私钥密码,因此我假设这意味着没有使用私钥。如果是这种情况,如何仅使用公钥使用此web服务?还是我误解了什么?(很可能)
编辑好的,这里有一些代码。我使用的服务客户机类是由
svcutil
生成的,并通过一个分部类进行了修改,以实现IDisposable
。以下是相关片段:
private ServiceResponse CallService(ServiceParameters serviceParameters)
{
...
using (var client = new ThirdPartyServiceClient())
{
SetClientCredentials(client);
client.RemoteCall(serviceParameters);
}
...
}
private void SetClientCredentials(ThirdPartyServiceClient client)
{
if (client.ClientCredentials == null)
{
throw new InvalidOperationException("ClientCredentials was null and certificate could not be set");
}
client.ClientCredentials.ClientCertificate.SetCertificate(
StoreLocation.LocalMachine,
StoreName.My,
X509FindType.FindBySubjectName,
_configuration.CertificateSubject);
}
这是我的WCF配置:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="ThirdPartyServiceBinding">
<security includeTimestamp="true" enableUnsecuredResponse="true" authenticationMode="CertificateOverTransport" messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10" />
<textMessageEncoding messageVersion="Soap11WSAddressing10" />
<httpsTransport requireClientCertificate="true" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="https://third-party.com/service" binding="customBinding" bindingConfiguration="ThirdPartyServiceBinding" contract="Namespace.To.ProxyClasses" name="ThirdPartyService" />
</client>
</system.serviceModel>
使用消息安全性,您可以使用私钥对文档进行签名,并使用其他方的公钥对文档进行加密。他们可以用私钥解密,也可以用公钥验证你的签名。听起来好像他们更换了他们的密钥,所以他们向您提供了新的公钥。如果他们的公钥没有可公开验证的信任链,那么您需要将他们的公钥作为受信任密钥安装在本地证书存储中。如果您不这样做,并且它们是不可公开验证的,您将得到一个关于无法验证链信任的异常。如果是您的密钥即将过期,那么他们需要一个公钥来识别您,而您需要他们不应该拥有的私钥。您能否共享设置证书的代码,以及在抛出NotSupportedException时的详细信息-包括堆栈跟踪?@RQDQ ok,开始吧! Server stack trace: at System.IdentityModel.Tokens.X509AsymmetricSecurityKey.GetSignatureFormatter(String algorithm) at System.IdentityModel.SignedXml.ComputeSignature(SecurityKey signingKey) at System.ServiceModel.Security.WSSecurityOneDotZeroSendSecurityHeader.CompletePrimarySignatureCore(SendSecurityHeaderElement[] signatureConfirmations, SecurityToken[] signedEndorsingTokens, SecurityToken[] signedTokens, SendSecurityHeaderElement[] basicTokens, Boolean isPrimarySignature) at System.ServiceModel.Security.WSSecurityOneDotZeroSendSecurityHeader.CreateSupportingSignature(SecurityToken token, SecurityKeyIdentifier identifier) at System.ServiceModel.Security.SendSecurityHeader.SignWithSupportingToken(SecurityToken token, SecurityKeyIdentifierClause identifierClause) at System.ServiceModel.Security.SendSecurityHeader.SignWithSupportingTokens() at System.ServiceModel.Security.SendSecurityHeader.CompleteSecurityApplication() at System.ServiceModel.Security.SecurityAppliedMessage.OnWriteMessage(XmlDictionaryWriter writer) at System.ServiceModel.Channels.BufferedMessageWriter.WriteMessage(Message message, BufferManager bufferManager, Int32 initialOffset, Int32 maxSizeQuota) at System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager, Int32 messageOffset) at System.ServiceModel.Channels.HttpOutput.SerializeBufferedMessage(Message message, Boolean shouldRecycleBuffer) at System.ServiceModel.Channels.HttpOutput.Send(TimeSpan timeout) at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.SendRequest(Message message, TimeSpan timeout) at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout) at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout) at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at Namespace.To.ProxyClasses.ThirdPartyService.RemoteCall(ServiceParameters request) [back up the normal call hierarchy of my code]