Я бросил делать это с 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());
}
}
Не забудьте заменить псевдоним хранилища ключей, его расположение и пароль (если есть), я думаю, что есть пароль по умолчанию, если ваше хранилище ключей ненет, не помню, как это называется.