簡體   English   中英

使用 X509 證書驗證 SOAP 請求

[英]Verify SOAP request using the X509 certificate

我有一個 SOAP 服務器。 在服務器上接收的 SOAP 請求具有ws 安全標頭 以下是請求 XML 的主要節點。

  1. BinarySecurityToken(X509PKIPathv1 證書)
  2. 消化法
  3. 摘要值
  4. 簽名值
  5. 安全令牌參考

  6. 數據(客戶端在 SOAP 主體中發送的數據)

我必須使用客戶端(請求的發送者)提供的證書(.cer 文件)來驗證請求。

驗證請求的步驟是什么? 請解釋這個概念。 沒有可用的庫來執行此操作。 經過長時間的研究,我能夠將BinarySecurityTokenbase64_encode($certFile) $certFile 是請求者的證書。 現在我正在研究如何將DigestValue與什么匹配。

WS-Security 標頭可以通過以下方式進行驗證。 我為此編寫了一個實用程序。 看看它。

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.StringReader;
import java.security.KeyStore;
import java.security.Provider;
import java.security.PublicKey;
import java.security.cert.X509Certificate;

import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;


public class WSUtil {
    public static void main(String[] args) throws Exception {

        String req = "SOAPMESSAGE";
        Document p = createXMLDocument(req);
        InputStream inStream = new FileInputStream("certificate.p12"); //Provide your certificate file

        KeyStore ks = KeyStore.getInstance("PKCS12");
        ks.load(inStream, "pass".toCharArray()); //Certificate password - pass

        String alias = ks.aliases().nextElement();
        X509Certificate certificate = (X509Certificate) ks.getCertificate(alias);

        validateSignature(p.getElementsByTagName("ds:Signature").item(0),p.getElementsByTagName("soapenv:Body").item(0),certificate.getPublicKey());//True if the message is valid
    }

    public static Document createXMLDocument(String xmlString) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        DocumentBuilder builder;
        Document document = null;
        try {
            builder = factory.newDocumentBuilder();
            document = builder.parse(new InputSource(
                    new StringReader(xmlString)));
        } catch (Exception e) {
            throw e;
        }
        return document;
    }

    private static boolean validateSignature(Node signatureNode, Node bodyTag, PublicKey publicKey) {
        boolean signatureIsValid = false;
        try {
            // Create a DOM XMLSignatureFactory that will be used to unmarshal the
            // document containing the XMLSignature
            String providerName = System.getProperty
                    ("jsr105Provider", "org.jcp.xml.dsig.internal.dom.XMLDSigRI");
            XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM",
                    (Provider) Class.forName(providerName).newInstance());

            // Create a DOMValidateContext and specify a KeyValue KeySelector
            // and document context
            DOMValidateContext valContext = new DOMValidateContext(new X509KeySelector(publicKey), signatureNode);
            valContext.setIdAttributeNS((Element) bodyTag, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "Id");

            // Unmarshal the XMLSignature.
            XMLSignature signature = fac.unmarshalXMLSignature(valContext);
            // Validate the XMLSignature.
            signatureIsValid = signature.validate(valContext); 

        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return signatureIsValid;
    }
}

注意您必須按原樣提供 SOAP 消息。 你不應該在某處做任何 XML 格式或任何空白。 添加了安全性的 SOAP 消息非常敏感。 即使末尾有空格也會使 SOAP 消息無效。

X509KeySelector 構造函數類型不正確

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM