仅使用公钥使用WCF使用web服务

仅使用公钥使用WCF使用web服务,wcf,x509,Wcf,X509,我正在使用WCF使用第三方的web服务。我有一个通过ClientCredentials.ClientCertificate.SetCertificate方法附加的PFX证书文件。我使用的是“消息安全版本”WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10 一切正常。现在,第三方的证书即将过期,因此他们已颁发了新证书。然而,这次它是一个P7B文

我正在使用WCF使用第三方的web服务。我有一个通过
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]