Эмуляция подписанного запроса soapUI с помощью nodejs - PullRequest
0 голосов
/ 25 января 2019

Оказывается, что я тестировал веб-сервис через soapUI, настраивая хранилище ключей с полученным сертификатом pem.

Когда я применяю исходящую подпись WSSE, я получаю элемент wsse: Security, подобный этому:

    <wsse:Security
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<ds:Signature Id="SIG-1C747258C55C77E5C5154835835043446"
    xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
        <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
            <ec:InclusiveNamespaces PrefixList="hal ns ns1 ns2 soapenv"
                xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            </ds:CanonicalizationMethod>
            <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
            <ds:Reference URI="#id-1C747258C55C77E5C515483521292064">
                <ds:Transforms>
                    <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                        <ec:InclusiveNamespaces PrefixList="hal ns ns1 ns2"
                            xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                        </ds:Transform>
                    </ds:Transforms>
                    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                    <ds:DigestValue>AfQsslNyqfZcR2GwBV+0vtAuO/c=</ds:DigestValue>
                </ds:Reference>
            </ds:SignedInfo>
            <ds:SignatureValue>
                [THE SIGNATURE]
            </ds:SignatureValue>
            <ds:KeyInfo Id="KI-1C747258C55C77E5C5154835835043344">
                <wsse:SecurityTokenReference wsu:Id="STR-1C747258C55C77E5C5154835835043345">
                    <wsse:KeyIdentifier EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier">VwDFSfuw3Zk0GeAG4PhV8YWZ2P4=</wsse:KeyIdentifier>
                </wsse:SecurityTokenReference>
            </ds:KeyInfo>
        </ds:Signature>
    </wsse:Security>

Я заинтересован в создании этого точного блока с помощью nodejs. Я пытался использовать пакет soap, но он всегда возвращает ошибку «Unable To Parse Request», которая, если я заменю блок подписи этим, работает.

Итак, в основном я хочу знать, как вручную подписать тело и заменить хэши, затем заменить их в этом блоке и сделать простую запись:)

Надеюсь, вы не найдете этот вопрос наивным (я очень плохо знаком с веб-сервисами SOAP).

Спасибо!

1 Ответ

0 голосов
/ 29 января 2019

Я бросил делать это с nodeJS и сделал это с помощью Java.Вот как я это сделал:

import org.apache.ws.security.WSConstants;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.components.crypto.CryptoFactory;
import org.apache.ws.security.message.WSSecHeader;
import org.apache.ws.security.message.WSSecSignature;
import org.apache.xml.security.algorithms.MessageDigestAlgorithm;
import org.apache.xml.security.signature.XMLSignature;
import org.w3c.dom.Document;
import java.io.StringWriter;
import java.util.Properties;

import static java.nio.file.Files.readAllBytes;
import static java.nio.file.Paths.get;

public class WSSecuritySign {

    public static void signXml() throws Exception {

        final String req = new String(readAllBytes(get("target/classes/test.xml"))); //the soap envelope to be signed without the security header
        final Document soapDocument = XmlUtils.parseXml(req);

        final WSSecHeader secHeader = new WSSecHeader();
        final WSSecSignature wssSign = new WSSecSignature();

        final Crypto wssCrypto = getCrypto();

        secHeader.insertSecurityHeader(soapDocument);

        wssSign.setSignatureAlgorithm(XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1);
        wssSign.setSigCanonicalization(WSConstants.C14N_EXCL_OMIT_COMMENTS);
        wssSign.setUseSingleCertificate(false);
        wssSign.setDigestAlgo(MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA1);
        wssSign.setKeyIdentifierType(WSConstants.CUSTOM_KEY_IDENTIFIER);

        wssSign.setUserInfo("keystore_alias", "a_password");
        wssSign.setKeyIdentifierType(4); //Or Subject Key Identifier

        wssSign.build(soapDocument, wssCrypto, secHeader);

        final StringWriter writer = new StringWriter();
        XmlUtils.serialize(soapDocument.getDocumentElement(), writer);
        System.out.println(writer.toString());
    }
    public static void main(String... unused) throws Exception {
        signXml();
    }

    public static Crypto getCrypto() throws Exception {
        Properties props =  new Properties();
        props.setProperty("org.apache.ws.security.crypto.provider", "org.apache.ws.security.components.crypto.Merlin");
        props.setProperty("org.apache.ws.security.crypto.merlin.keystore.password", "a_password");
        props.setProperty("org.apache.ws.security.crypto.merlin.keystore.alias", "keystore_alias");
        props.setProperty("org.apache.ws.security.crypto.merlin.keystore.file", "keystore.jks");

        return CryptoFactory.getInstance(props, ClassLoader.getSystemClassLoader());
    }
}

Не забудьте заменить псевдоним хранилища ключей, его расположение и пароль (если есть), я думаю, что есть пароль по умолчанию, если ваше хранилище ключей ненет, не помню, как это называется.

...