2017-02-07 69 views
3

我正尝试在java中创建一个Soap客户端,我必须使用我的私钥签署Soap消息。用于WSSecurity与数字签名的SOAPHandler

我使用SoapUI获得响应,配置了WS-Security

我已经使用wsimport导入了WSDL和生成的类。

我创建了一个SOAPHandler来签名消息,如下所示。我不确定如果这是签署消息的正确方法。

@Override 
private void handleMessage(SOAPMessageContext context) throws SOAPException, WSSecurityException { 
    try { 
     SOAPMessage soapMessage = context.getMessage(); 
     SOAPPart soapPart = soapMessage.getSOAPPart(); 
     soapMessage.getSOAPHeader(); 
     WSSecHeader wsSecHeader = new WSSecHeader(); 
     wsSecHeader.setMustUnderstand(true); 
     wsSecHeader.insertSecurityHeader(soapPart); 

     WSSecTimestamp wsSecTimeStamp = new WSSecTimestamp(); 
     wsSecTimeStamp.prepare(soapPart); 
     wsSecTimeStamp.prependToHeader(wsSecHeader); 

     WSSConfig wssConfig = new WSSConfig(); 
     WSSecSignature sign = new WSSecSignature(wssConfig); 
     sign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE); 

     Properties cxfProps = new Properties(); 
     cxfProps.setProperty("org.apache.ws.security.crypto.provider", "org.apache.ws.security.components.crypto.Merlin"); 
     cxfProps.setProperty("org.apache.ws.security.crypto.merlin.keystore.type", "jks"); 
     cxfProps.setProperty("org.apache.ws.security.crypto.merlin.keystore.alias", "example.com"); 
     cxfProps.setProperty("org.apache.ws.security.crypto.merlin.keystore.password", "password"); 
     cxfProps.setProperty("org.apache.ws.security.crypto.merlin.keystore.file", "keystore.jks"); 

     Crypto crypto1 = CryptoFactory.getInstance(cxfProps); 

     sign.prepare(soapPart, crypto1, wsSecHeader); 
     String bstId = sign.getBSTTokenId(); 
     sign.appendBSTElementToHeader(wsSecHeader); 
     sign.setDigestAlgo("http://www.w3.org/2001/04/xmlenc#sha256"); 
     sign.setSignatureAlgorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"); 
     Vector<WSEncryptionPart> signParts = new Vector<WSEncryptionPart>(); 
     signParts.add(new WSEncryptionPart(wsSecTimeStamp.getId())); 
     signParts.add(new WSEncryptionPart(WSConstants.ELEM_BODY, 
       WSConstants.URI_SOAP12_ENV, "")); 
     signParts.add(new WSEncryptionPart(bstId)); 
     sign.addReferencesToSign(signParts, wsSecHeader); 
     List<Reference> referenceList = sign.addReferencesToSign(signParts, 
       wsSecHeader); 
     sign.computeSignature(referenceList, false, null); 

    } catch (Exception ex) { 
     Logger.getLogger(SecurityHandler.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 

我得到一个NullPointerException

java.lang.NullPointerException 
at sun.security.provider.JavaKeyStore$JKS.convertAlias(JavaKeyStore.java:57) 
at sun.security.provider.JavaKeyStore.engineGetCertificateChain(JavaKeyStore.java:153) 
at sun.security.provider.JavaKeyStore$JKS.engineGetCertificateChain(JavaKeyStore.java:55) 
at java.security.KeyStore.getCertificateChain(KeyStore.java:1036) 
at org.apache.ws.security.components.crypto.Merlin.getX509Certificates(Merlin.java:1277) 
at org.apache.ws.security.components.crypto.Merlin.getX509Certificates(Merlin.java:600) 
at org.apache.ws.security.message.WSSecSignature.getSigningCerts(WSSecSignature.java:793) 
at org.apache.ws.security.message.WSSecSignature.prepare(WSSecSignature.java:169) 
at app.SecurityHandler.handleOutboundMessage(SecurityHandler.java:187) 
+0

对此有何想法? – gllambi

+0

使用Spring [webservice模板](http://docs.spring.io/spring-ws/site/apidocs/org/springframework/ws/client/core/WebServiceTemplate.html)并使用Wss4jSecurityInterceptor添加配置 – Mahasooq

回答

0

为了从您的密钥库中选择目标私钥,你必须在你的代码添加

sign.setUserInfo("key-alias", "key-password");