저는 보안 웹 서비스 간의 상호 운용성에 대한 연구를하고 있습니다. 보안은 메시지 수준에서만 수행되어야합니다. 지금까지 인증서를 사용하여 WCF와 WSIT/Metro를 함께 사용하도록했습니다. 이제 나는 gSoap을 사용하여 똑같은 일을하려하지만, 지금까지는 운이 없었습니다.Gsoap 클라이언트의 대칭 키를 사용하여 Username 인증을 사용하여 Java Metro 웹 서비스를 사용하는 방법은 무엇입니까?
wsdl2h를 사용하여 Java 서비스 WSDL에서 헤더 파일을 생성하는 데 성공했으며 soapcpp2를 사용하여 필요한 클래스를 생성 할 수있었습니다. gsoap 문서를 따르면 WSSE 및 WSA 플러그인 은이 올바르게 구성되어야하며 실제로 Wireshark에서 스니핑을하면 Gsoap 클라이언트가 보안 헤더와 WS-Addressing 필드가있는 요청을 보냅니다 (To, Action , MessageID, ReplyTo).
Java 서비스는 3DES 알고리즘, 사용자 이름 인증 토큰 및 Lax 보안 헤더 레이아웃을 사용하여 대칭 키와 함께 사용자 이름 인증을 사용하도록 구성됩니다.
인증서는 Glassfish 키 저장소 및 신뢰 저장소에 있으며 gSoap에서 사용하기 위해 PEM 파일로 내보내지고 변환되었습니다. 나는 내가 무엇을 타임 스탬프, 인증서, 사용자 이름과 암호를 추가하고있는 중이 야, 나는이 몸을 암호화, 알고 마찬가지로 지금까지
#include <cstdlib>
#include <iostream>
#include "soapNewWebServicePortBindingProxy.h"
#include "NewWebServicePortBinding.nsmap"
#include "wsseapi.h"
#include "wsaapi.h"
using namespace std;
/*
*
*/
int main(int argc, char** argv) {
static char DES_KEY[20] =
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
/* SET UP */
NewWebServicePortBinding proxy;
proxy.soap = soap_new1(SOAP_XML_CANONICAL | SOAP_XML_INDENT);
soap_register_plugin(proxy.soap, soap_wsa);
soap_register_plugin(proxy.soap, soap_wsse);
ns1__hello req;
ns1__helloResponse resp;
req.name = new std::string("derpenstein");
/* ADD WS-SECURITY ELEMENTS */
soap_wsse_add_Security(proxy.soap);
soap_wsse_add_Signature(proxy.soap);
soap_wsse_add_Timestamp(proxy.soap, NULL, 300);
//OpenSSL_add_all_algorithms();
FILE *fd = fopen("gsoappublic.pem", "r");
FILE *fpriv = fopen("gsoapprivate.pem", "r");
X509 *cert = PEM_read_X509(fd, NULL, NULL, NULL);
EVP_PKEY *privkey = NULL;
EVP_PKEY *pubkey = NULL;
privkey = PEM_read_PrivateKey(fpriv, NULL, NULL, (void*)"changeit");
if (!privkey) {
cout << "error getting private key" << endl;
ERR_print_errors_fp(stderr);
return -1;
}
pubkey = X509_get_pubkey(cert);
if (!pubkey) {
cout << "error getting public key from certificate" << endl;
}
fclose(fd);
fclose(fpriv);
if (soap_wsse_encrypt_body(proxy.soap, SOAP_MEC_ENC_DES_CBC, DES_KEY, sizeof(DES_KEY))
|| soap_wsse_add_EncryptedKey(proxy.soap, "Cert", cert, NULL)
|| soap_wsse_add_UsernameTokenText(proxy.soap, "User", "test", "test")
|| soap_wsse_sign_body(proxy.soap, SOAP_SMD_SIGN_RSA_SHA1, privkey, 0)
|| soap_wsse_add_BinarySecurityTokenX509(proxy.soap, "X509Token", cert)
|| soap_wsse_add_KeyInfo_SecurityTokenReferenceX509(proxy.soap, "#X509Token")){
soap_print_fault(proxy.soap, stderr);
}
/* ADD WS-ADDRESSING */
soap_wsse_set_wsu_id(proxy.soap, "wsa5:From wsa5:To wsa5:ReplyTo wsa5:FaultTo wsa5:Action");
if (soap_wsa_request(proxy.soap, "uuid:5ad", "http://belgianguypc:8080/NewSecureService/NewWebService", "http://newsec.mince.org/NewWebService/helloRequest")
|| soap_wsa_add_ReplyTo(proxy.soap, "http://www.w3.org/2005/08/addressing/anonymous")) {
soap_print_fault(proxy.soap, stderr);
}
/* MAKE THE CALL */
int err = proxy.__ns1__hello(&req, &resp);
if (err == SOAP_OK) {
cout << "Success!";
cout << resp.return_;
}
else {
cout << "When sending:" << endl;
soap_print_fault(proxy.soap, stderr);
return -1;
}
return 0;
}
:
이것은 C++ 응용 프로그램에 대한 내 코드입니다 더미 DES 키와 나는 내 개인 키로 메시지에 서명한다. 그럼 난 ...
그러나이 작동하지 않습니다, 제가 출력으로 얻을 것은 호출되어 있는지 확인합니다 :
SEVERE: WSS1913: Key used to decrypt EncryptedKey cannot be null
SEVERE: WSS1927: Error occured while decrypting EncryptedKey
SEVERE: WSITPVD0035: Error in Verifying Security in Inbound Message.
com.sun.xml.wss.impl.WssSoapFaultException: WSS1927: Error occured while decrypting EncryptedKey
at com.sun.xml.ws.security.opt.impl.util.SOAPUtil.newSOAPFaultException(SOAPUtil.java:158)
at com.sun.xml.ws.security.opt.impl.incoming.EncryptedKey.getKey(EncryptedKey.java:354)
at com.sun.xml.ws.security.opt.impl.incoming.KeySelectorImpl.resolveDirectReference(KeySelectorImpl.java:628)
at com.sun.xml.ws.security.opt.impl.incoming.processor.SecurityTokenProcessor.processDirectReference(SecurityTokenProcessor.java:267)
at com.sun.xml.ws.security.opt.impl.incoming.processor.SecurityTokenProcessor.resolveReference(SecurityTokenProcessor.java:143)
at com.sun.xml.ws.security.opt.impl.incoming.processor.KeyInfoProcessor.processKeyInfo(KeyInfoProcessor.java:152)
at com.sun.xml.ws.security.opt.impl.incoming.processor.KeyInfoProcessor.getKey(KeyInfoProcessor.java:132)
at com.sun.xml.ws.security.opt.impl.incoming.EncryptedData.process(EncryptedData.java:156)
at com.sun.xml.ws.security.opt.impl.incoming.EncryptedData.<init>(EncryptedData.java:113)
at com.sun.xml.ws.security.opt.impl.incoming.SecurityRecipient.createMessage(SecurityRecipient.java:791)
at com.sun.xml.ws.security.opt.impl.incoming.SecurityRecipient.validateMessage(SecurityRecipient.java:232)
at com.sun.xml.wss.provider.wsit.WSITServerAuthContext.verifyInboundMessage(WSITServerAuthContext.java:586)
at com.sun.xml.wss.provider.wsit.WSITServerAuthContext.validateRequest(WSITServerAuthContext.java:360)
at com.sun.xml.wss.provider.wsit.WSITServerAuthContext.validateRequest(WSITServerAuthContext.java:263)
at com.sun.enterprise.security.webservices.CommonServerSecurityPipe.processRequest(CommonServerSecurityPipe.java:173)
at com.sun.enterprise.security.webservices.CommonServerSecurityPipe.process(CommonServerSecurityPipe.java:144)
at com.sun.xml.ws.api.pipe.helper.PipeAdapter.processRequest(PipeAdapter.java:119)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:641)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:600)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:585)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:482)
at com.sun.xml.ws.server.WSEndpointImpl$2.process(WSEndpointImpl.java:314)
at com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:608)
at com.sun.xml.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:259)
at com.sun.xml.ws.transport.http.servlet.ServletAdapter.handle(ServletAdapter.java:162)
at org.glassfish.webservices.JAXWSServlet.doPost(JAXWSServlet.java:145)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:754)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:232)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Unknown Source)
Caused by: java.io.IOException: Key used to decrypt EncryptedKey cannot be null
at com.sun.xml.ws.security.opt.impl.enc.CryptoProcessor.decryptKey(CryptoProcessor.java:346)
at com.sun.xml.ws.security.opt.impl.incoming.EncryptedKey.getKey(EncryptedKey.java:351)
... 51 more
내가의 루트를 가정 :
When sending:
SOAP 1.1 Fault: wsse:FailedCheck [no subcode]
"WSS1927: Error occurred while decrypting EncryptedKey"
Detail: [no detail]
글래스 피쉬는 스택 추적을 제공합니다 문제는 EncryptedKey가 서비스에 따라 null이지만 어떤 키인지 또는 왜 null인지 알지 못한다는 것입니다.
내 질문은 : Gsoap에서 안전한 Metro 서비스를 사용할 수 있습니까? 그렇다면 무엇이 잘못 되었습니까? 내가 뭘 놓치고 있니?
감사합니다.