gpt4 book ai didi

c# - WCF : The EncryptedKey clause was not wrapped with the required encryption token 'System.IdentityModel.Tokens.X509SecurityToken'

转载 作者:太空狗 更新时间:2023-10-29 20:19:25 33 4
gpt4 key购买 nike

我正在尝试使用 WCF 客户端连接到基于 Java 的 Web 服务

我提供的证书(自签名)在 SOAPUI 中完美运行。

这是我的设置:

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

但是,我在使用 WCF 客户端时遇到问题。

我的app.config

    <bindings>
<customBinding>
<binding name="Example_TestBinding">
<security defaultAlgorithmSuite="TripleDesRsa15"
authenticationMode="MutualCertificate"
requireDerivedKeys="false"
includeTimestamp="false"
messageProtectionOrder="SignBeforeEncrypt"
messageSecurityVersion="WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10"
requireSignatureConfirmation="false">
<localClientSettings detectReplays="true"/>
<localServiceSettings detectReplays="true"/>
</security>
<textMessageEncoding messageVersion="Soap11"/>
<httpsTransport authenticationScheme="Basic" manualAddressing="false" maxReceivedMessageSize="524288000" transferMode="Buffered"/>
</binding>
</customBinding>
</bindings>
<client>
<endpoint
address="https://blabla.hana.ondemand.com/Example_Test"
binding="customBinding"
bindingConfiguration="Example_TestBinding"
contract="WebServiceTest.Example_Test"
name="Example_Test"
/>
</client>

我使用 Keystore Explorer 从 JKS 导出两个证书:

  • public_test_hci_cert.cer
  • test_soap_ui.p12

网络服务调用:

            var client = new Example_TestClient();
client.ClientCredentials.UserName.UserName = "user";
client.ClientCredentials.UserName.Password = "pass";

X509Certificate2 certClient = new X509Certificate2(certClientPath, certClientPassword);
client.ClientCredentials.ClientCertificate.Certificate = certClient;

X509Certificate2 certService= new X509Certificate2(certServicePath);
client.ClientCredentials.ServiceCertificate.DefaultCertificate = certService;

var response = client.Example_Test(requestObj);

请求完美地到达服务器,但似乎 WCF 不理解响应,因为我收到此异常:

"The EncryptedKey clause was not wrapped with the required 
encryption token 'System.IdentityModel.Tokens.X509SecurityToken'."
at System.ServiceModel.Security.WSSecurityJan2004.WrappedKeyTokenEntry.CreateWrappedKeyToken(String id, String encryptionMethod, String carriedKeyName, SecurityKeyIdentifier unwrappingTokenIdentifier, Byte[] wrappedKey, SecurityTokenResolver tokenResolver)\r\n ...

服务跟踪提供:

The security protocol cannot verify the incoming message

UPDATE1:通过使用相同的证书进行签名和加密来简化任务。同样的信息。

UPDATE2:我编写了 CustomTextMessageEncoder,我在其中手动解密消息正文并且它有效。但是在 ReadMessage 中返回它仍然会引发错误。

    public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)
{
var msgContents = new byte[buffer.Count];
Array.Copy(buffer.Array, buffer.Offset, msgContents, 0, msgContents.Length);
bufferManager.ReturnBuffer(buffer.Array);
var message = Encoding.UTF8.GetString(msgContents);

//return ReadMessage(Decryptor.DecryptBody(message), int.MaxValue);
var stream = new MemoryStream(Encoding.UTF8.GetBytes(message));
return ReadMessage(stream, int.MaxValue);
}

public static MemoryStream DecryptBody(string xmlResponse)
{
X509Certificate2 cert = new X509Certificate2(clientCertPath, certPass);
SymmetricAlgorithm algorithm = new TripleDESCryptoServiceProvider();

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = true;
xmlDoc.LoadXml(xmlResponse);

XmlElement encryptedKeyElement = xmlDoc.GetElementsByTagName("EncryptedKey", XmlEncryptionStrings.Namespace)[0] as XmlElement;
XmlElement keyCipherValueElement = encryptedKeyElement.GetElementsByTagName("CipherValue", XmlEncryptionStrings.Namespace)[0] as XmlElement;
XmlElement encryptedElement = xmlDoc.GetElementsByTagName("EncryptedData", XmlEncryptionStrings.Namespace)[0] as XmlElement;

var key = Convert.FromBase64String(keyCipherValueElement.InnerText);

EncryptedData edElement = new EncryptedData();
edElement.LoadXml(encryptedElement);
EncryptedXml exml = new EncryptedXml();

algorithm.Key = (cert.PrivateKey as RSACryptoServiceProvider).Decrypt(key, false);

byte[] rgbOutput = exml.DecryptData(edElement, algorithm);
exml.ReplaceData(encryptedElement, rgbOutput);

//var body = Encoding.UTF8.GetString(rgbOutput);

MemoryStream ms = new MemoryStream();
xmlDoc.Save(ms);
return ms;
}

最佳答案

我把这个问题留在了项目的最后冲刺中,最后又回到了它。
这是证书问题。我由基于 Java 的 Web 服务提供的自签名证书是使用 KeyStore Explorer 生成的。两个证书都缺少一个重要部分:

Subject Key Identifier

enter image description here

一旦重新生成 WCF 就能够在不使用编码器的情况下对其进行解密。

我还必须:

  1. 在受信任的根 CA(用户)中安装服务证书
  2. 将 Web 服务设置为使用时间戳回复

我从代码中删除了所有配置(客户端用户名和密码除外)并放置在 app.config 中。这是完整的配置:

  <system.serviceModel>
<bindings>
<customBinding>
<binding name="Example_TestBinding">
<security
defaultAlgorithmSuite="TripleDesRsa15"
authenticationMode="MutualCertificate"
requireDerivedKeys="false"
includeTimestamp="true"
messageProtectionOrder="SignBeforeEncrypt"
messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
requireSignatureConfirmation="false"
allowSerializedSigningTokenOnReply="true"
>
</security>
<textMessageEncoding messageVersion="Soap11"/>
<httpsTransport authenticationScheme="Basic"
manualAddressing="false"
maxReceivedMessageSize="524288000"
transferMode="Buffered"/>
</binding>
</customBinding>

</bindings>
<client>
<endpoint address="https://klaatuveratanecto.com/cxf/Example_TestBinding"
behaviorConfiguration="endpointCredentialBehavior"
binding="customBinding"
bindingConfiguration="Example_TestBinding"
contract="WebServiceTest.Example_Test"
name="Example_Test">
<identity>
<dns value="test.service.klaatuveratanecto.com"/>
</identity>
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="endpointCredentialBehavior">
<clientCredentials>
<serviceCertificate>
<defaultCertificate findValue="test.service.klaatuveratanecto.com"
storeLocation="CurrentUser"
storeName="Root"
x509FindType="FindBySubjectName" />
</serviceCertificate>
<clientCertificate findValue="test.client.klaatuveratanecto.com"
storeLocation="CurrentUser"
storeName="My"
x509FindType="FindBySubjectName" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>

我是怎么到那里的。看看堆栈跟踪:

Server stack trace: 
at System.ServiceModel.Security.WSSecurityJan2004.WrappedKeyTokenEntry.CreateWrappedKeyToken(String id, String encryptionMethod, String carriedKeyName, SecurityKeyIdentifier unwrappingTokenIdentifier, Byte[] wrappedKey, SecurityTokenResolver tokenResolver)
at System.ServiceModel.Security.WSSecurityJan2004.WrappedKeyTokenEntry.ReadTokenCore(XmlDictionaryReader reader, SecurityTokenResolver tokenResolver)
at System.ServiceModel.Security.WSSecurityTokenSerializer.ReadTokenCore(XmlReader reader, SecurityTokenResolver tokenResolver)
at System.IdentityModel.Selectors.SecurityTokenSerializer.ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver)
at System.ServiceModel.Security.WSSecurityOneDotZeroReceiveSecurityHeader.DecryptWrappedKey(XmlDictionaryReader reader)
at System.ServiceModel.Security.ReceiveSecurityHeader.ReadEncryptedKey(XmlDictionaryReader reader, Boolean processReferenceListIfPresent)
at System.ServiceModel.Security.ReceiveSecurityHeader.ExecuteFullPass(XmlDictionaryReader reader)
at System.ServiceModel.Security.StrictModeSecurityHeaderElementInferenceEngine.ExecuteProcessingPasses(ReceiveSecurityHeader securityHeader, XmlDictionaryReader reader)
at System.ServiceModel.Security.ReceiveSecurityHeader.Process(TimeSpan timeout, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy)
at System.ServiceModel.Security.MessageSecurityProtocol.ProcessSecurityHeader(ReceiveSecurityHeader securityHeader, Message& message, SecurityToken requiredSigningToken, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
at System.ServiceModel.Security.AsymmetricSecurityProtocol.VerifyIncomingMessageCore(Message& message, String actor, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
at System.ServiceModel.Security.MessageSecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, 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)

我在 JetBrains dotPeek 的帮助下调试了 CreateWrappedKeyToken 方法,发现它试图从证书中读取原始 SKI,但没有找到。

关于c# - WCF : The EncryptedKey clause was not wrapped with the required encryption token 'System.IdentityModel.Tokens.X509SecurityToken' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46686785/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com