我很想使用wss4j来签名SOAP文档。我希望我看起来像图1。但是,它像图2一样出现。也就是说,图1中有一个,它指向文档的BinarySecurityToken。而图2中有一个,它引用了用于签署文档的原始证书。

A)现在,BinarySecurityToken是提供者端用来在其密钥库中定位相应证书链的二进制值(用于验证消息)。

B)我相信SecurityTokenReference用于引用二进制安全令牌,该令牌包含应用于验证签名的公共密钥。所以看起来我的挑战是使图2中的指针看起来像图1。

它是否正确?如果是这样,wss4j中的什么开关可以做到这一点?生成图2的代码在图3中(Clojure代码)。到目前为止,我一直在研究wss4j源代码以供参考(ReferenceTest.javaSecurityTokenReferenceTest.javaSignatureTest.java)。

        <wsse:SecurityTokenReference wsu:Id="STRId-A96305E32CE45DAB06139999212441542"
                                     xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
           <wsse:Reference URI="#CertId-A96305E32CE45DAB06139999212441540"   <!-- this points to <wsse:BinarySecurityToken> -->
                                    ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
        </wsse:SecurityTokenReference>


图。1

        <wsse:SecurityTokenReference wsu:Id="STR-f9837b22-c073-45d2-92d0-2df67e823b2e">
          <ds:X509Data>
            <ds:X509IssuerSerial>
              <ds:X509IssuerName>CN=*.***.com,O=<org>,L=<city>,ST=<state>,C=<country>
              </ds:X509IssuerName>
              <ds:X509SerialNumber><some-value>
              </ds:X509SerialNumber>
            </ds:X509IssuerSerial>
          </ds:X509Data>
        </wsse:SecurityTokenReference>


图2

  (defn sign-soap [soap-string]

    (let [
          ;; ===> pull in keystore & cerificate
          ks (ks/keystore)
          _ (ks/import-cert ks "server" (slurp "<mykeystore>"))

          cert (.getCertificate ks "server")
          keyEntry (.getEntry ks "server" nil)


          ;; ===> set Certificate on the signature object
          builder (WSSecSignature.)
          _ (.setX509Certificate builder cert)



          ;; ===> insert security header into the document
          docu (soap/to-w3c-document soap-string)

          secHeader (WSSecHeader.)
          _ (.insertSecurityHeader secHeader docu)


          ;; ===>
          crypto (CryptoFactory/getInstance)


          bst (X509Security. docu)
          cryptoType (CryptoType. org.apache.wss4j.common.crypto.CryptoType$TYPE/ALIAS)
          _ (.setAlias cryptoType "mykey")


          certs (.getX509Certificates crypto cryptoType)
          _ (.setX509Certificate bst (first (seq certs)))
          _ (WSSecurityUtil/prependChildElement
             (.getSecurityHeader secHeader)
             (.getElement bst))

          ;; ===>
          timestamp (WSSecTimestamp.)
          _ (.setTimeToLive timestamp 300)

          createdDoc (.build timestamp docu secHeader)


          ;; ===>
          encTimestamp (WSEncryptionPart. "Timestamp" WSConstants/WSU_NS "")
          encBody (WSEncryptionPart. "Body" "http://schemas.xmlsoap.org/soap/envelope/" "")
          parts (ArrayList.)
          _ (.add parts encTimestamp)
          _ (.add parts encBody)
          _ (.setParts builder parts)

          _ (.setUserInfo builder "myusername" "mypassword")

          signedDoc (.build builder createdDoc crypto secHeader)

          secHeaderElement (.getSecurityHeader secHeader)
          timestampNode (.. secHeaderElement (getElementsByTagNameNS WSConstants/WSU_NS "Timestamp") (item 0))
          _ (.setAttributeNS (cast Element timestampNode) WSConstants/XMLNS_NS "xmlns" WSConstants/WSU_NS)

          wss (XMLUtils/PrettyDocumentToString signedDoc)]

      wss))


图3

最佳答案

好的,在相邻的SO问题WSS4j elements order during signing SOAP message中找到了答案。

因此,这个用户在问一个不同的问题时,有一个代码示例可以满足我的需求。特别是对builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE)的调用。我喜欢StackOverflow :)

builder.setX509Certificate(signingCert);
builder.setUserInfo(alias, new String(passphrase));
builder.setUseSingleCertificate(true);
builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);

关于java - 如何更正SecurityTokenReference,使用WSS4J对SOAP进行签名,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23744513/

10-10 23:16