2012-12-27 4 views
6

Ich bin Web-Service-Client in Java, die wss4j 1.6.8 für WS-Security (genauer gesagt, ich muss eine SOAP-Nachricht signieren). Server-Seite erfordert Anfragen die folgende Struktur haben:WSS4j Elemente Reihenfolge während der Signierung SOAP-Nachricht

<Envelope> 
    <Header> 
     <wsse:Security mustUnderstand="1"> 
      **<wsu:Timestamp wsu:Id="Timestamp-913ca68e-05ed-44e1-9d6c-b2f293da5a1d"> 
       <wsu:Created>2012-12-21T11:37:31Z</wsu:Created> 
       <wsu:Expires>2012-12-21T11:42:31Z</wsu:Expires> 
      </wsu:Timestamp>** 
      <wsse:BinarySecurityToken> 
       MIID2jCCAsKg... 
      </wsse:BinarySecurityToken> 
      <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> 
       <SignedInfo> 
        <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> 
        <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> 
        <Reference URI="#Timestamp-913ca68e-05ed-44e1-9d6c-b2f293da5a1d"> 
         <Transforms> 
          <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> 
         </Transforms> 
         <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> 
         <DigestValue>jdVY1HaDLusqO9UcxASE/GQHxyo=</DigestValue> 
        </Reference> 
        <Reference URI="#Body-e344eef1-2d8a-42d0-8a30-361ee61a8617"> 
         <Transforms> 
          <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> 
         </Transforms> 
         <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> 
         <DigestValue>L60mQelZERvXgLEgWlW50uJNqEA=</DigestValue> 
        </Reference> 
       </SignedInfo> 
       <SignatureValue> 
        NmgACUqrYYc/Kp/F... 
       </SignatureValue> 
       <KeyInfo> 
        <wsse:SecurityTokenReference xmlns=""> 
         <wsse:Reference URI="#SecurityToken-3f054298-711c-4090-95c3-105e1093f3ba" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/> 
        </wsse:SecurityTokenReference> 
       </KeyInfo> 
      </Signature> 
     </wsse:Security> 
    </S:Header> 
    <S:Body> 
     Body content... 
    </S:Body> 
</Envelope> 

Meine Lösung unterzeichnet das Dokument (beide Körper und Zeitstempel-Elemente), aber aus irgendeinem Grund WSS4J setzt Zeitstempel-Element an der Unterseite des Abschnitts nach <wsse:BinarySecurityToken> und <Signature> Elemente, was ist falsch. Bitte schauen Sie sich die Quellen, die Arbeit nicht Unterzeichnung:

public static SOAPMessage signSoapMessage(SOAPMessage message, PrivateKey signingKey, X509Certificate signingCert, char[] passphrase) throws WSSecurityException { 

    final String alias = "signingKey"; 
    final int signatureValidityTime = 3600; // 1hour in seconds 

    WSSConfig config = new WSSConfig(); 
    config.setWsiBSPCompliant(false); 

    WSSecSignature builder = new WSSecSignature(config); 

    builder.setX509Certificate(signingCert); 
    builder.setUserInfo(alias, new String(passphrase)); 
    builder.setUseSingleCertificate(true); 
    builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE); 

    try { 
     Document document = DanskeUtils.toDocument(message); 
     WSSecHeader secHeader = new WSSecHeader(); 
     secHeader.setMustUnderstand(true); 
     secHeader.insertSecurityHeader(document); 

     WSSecTimestamp timestamp = new WSSecTimestamp(); 
     timestamp.setTimeToLive(signatureValidityTime); 
     document = timestamp.build(document, secHeader); 

     List<WSEncryptionPart> parts = new ArrayList<WSEncryptionPart>(); 
     WSEncryptionPart timestampPart = new WSEncryptionPart("Timestamp", WSConstants.WSU_NS, ""); 
     WSEncryptionPart bodyPart = new WSEncryptionPart(WSConstants.ELEM_BODY, WSConstants.URI_SOAP11_ENV, ""); 
     parts.add(timestampPart); 
     parts.add(bodyPart); 
     builder.setParts(parts); 

     Properties properties = new Properties(); 
     properties.setProperty("org.apache.ws.security.crypto.provider", "org.apache.ws.security.components.crypto.Merlin"); 
     Crypto crypto = CryptoFactory.getInstance(properties); 
     KeyStore keystore = KeyStore.getInstance("JKS"); 
     keystore.load(null, passphrase); 
     keystore.setKeyEntry(alias, signingKey, passphrase, new Certificate[]{signingCert}); 
     ((Merlin) crypto).setKeyStore(keystore); 
     crypto.loadCertificate(new ByteArrayInputStream(signingCert.getEncoded())); 

     document = builder.build(document, crypto, secHeader); 
     return Utils.updateSoapMessage(document, message); 
    } catch (Exception e) { 
     throw new WSSecurityException(WSSecurityException.Reason.SIGNING_ISSUE, e); 
    } 
} 

Könnten Sie mir bitte helfen, zu klären, wie die Reihenfolge der Elemente vor Dokument unterzeichnen wird sich ändern? Vielen Dank!

+0

Danke. Deine Frage hat mir sehr geholfen. Können Sie mir bitte sagen, wie man die Signatur einer Soap-Nachricht mit wss4j apis validiert. –

Antwort

1

Die WS-SEC-Spezifikation sagt "Wenn Elemente zu einem Header-Block hinzugefügt werden, SOLLTEN sie den vorhandenen Elementen vorangestellt werden."

Wenn Sie also zuerst den Zeitstempel hinzufügen, wird er über allen vorhandenen untergeordneten Elementen in der WS-Kopfzeile liegen. Da Sie eine Nachricht nach dem Hinzufügen des Timstamps signieren, wird die Signierungsinformation erneut an den Header angehängt und erscheint somit über dem Timestamp-Element.

Wenn Sie den Zeitstempel-Element müssen an der Spitze erscheinen, fügen Sie es in den Header als letzte Prozess

0

Nachdem Sie die Signatur erstellen können Sie diese Zeile hinzufügen:

timestamp.prependToHeader(secHeader); 

es wird Setzen Sie das Timestamp-Element über Ihr BinarySecurityToken-Element.

Verwandte Themen