C# WCF客户端到java服务,使用相互证书实现传输和消息安全
我正在尝试创建一个WCF客户端应用程序,它使用一个JAVA WS,它使用三个证书,其中两个用于签名和加密,一个用于传输。服务器上安装了一个私钥,并从JKS密钥库文件导出了一个公共证书文件。我已通过MMC在个人证书下将公钥和用于签名和加密的密钥安装到证书存储中 以下是我的表单代码:C# WCF客户端到java服务,使用相互证书实现传输和消息安全,c#,.net,wcf,soap,service,C#,.net,Wcf,Soap,Service,我正在尝试创建一个WCF客户端应用程序,它使用一个JAVA WS,它使用三个证书,其中两个用于签名和加密,一个用于传输。服务器上安装了一个私钥,并从JKS密钥库文件导出了一个公共证书文件。我已通过MMC在个人证书下将公钥和用于签名和加密的密钥安装到证书存储中 以下是我的表单代码: public Form1() { InitializeComponent(); ServicePoin
public Form1()
{
InitializeComponent();
ServicePointManager.SecurityProtocol=SecurityProtocolType.Tls;
referencaServisa.obrtniWsServiceClient klijent = new referencaServisa.SomeServiceClient();
var vs = klijent.Endpoint.Behaviors.Where((i) => i.GetType().Namespace.Contains("VisualStudio"));
klijent.Endpoint.Behaviors.Remove((System.ServiceModel.Description.IEndpointBehavior)vs.Single());
klijent.Endpoint.Address = new System.ServiceModel.EndpointAddress(@"https://213.147.119.174:4444/some-registar-ws/someWsService");
CustomBinding binding = new CustomBinding();
SecurityBindingElement sbe = SecurityBindingElement.CreateMutualCertificateDuplexBindingElement(MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);
AsymmetricSecurityBindingElement asymetricElement=(AsymmetricSecurityBindingElement)sbe;
asymetricElement.DefaultAlgorithmSuite = System.ServiceModel.Security.SecurityAlgorithmSuite.Basic128Rsa15;
asymetricElement.ProtectTokens = true;
asymetricElement.IncludeTimestamp = false;
asymetricElement.SetKeyDerivation(false);
asymetricElement.EnableUnsecuredResponse = true;
asymetricElement.SecurityHeaderLayout = SecurityHeaderLayout.Lax;
asymetricElement.KeyEntropyMode = SecurityKeyEntropyMode.ClientEntropy;
asymetricElement.AllowSerializedSigningTokenOnReply=true;
X509SecurityTokenParameters initiator = new X509SecurityTokenParameters(X509KeyIdentifierClauseType.SubjectKeyIdentifier, SecurityTokenInclusionMode.AlwaysToInitiator);
/*X509SecurityTokenParameters recipient = new X509SecurityTokenParameters(X509KeyIdentifierClauseType.RawDataKeyIdentifier, SecurityTokenInclusionMode.AlwaysToInitiator);
asymetricElement.RecipientTokenParameters = recipient;
asymetricElement.InitiatorTokenParameters = initiator;
asymetricElement.InitiatorTokenParameters.RequireDerivedKeys = false;*/
asymetricElement.MessageProtectionOrder = System.ServiceModel.Security.MessageProtectionOrder.SignBeforeEncrypt;
asymetricElement.LocalClientSettings.IdentityVerifier = new MyIdentityVerifier();
asymetricElement.EndpointSupportingTokenParameters.Signed.Add(
new X509SecurityTokenParameters());
binding.Elements.Clear();
binding.Elements.Add(asymetricElement);
CustomTextMessageBindingElement customTextMessageBindingElement = new CustomTextMessageBindingElement("UTF-8", "text/xml", MessageVersion.Soap11);
binding.Elements.Add(customTextMessageBindingElement);
HttpsTransportBindingElement httpsTransportBindingElement = new HttpsTransportBindingElement
{
RequireClientCertificate=true
};
httpsTransportBindingElement.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
httpsTransportBindingElement.TransferMode = TransferMode.Buffered;
httpsTransportBindingElement.UseDefaultWebProxy = true;
httpsTransportBindingElement.KeepAliveEnabled=true;
httpsTransportBindingElement.AuthenticationScheme = AuthenticationSchemes.Digest;
httpsTransportBindingElement.RequireClientCertificate = true;
binding.Elements.Add(httpsTransportBindingElement);
klijent.Endpoint.Binding = binding;
referencaServisa.statusType status;
string poruka;
referencaServisa.registarskiUlozak[] registarskiUlosci;
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
// Begin using the client.
try
{
klijent.Open();
status = klijent.getUlosciByMbo("90445066",false, out poruka, out registarskiUlosci);
referencaServisa.ulozak receivedUlozak = null;
if (status.ToString() == "OK")
{
receivedUlozak = registarskiUlosci[0].aktivnoStanjeUloska.ulozak;
MessageBox.Show(receivedUlozak.vlasnici[0].redniBroj.ToString());
}
MessageBox.Show(status.ToString());
// Close the client.
klijent.Close();
}
catch (ProtocolException ex) { MessageBox.Show(ex.Message); }
}
So I use three certificates one for signing one for encryption and one for SSL transport. I use custom binding for separation of certificates. When I start my app I get an error General security error:
The content type text/xml;charset=UTF-8 of the response message does not match the content type of the binding (text/xml; charset=UTF-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 394 bytes of the response were: '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><soap:Fault><faultcode xmlns:ns1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">ns1:InvalidSecurity</faultcode><faultstring>An error was discovered processing the <wsse:Security> header (Unsupported key identification)</faultstring></soap:Fault></soap:Body></soap:Envelope>'.
Here is my app.config :
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="dasda12312.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
</startup>
<system.net>
<settings>
<httpWebRequest useUnsafeHeaderParsing="false"/>
</settings>
</system.net>
<system.diagnostics>
<switches>
<add name="Remote.Disable" value="1"/>
</switches>
</system.diagnostics>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="MyClientCredentialsExtension">
<MyClientCredentialsExtension>
<clientCertificate findValue="removed" storeLocation="LocalMachine" x509FindType="FindBySerialNumber" storeName="My" />
<serviceCertificate>
<defaultCertificate findValue="removed" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
</serviceCertificate>
<transportCertificate findValue="removed" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySerialNumber"/>
</MyClientCredentialsExtension>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="cb">
<security authenticationMode="MutualCertificate" requireDerivedKeys="true" includeTimestamp="true"
allowSerializedSigningTokenOnReply="true" securityHeaderLayout="Lax"
defaultAlgorithmSuite="Basic256"
keyEntropyMode="ClientEntropy" requireSecurityContextCancellation="false"
messageProtectionOrder="SignBeforeEncrypt" messageSecurityVersion="WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10" />
<textMessageEncoding messageVersion="Soap11" />
<httpsTransport />
</binding>
</customBinding>
<client>
<!---->
<endpoint address=""
behaviorConfiguration="MyClientCredentialsExtension" binding="customBinding" bindingConfiguration="cb"
contract="referencaServisa.someWsService"
name="SomeWsServiceImplPort">
</endpoint>
</client>
<extensions>
<behaviorExtensions>
<add name="MyClientCredentialsExtension" type="SEOP.MyClientCredentialsExtensionElement,dasda12312"/>
</behaviorExtensions>
</extensions>
</system.serviceModel>
<applicationSettings>
<dasda12312.Properties.Settings>
<setting name="dasda12312_someReferenca2_someWsService" serializeAs="string">
<value>https://213.147.119.174:4444/some-registar-ws/someWsService</value>
</setting>
</dasda12312.Properties.Settings>
</applicationSettings>
</configuration>
Anyone had similar problem please help me and tell me how to fix this.
Thank you.
public Form1()
{
初始化组件();
ServicePointManager.SecurityProtocol=SecurityProtocolType.Tls;
referenceCaservisa.obrtniWsServiceClient klijent=新referenceCaservisa.SomeServiceClient();
var vs=klijent.Endpoint.Behaviors.Where((i)=>i.GetType().Namespace.Contains(“VisualStudio”);
Remove((System.ServiceModel.Description.IEndpointBehavior)vs.Single());
klijent.Endpoint.Address=新系统.ServiceModel.EndpointAddress(@“https://213.147.119.174:4444/some-注册ws/someWsService”);
CustomBinding=新的CustomBinding();
SecurityBindingElement sbe=SecurityBindingElement.CreateMutualCertificatedPlexBindingElement(MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);
AsymmetricSecurityBindingElement AsymmetricElement=(AsymmetricSecurityBindingElement)sbe;
asymetricElement.DefaultAlgorithmSuite=System.ServiceModel.Security.SecurityAlgorithmSuite.Basic128Rsa15;
asymetricElement.ProtectTokens=true;
asymetricElement.IncludeTimestamp=false;
asymetricElement.SetKeyDerivation(false);
asymetricElement.EnableUnsecuredResponse=true;
asymetricElement.SecurityHeaderLayout=SecurityHeaderLayout.Lax;
asymetricElement.KeyEntropyMode=SecurityKeyEntropyMode.ClientEntry;
asymetricElement.AllowSerializedSigningTokenOnReply=true;
X509SecurityTokenParameters启动器=新的X509SecurityTokenParameters(X509KeyIdentifierClauseType.SubjectKeyIdentifier,SecurityTokenInclusionMode.AlwaysTokenInitiator);
/*X509SecurityTokenParameters收件人=新的X509SecurityTokenParameters(X509KeyIdentifierClauseType.RawDataKeyIdentifier,SecurityTokenInclusionMode.AlwaysTokenInitiator);
asymetricElement.RecipientTokenParameters=收件人;
asymetricElement.InitiatorTokenParameters=启动器;
asymetricElement.InitiatorTokenParameters.RequiredDrivedKeys=false*/
asymetricElement.MessageProtectionOrder=System.ServiceModel.Security.MessageProtectionOrder.SignBeforeEncrypt;
asymetricElement.LocalClientSettings.IdentityVerifier=新的MyIdentityVerifier();
asymetricElement.EndpointSupportingTokenParameters.Signed.Add(
新X509SecurityTokenParameters());
binding.Elements.Clear();
binding.Elements.Add(asymetricElement);
CustomTextMessageBindingElement CustomTextMessageBindingElement=新的CustomTextMessageBindingElement(“UTF-8”,“text/xml”,MessageVersion.Soap11);
binding.Elements.Add(customTextMessageBindingElement);
HttpsTransportBindingElement HttpsTransportBindingElement=新的HttpsTransportBindingElement
{
RequireClientCertificate=true
};
httpsTransportBindingElement.HostNameComparisonMode=HostNameComparisonMode.strong通配符;
httpsTransportBindingElement.TransferMode=TransferMode.Buffered;
httpsTransportBindingElement.UseDefaultWebProxy=true;
httpsTransportBindingElement.KeepAliveEnabled=true;
httpsTransportBindingElement.AuthenticationScheme=AuthenticationSchemes.Digest;
httpsTransportBindingElement.RequireClientCertificate=true;
binding.Elements.Add(httpsTransportBindingElement);
klijent.Endpoint.Binding=绑定;
ReferenceCaserVisa.statusType状态;
弦波鲁卡;
referencaServisa.registarskiUlozak[]registarskiUlosci;
System.Net.ServicePointManager.ServerCertificateValidationCallback=委托{return true;};
//开始使用客户端。
尝试
{
klijent.Open();
status=klijent.getUlosciByMbo(“90445066”,false,out poruka,out registarskiUlosci);
referenceCaservisa.ulozak receivedLozak=null;
if(status.ToString()=“OK”)
{
receivedUlozak=RegistersKiulosci[0]。aktivnosanjeuloska.ulozak;
Show(receivedUlozak.vlasnici[0].redniBroj.ToString());
}
Show(status.ToString());
//关闭客户端。
klijent.Close();
}
catch(ProtocolException ex){MessageBox.Show(ex.Message);}
}
所以我使用了三个证书,一个用于签名,一个用于加密,一个用于SSL传输。我使用自定义绑定分离证书。当我启动我的应用程序时,我收到一个错误-一般安全错误:
内容类型为text/xml;响应消息的charset=UTF-8与绑定的内容类型(text/xml;charset=UTF-8)不匹配。如果使用自定义编码器,请确保正确实现IsContentTypeSupported方法。响应的前394个字节是:“ns1:InvalidSecurity在处理wsse:Security>标头(不支持的密钥标识)时发现错误”