2012-03-12 4 views
1

저는 보안 웹 서비스 간의 상호 운용성에 대한 연구를하고 있습니다. 보안은 메시지 수준에서만 수행되어야합니다. 지금까지 인증서를 사용하여 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 서비스를 사용할 수 있습니까? 그렇다면 무엇이 잘못 되었습니까? 내가 뭘 놓치고 있니?

감사합니다.

답변

0

gSOAP Yahoo 그룹에 질문 해 보셨습니까? http://tech.groups.yahoo.com/group/gsoap/에 있습니다. 약속 없음; 비슷한 문제 (WSSE가있는 Java Apache Axis와는 다른 서비스이지만 gSOAP)에 어려움을 겪고 있으며 해당 그룹의 도움이 부족합니다.

덧붙여 gSOAP를위한 패치는 "no detail"문자열 대신에 전체 오류 메시지를 되돌릴 수있게 해줍니다. 이 메시지에 있습니다 : http://tech.groups.yahoo.com/group/gsoap/message/19031