2012-12-27 15 views
6

私はJavaでWebサービスクライアントを実装しています。これはWS-Securityにwss4j 1.6.8を使用しています(SOAPメッセージに署名する必要があります)。サーバー側は、次のような構造を持っているのリクエストが必要です。WSS4j要素はSOAPメッセージに署名する際に順序付けします

<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> 

私のソリューションは、文書(ボディおよびタイムスタンプの要素の両方を)署名が、何らかの理由でWSS4Jは何<wsse:BinarySecurityToken><Signature>要素の後、セクションの下部にタイムスタンプ要素を置きます間違っている。仕事に署名しないソースを見てください:

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); 
    } 
} 

あなたは、文書が署名されます前に、要素の順序を変更する方法を明確にするために私を助けていただけますか? ありがとうございました!

+0

ありがとうございました。あなたの質問は私を大いに助けました。 wss4j apisを使ってsoapメッセージの署名を検証する方法を教えてください。 –

答えて

1

WS-SEC仕様では、「要素がヘッダーブロックに追加されると、既存の要素の先頭に追加する必要があります」と記載されています(SHOULD)。

タイムスタンプを最初に追加すると、ws-headerの既存の子要素の上になります。タイムスタンプを追加した後にメッセージに署名しているので、署名情報はヘッダーに先行して追加されます。したがって、タイムスタンプ要素の上に表示されます。

あなたは、あなたがこの行を追加することができます署名を構築した後、最終的なプロセス

0

としてヘッダに追加し、一番上に表示されるようにタイムスタンプ要素が必要な場合:

timestamp.prependToHeader(secHeader); 

それは意志タイムスタンプ要素をBinarySecurityToken要素の上に置きます。

関連する問題