title: WSS4J code calculating digest, signing and adding key information?
body: <p>We need to create a WS client to interface with the IRS. We are following the steps the IRS defines on page 31 of their guide <a href="https://www.irs.gov/PUP/for_taxpros/software_developers/information_returns/AIR%20Submission%20Composition%20and%20Reference%20Guide%20TY2015.pdf" rel="nofollow noreferrer">https://www.irs.gov/PUP/for_taxpros/software_developers/information_returns/AIR%20Submission%20Composition%20and%20Reference%20Guide%20TY2015.pdf</a></p>
  
  <p>It looks like standard WS-Security that WSS4J can handle. But when using WS44J and hitting the IRS WS we keep on getting "Invalid WS Security Header. Please try again"</p>
  
  <p>So, can someone please tell me if the below WSS4J code is in fact <strong><em>(1)</em></strong> calculating the digest of elements ACABusinessHeader, ACATransmitterManifestReqDtl and Timestamp <strong><em>(2)</em></strong> collecting these reference elements within a SignedInfo element <strong><em>(3)</em></strong> calculating the digest of the SignedInfo element, signing that digest and putting the signature value in a SignatureValue <strong><em>(4)</em></strong> placing keying information  in the KeyInfo element:</p>
  
  <pre><code>public static SOAPMessage signSoapMessage(SOAPMessage message,
          String keystorePassword, String irsPrivateKeyPassword,
          char[] passphrase) throws WSSecurityException {
  
      PrivateKeyEntry privateKeyEntry = getPrivateKeyEntry(keystorePassword,
              irsPrivateKeyPassword);
  
      PrivateKey signingKey = privateKeyEntry.getPrivateKey();
      X509Certificate signingCert = (X509Certificate) privateKeyEntry
              .getCertificate();
  
      final String alias = "signingKey";
      final int signatureValidityTime = 3600; // 1hour in seconds
  
      WSSConfig config = new WSSConfig();
      config.setWsiBSPCompliant(true);
  
      WSSecSignature builder = new WSSecSignature(config);
  
      builder.setX509Certificate(signingCert);
      builder.setUserInfo(alias, new String(passphrase));
      builder.setUseSingleCertificate(true);
      builder.setKeyIdentifierType(WSConstants.X509_KEY_IDENTIFIER);      
      builder.setDigestAlgo(WSConstants.SHA1);
      builder.setSignatureAlgorithm(WSConstants.RSA_SHA1);
      builder.setSigCanonicalization(WSConstants.C14N_EXCL_WITH_COMMENTS);
  
      try {
          Document document = 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&lt;WSEncryptionPart&gt; parts = new ArrayList&lt;WSEncryptionPart&gt;();
          WSEncryptionPart timestampPart = new WSEncryptionPart("Timestamp",
                  WSConstants.WSU_NS, "");
  
          WSEncryptionPart aCATransmitterManifestReqDtlPart = new WSEncryptionPart(
                  "ACATransmitterManifestReqDtl",
                  "urn:us:gov:treasury:irs:ext:aca:air:7.0", "");
          WSEncryptionPart aCABusinessHeaderPart = new WSEncryptionPart(
                  "ACABusinessHeader",
                  "urn:us:gov:treasury:irs:msg:acabusinessheader", "");
          parts.add(timestampPart);
          parts.add(aCATransmitterManifestReqDtlPart);
          parts.add(aCABusinessHeaderPart);
          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);
  
          updateSOAPMessage(document, message);
  
  
      } catch (Exception e) {
          // throw new
          // WSSecurityException(WSSecurityException.Reason.SIGNING_ISSUE, e);
          e.printStackTrace();
      }
  
      return message;
  }
  
  private static Document toDocument(SOAPMessage soapMsg)
          throws TransformerConfigurationException, TransformerException,
          SOAPException, IOException {
      Source src = soapMsg.getSOAPPart().getContent();
      TransformerFactory tf = TransformerFactory.newInstance();
      Transformer transformer = tf.newTransformer();
      DOMResult result = new DOMResult();
      transformer.transform(src, result);
      return (Document) result.getNode();
  }
  
  //https://svn.apache.org/repos/asf/webservices/wss4j/branches/WSS4J_1_1_0_FINAL/test/wssec/SOAPUtil.java
  private static SOAPMessage updateSOAPMessage(Document doc,
                                              SOAPMessage message)
          throws Exception {
      DOMSource domSource = new DOMSource(doc);
      message.getSOAPPart().setContent(domSource);
      return message;
  }
  </code></pre>
  
  <p>Here is our output:</p>
  
  <pre><code>&lt;S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
  xmlns:oas="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
  xmlns:urn="urn:us:gov:treasury:irs:ext:aca:air:7.0" xmlns:urn1="urn:us:gov:treasury:irs:common"
  xmlns:urn2="urn:us:gov:treasury:irs:msg:acabusinessheader" xmlns:urn3="urn:us:gov:treasury:irs:msg:acasecurityheader"
  xmlns:urn4="urn:us:gov:treasury:irs:msg:irsacabulkrequesttransmitter"
  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"&gt;
  &lt;S:Header&gt;
      &lt;wsse:Security S:mustUnderstand="1"&gt;
          &lt;ds:Signature Id="SIG-2"&gt;
              &lt;ds:SignedInfo&gt;
                  &lt;ds:CanonicalizationMethod
                      Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#WithComments" /&gt;
                  &lt;ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /&gt;
                  &lt;ds:Reference URI="#TS-1"&gt;
                      &lt;ds:Transforms&gt;
                          &lt;ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"&gt;
                              &lt;ec:InclusiveNamespaces
                                  PrefixList="wsse S ds oas urn urn1 urn2 urn3 urn4 wsse"
                                  xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" /&gt;
                          &lt;/ds:Transform&gt;
                      &lt;/ds:Transforms&gt;
                      &lt;ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /&gt;
                      &lt;ds:DigestValue&gt;nTyiWyyyQd+JQZvU2QPY1QnInd4=&lt;/ds:DigestValue&gt;
                  &lt;/ds:Reference&gt;
                  &lt;ds:Reference URI="#aCATransmitterManifestReqDtl"&gt;
                      &lt;ds:Transforms&gt;
                          &lt;ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"&gt;
                              &lt;ec:InclusiveNamespaces
                                  PrefixList="S ds oas urn urn1 urn2 urn3 urn4 wsse wsu"
                                  xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" /&gt;
                          &lt;/ds:Transform&gt;
                      &lt;/ds:Transforms&gt;
                      &lt;ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /&gt;
                      &lt;ds:DigestValue&gt;3pUoQp4S5sKXa6o9+MamJbji8vs=&lt;/ds:DigestValue&gt;
                  &lt;/ds:Reference&gt;
                  &lt;ds:Reference URI="#acabusinessheader"&gt;
                      &lt;ds:Transforms&gt;
                          &lt;ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"&gt;
                              &lt;ec:InclusiveNamespaces PrefixList="S ds oas urn urn1 urn3 urn4 wsse"
                                  xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" /&gt;
                          &lt;/ds:Transform&gt;
                      &lt;/ds:Transforms&gt;
                      &lt;ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /&gt;
                      &lt;ds:DigestValue&gt;9SvmkYlD+ItpUctUaQZTH5pGXjc=&lt;/ds:DigestValue&gt;
                  &lt;/ds:Reference&gt;
              &lt;/ds:SignedInfo&gt;
              &lt;ds:SignatureValue&gt;qgmh8LN8KwR0KZf508heS6whaM7ZGeW88dl/0awLYCd3lzle8THHUUstYKCaZJi6XF1DGJjDrIq81FEszUSp9Pa1akZ3r6rB8Oi2dOlgzHq6H+lYaHFVwYnMHHyFpEHRQJO36OaXKl25SILDHWxvrFRXf21NDnWszXKXnvvbSjrkzTTzWo4wRO2ftUQq2F69MPM3OsG981rmPWUd5z/KC5jVTsqELBtSM5L8ehOihXoJ0uNwdw1HZzh7xYXme6bXU++4w2I8x5vLjvnCcD1TIuNLvrK6HN414KylAEoxAUqAkWo69GJyx/18soLFXVaLKbwAhQkplkaJwcWKoEiRaw==
              &lt;/ds:SignatureValue&gt;
              &lt;ds:KeyInfo Id="KI-4E5E7B5A7DFD75103414509160809772"&gt;
                  &lt;wsse:SecurityTokenReference wsu:Id="STR-4E5E7B5A7DFD75103414509160809783"&gt;
                      &lt;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#X509v3"&gt;removed
                      &lt;/wsse:KeyIdentifier&gt;
                  &lt;/wsse:SecurityTokenReference&gt;
              &lt;/ds:KeyInfo&gt;
          &lt;/ds:Signature&gt;
          &lt;wsu:Timestamp wsu:Id="TS-1"&gt;
              &lt;wsu:Created&gt;2015-12-24T00:14:40.968Z&lt;/wsu:Created&gt;
              &lt;wsu:Expires&gt;2015-12-24T01:14:40.968Z&lt;/wsu:Expires&gt;
          &lt;/wsu:Timestamp&gt;
      &lt;/wsse:Security&gt;
      &lt;ACATransmitterManifestReqDtl
          xmlns:ns3="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
          ns3:Id="aCATransmitterManifestReqDtl" xmlns="urn:us:gov:treasury:irs:ext:aca:air:7.0"
          xmlns:ns2="urn:us:gov:treasury:irs:common"&gt;
          &lt;PaymentYr&gt;2015&lt;/PaymentYr&gt;
          &lt;PriorYearDataInd&gt;0&lt;/PriorYearDataInd&gt;
          &lt;ns2:EIN&gt;blah&lt;/ns2:EIN&gt;
          &lt;TransmissionTypeCd&gt;O&lt;/TransmissionTypeCd&gt;
          &lt;TestFileCd&gt;T&lt;/TestFileCd&gt;
          &lt;TransmitterNameGrp&gt;
              &lt;BusinessNameLine1Txt&gt;blah&lt;/BusinessNameLine1Txt&gt;
              &lt;BusinessNameLine2Txt&gt;blah&lt;/BusinessNameLine2Txt&gt;
          &lt;/TransmitterNameGrp&gt;
          &lt;CompanyInformationGrp&gt;
              &lt;CompanyNm&gt;blah&lt;/CompanyNm&gt;
              &lt;MailingAddressGrp&gt;
                  &lt;USAddressGrp&gt;
                      &lt;AddressLine1Txt&gt;blah&lt;/AddressLine1Txt&gt;
                      &lt;AddressLine2Txt&gt;3rd Floor&lt;/AddressLine2Txt&gt;
                      &lt;ns2:CityNm&gt;blah&lt;/ns2:CityNm&gt;
                      &lt;USStateCd&gt;CA&lt;/USStateCd&gt;
                      &lt;ns2:USZIPCd&gt;12345&lt;/ns2:USZIPCd&gt;
                      &lt;ns2:USZIPExtensionCd&gt;1234&lt;/ns2:USZIPExtensionCd&gt;
                  &lt;/USAddressGrp&gt;
              &lt;/MailingAddressGrp&gt;
              &lt;ContactNameGrp&gt;
                  &lt;PersonFirstNm&gt;blah&lt;/PersonFirstNm&gt;
                  &lt;PersonMiddleNm&gt;X&lt;/PersonMiddleNm&gt;
                  &lt;PersonLastNm&gt;blah&lt;/PersonLastNm&gt;
                  &lt;SuffixNm /&gt;
              &lt;/ContactNameGrp&gt;
              &lt;ContactPhoneNum&gt;1231231234&lt;/ContactPhoneNum&gt;
          &lt;/CompanyInformationGrp&gt;
          &lt;VendorInformationGrp&gt;
              &lt;VendorCd&gt;I&lt;/VendorCd&gt;
              &lt;ContactNameGrp&gt;
                  &lt;PersonFirstNm&gt;blah&lt;/PersonFirstNm&gt;
                  &lt;PersonMiddleNm&gt;X&lt;/PersonMiddleNm&gt;
                  &lt;PersonLastNm&gt;blah&lt;/PersonLastNm&gt;
                  &lt;SuffixNm /&gt;
              &lt;/ContactNameGrp&gt;
              &lt;ContactPhoneNum&gt;5556651212&lt;/ContactPhoneNum&gt;
          &lt;/VendorInformationGrp&gt;
          &lt;TotalPayeeRecordCnt&gt;1000&lt;/TotalPayeeRecordCnt&gt;
          &lt;TotalPayerRecordCnt&gt;1&lt;/TotalPayerRecordCnt&gt;
          &lt;SoftwareId&gt;blah&lt;/SoftwareId&gt;
          &lt;FormTypeCd&gt;1094/1095B&lt;/FormTypeCd&gt;
          &lt;ns2:BinaryFormatCd&gt;application/xml&lt;/ns2:BinaryFormatCd&gt;
          &lt;ns2:ChecksumAugmentationNum&gt;04ff9f93f9b797ae51ea2ac8bf9c24d2
          &lt;/ns2:ChecksumAugmentationNum&gt;
          &lt;ns2:AttachmentByteSizeNum&gt;237018&lt;/ns2:AttachmentByteSizeNum&gt;
          &lt;DocumentSystemFileNm&gt;1000_form1094BUpstreamDetailType.xml
          &lt;/DocumentSystemFileNm&gt;
      &lt;/ACATransmitterManifestReqDtl&gt;
      &lt;urn2:ACABusinessHeader wsu:Id="acabusinessheader"&gt;
          &lt;urn:UniqueTransmissionId&gt;1&lt;/urn:UniqueTransmissionId&gt;
          &lt;urn1:Timestamp&gt;2015-12-24T00:19:40.826Z&lt;/urn1:Timestamp&gt;
      &lt;/urn2:ACABusinessHeader&gt;
  &lt;/S:Header&gt;
  &lt;S:Body&gt;
      &lt;ns8:ACABulkRequestTransmitter xmlns="http://www.w3.org/2000/09/xmldsig#"
          xmlns:ns2="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
          xmlns:ns3="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
          xmlns:ns4="urn:us:gov:treasury:irs:common" xmlns:ns5="urn:us:gov:treasury:irs:ext:aca:air:7.0"
          xmlns:ns6="urn:us:gov:treasury:irs:msg:acabusinessheader" xmlns:ns7="urn:us:gov:treasury:irs:msg:acasecurityheader"
          xmlns:ns8="urn:us:gov:treasury:irs:msg:irsacabulkrequesttransmitter"&gt;
          &lt;ns4:BulkExchangeFile&gt;H4sIAAAAA&lt;/ns4:BulkExchangeFile&gt;
      &lt;/ns8:ACABulkRequestTransmitter&gt;
  &lt;/S:Body&gt;
  </code></pre>
  
  <p></p>
  
  <p><strong><em>EDIT Here is the improved Java code that can bypass the infamous "Invalid WS Security Header. Please try again." message. Our stack is Apache CXF 3.1.4 and WSS4J 2.1.4</em></strong></p>
  
  <p><a href="https://stackoverflow.com/a/34959348/3724142">https://stackoverflow.com/a/34959348/3724142</a></p>
  
  <p><strong><em>Refer to the above link for latest source</em></strong></p>