7

WS-Securityにwss4j1.6.8を使用するWebサービスクライアントをJavaで実装しています(より正確に言うと、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);
    }
}

ドキュメントが署名される前に要素の順序を変更する方法を明確にするのを手伝っていただけませんか?ありがとうございました!

4

2 に答える 2

1

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

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

タイムスタンプ要素を一番上に表示する必要がある場合は、最終プロセスとしてヘッダーに追加します

于 2013-10-24T08:40:17.197 に答える