我正在尝试创建一个使用JAVA WS的WCF客户端APP,它使用三个证书,其中两个用于签名和加密,一个用于传输。服务器上安装了一个私钥,并从JKS密钥库文件导出了公共证书文件。我在个人证书下通过MMC安装了用于签名和加密到证书存储区的公钥和密钥。
以下是表格中的我的代码:
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.