Java 为特定XML元素/节点创建数字签名时出现引用URI错误

Java 为特定XML元素/节点创建数字签名时出现引用URI错误,java,digital-signature,Java,Digital Signature,我一直在努力让它发挥作用,但我总是遇到一个例外 当我试图创建一个数字dignature为我的 XML文档。源文档是SOAP信封和程序 解析文件中的数据并创建文档对象。 基本上我想做的是用 多个部分/引用…主要是SOAP主体和时间戳 SOAP头的安全节点下的节点。所以现在我是 正在尝试对SOAP消息的正文部分进行签名。皂体有一个 wsu:Id值,我在创建引用对象时使用它。 我使用securityNode引用插入签名节点 因为这是它应该在的地方。我不认为这是个问题 但我想我会说出来以防万一。我想我正

我一直在努力让它发挥作用,但我总是遇到一个例外 当我试图创建一个数字dignature为我的 XML文档。源文档是SOAP信封和程序 解析文件中的数据并创建文档对象。 基本上我想做的是用 多个部分/引用…主要是SOAP主体和时间戳 SOAP头的安全节点下的节点。所以现在我是 正在尝试对SOAP消息的正文部分进行签名。皂体有一个 wsu:Id值,我在创建引用对象时使用它。 我使用securityNode引用插入签名节点 因为这是它应该在的地方。我不认为这是个问题 但我想我会说出来以防万一。我想我正在这样做 对,但它不起作用。我看到其他人发布了同样的问题 但没有人回答

我已经尝试了很多不同的方法,只要我指定URI 为了创建引用对象,我得到了一个异常。怪人 问题是,异常是在签名时抛出的 上下文我这样做对吗?我如何纠正这个问题?任何帮助都是无效的 非常感谢

//异常

线程“main”中出现异常 javax.xml.crypto.dsig.XMLSignatureException: javax.xml.crypto.URIReferenceException:java.lang.NullPointerException 位于org.jcp.xml.dsig.internal.dom.DOMReference.dereference(未知源) 位于org.jcp.xml.dsig.internal.dom.DOMReference.digest(未知源) 位于org.jcp.xml.dsig.internal.dom.DOMXMLSignature.digestReference(未知 (来源) 位于org.jcp.xml.dsig.internal.dom.DOMXMLSignature.sign(未知源) 在XMLDsigTester.main(XMLDsigTester.java:163)处,由以下原因引起:javax.xml.crypto.URIReferenceException:java.lang.NullPointerException 位于org.jcp.xml.dsig.internal.dom.domuridereference.dereference(未知 (来源) ... 还有5个原因:java.lang.NullPointerException 位于com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverDirectHTTP.engineCanResolve(未知 (来源) 位于com.sun.org.apache.xml.internal.security.utils.resolver.resourcesolver.canResolve(未知 (来源) 位于com.sun.org.apache.xml.internal.security.utils.resolver.resourcesolver.getInstance(未知 (来源) ... 6更多javax.xml.crypto.URIReferenceException:java.lang.NullPointerException 位于org.jcp.xml.dsig.internal.dom.domuridereference.dereference(未知 (来源) 位于org.jcp.xml.dsig.internal.dom.DOMReference.dereference(未知源) 位于org.jcp.xml.dsig.internal.dom.DOMReference.digest(未知源) 位于org.jcp.xml.dsig.internal.dom.DOMXMLSignature.digestReference(未知 (来源) 位于org.jcp.xml.dsig.internal.dom.DOMXMLSignature.sign(未知源) 在XMLDsigTester.main(XMLDsigTester.java:163)处,由以下原因引起:java.lang.NullPointerException 位于com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverDirectHTTP.engineCanResolve(未知 (来源) 位于com.sun.org.apache.xml.internal.security.utils.resolver.resourcesolver.canResolve(未知 (来源) 位于com.sun.org.apache.xml.internal.security.utils.resolver.resourcesolver.getInstance(未知 (来源) ... 还有6个

/******************JAVA类********************
导入javax.xml.crypto.*;
导入javax.xml.crypto.dsig.*;
导入javax.xml.crypto.dom.*;
导入javax.xml.crypto.dsig.dom.DOMSignContext;
导入javax.xml.crypto.dsig.keyinfo.*;
导入javax.xml.crypto.dsig.spec.TransformParameterSpec;
导入javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
导入java.io.FileInputStream;
导入java.io.FileOutputStream;
导入java.io.OutputStream;
导入java.security.*;
导入java.util.Collections;
导入java.util.Iterator;
导入javax.xml.parsers.DocumentBuilderFactory;
导入javax.xml.transform.*;
导入javax.xml.transform.dom.DOMSource;
导入javax.xml.transform.stream.StreamResult;
导入org.w3c.dom.Document;
导入org.w3c.dom.*;
公共类XMLDsigTester
{
公共静态void main(字符串[]args)引发异常
{
//////////////声明//////////////////
最终字符串信封\u TAG=“信封”;
最终字符串标题\u TAG=“HEADER”;
最终字符串SECURITY\u TAG=“SECURITY”;
最终字符串正文\u TAG=“正文”;
最终字符串分隔符=“:”;
节点envelopeNode=null;
节点头节点=null;
Node bodyNode=null;
节点列表envelopeChildren=null;
NodeList headerChildren=null;
Node-childNode=null;
节点securityNode=null;
字符串providerName=null;
字符串senevelopenamespace=null;
字符串sFullHeaderTagName=null;
字符串sFullBodyTagName=null;
字符串sNodeName=null;
国际发展儿童;
国际领袖儿童;
//////////////逻辑起点//////////////////
providerName=System.getProperty(“jsr105Provider”、“org.jcp.xml.dsig.internal.dom.XMLDSigRI”);
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc=dbf.newDocumentBuilder().parse(新文件输入流(“myfile.xml”);
Provider providerObj=(Provider)Class.forName(providerName).newInstance();
///创建对信封、标题、正文和安全节点的引用///
envelopeNode=doc.getDocumentElement();
envelopeChildren=envelopeNode.getChildNodes();
IEEnvelopeChildren=envelopeChildren.getLength();
senvelopleNamespace=envelopeNode.getPrefix();
如果(senvelopleNamespace!=null&&!senvelopleNamespace.trim().equals(“”)
  //********************   JAVA CLass  ********************



    import javax.xml.crypto.*;
    import javax.xml.crypto.dsig.*;
    import javax.xml.crypto.dom.*;
    import javax.xml.crypto.dsig.dom.DOMSignContext;
    import javax.xml.crypto.dsig.keyinfo.*;
    import javax.xml.crypto.dsig.spec.TransformParameterSpec;
    import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.OutputStream;
    import java.security.*;
    import java.util.Collections;
    import java.util.Iterator;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.transform.*;
    import javax.xml.transform.dom.DOMSource;
    import javax.xml.transform.stream.StreamResult;
    import org.w3c.dom.Document;
    import org.w3c.dom.*;

    public class XMLDsigTester
    {

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

    //////////////          DECLARATIONS      //////////////////

    final String ENVELOPE_TAG = "Envelope";
    final String HEADER_TAG = "Header";
    final String SECURITY_TAG = "Security";
    final String BODY_TAG = "Body";
    final String SEPARATOR = ":";

    Node envelopeNode = null;
    Node headerNode = null;
    Node bodyNode = null;

    NodeList envelopeChildren = null;
    NodeList headerChildren = null;
    Node childNode = null;
    Node securityNode = null;

    String providerName = null;
    String sEnvelopeNamespace = null;
    String sFullHeaderTagName = null;
    String sFullBodyTagName = null;
    String sNodeName = null;

    int iEnvelopeChildren;
    int iHeaderChildren;

    //////////////          START OF LOGIC      //////////////////

    providerName = System.getProperty("jsr105Provider", "org.jcp.xml.dsig.internal.dom.XMLDSigRI");

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    Document doc = dbf.newDocumentBuilder().parse(new FileInputStream("myfile.xml"));

    Provider providerObj = (Provider) Class.forName(providerName).newInstance();

    ///  Create references to the Envelope, Header, Body and Security nodes  ///

    envelopeNode = doc.getDocumentElement();
    envelopeChildren = envelopeNode.getChildNodes();
    iEnvelopeChildren = envelopeChildren.getLength();

    sEnvelopeNamespace = envelopeNode.getPrefix();
    if (sEnvelopeNamespace != null && !sEnvelopeNamespace.trim().equals(""))
    {
    sFullHeaderTagName = sEnvelopeNamespace.trim().concat(SEPARATOR).concat(HEADER_TAG);
    sFullBodyTagName = sEnvelopeNamespace.trim().concat(SEPARATOR).concat(BODY_TAG);
    }
    else
    {
    sFullHeaderTagName = HEADER_TAG;
    sFullBodyTagName = BODY_TAG;
    }

    for (int i=0; i < iEnvelopeChildren; i++)
    {
    sNodeName = null;
    childNode = null;

    childNode = envelopeChildren.item(i);
    sNodeName = childNode.getNodeName().trim();

    if (sNodeName.equalsIgnoreCase(sFullHeaderTagName))
    headerNode = childNode;
    else if (sNodeName.equalsIgnoreCase(sFullBodyTagName))
    bodyNode = childNode;
    }

    headerChildren = headerNode.getChildNodes();
    iHeaderChildren = headerChildren.getLength();

    String sLocalNodeName = null;
    for (int i=0; i < iHeaderChildren; i++)
    {
    sLocalNodeName = null;
    sNodeName = null;
    childNode = null;

    childNode = headerChildren.item(i);
    sNodeName = childNode.getNodeName().trim();

    sLocalNodeName = childNode.getLocalName();

    if (sLocalNodeName != null)
    if (sLocalNodeName.trim().equalsIgnoreCase(SECURITY_TAG))
    {
    securityNode = childNode;
    break;
    }
    }

    ///  Main logic for generating XML signature  ///

    XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM", providerObj);

    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
    kpg.initialize(512);
    KeyPair kp = kpg.generateKeyPair();

    KeyInfoFactory kif = fac.getKeyInfoFactory();
    KeyValue kv = kif.newKeyValue(kp.getPublic());

    KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv));


    DOMSignContext dsc = new DOMSignContext(kp.getPrivate(), securityNode);
    dsc.putNamespacePrefix("http://www.w3.org/2000/09/xmldsig#", "ds");


    DigestMethod digestMethod = fac.newDigestMethod(DigestMethod.SHA1, null);
    Transform transformObj = fac.newTransform(CanonicalizationMethod.EXCLUSIVE, (TransformParameterSpec) null);

    Reference ref = fac.newReference("part-Body-4F4332715C4C1670E10080000A441E26", digestMethod, Collections.singletonList(transformObj), null, null);

    CanonicalizationMethod canonMethodObj = fac.newCanonicalizationMethod(CanonicalizationMethod.EXCLUSIVE, (C14NMethodParameterSpec) null);
    SignatureMethod signatureMethodObj = fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null);
    SignedInfo si = fac.newSignedInfo(canonMethodObj, signatureMethodObj, Collections.singletonList(ref));

    XMLSignature signature = fac.newXMLSignature(si, ki);
    signature.sign(dsc);

    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer trans = tf.newTransformer();
    trans.transform(new DOMSource(doc), new StreamResult(new FileOutputStream("mySignedFile.xml")));
    }
    } <br>

    //********************   INPUT DATA  ********************

    <soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
       <soap-env:Header>
          <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">
             <wsu:Timestamp wsu:Id="ts-4F43326F5C4C1670E10080000A441E26">
                <wsu:Created>2012-09-30T22:09:55Z</wsu:Created>
                <wsu:Expires>2012-09-30T22:14:55Z</wsu:Expires>
             </wsu:Timestamp>
          </wsse:Security>
          <wsa:Action soap-env:mustUnderstand="1" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"/>
          <wsa:MessageID xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">uuid:4f43f2ff-38aa-1a90-e100-80000a441e26</wsa:MessageID>
       </soap-env:Header>
       <soap-env:Body wsu:Id="part-Body-4F4332715C4C1670E10080000A441E26" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
           <PurchaseOrder>
             <Customer>
               <Name>Robert Smith</Name>
               <CustomerId>788335</CustomerId>
             </Customer>
             <Item partNum="C763">
               <ProductId>6883-JF3</ProductId>
               <Quantity>3</Quantity>
               <ShipDate>2002-09-03</ShipDate>
               <Name>ThinkPad X20</Name>
             </Item>
           </PurchaseOrder>
       </soap-env:Body>
    </soap-env:Envelope>
Transform transformObj = fac.newTransform(CanonicalizationMethod.EXCLUSIVE, (TransformParameterSpec) null);

Reference ref = fac.newReference("part-Body-4F4332715C4C1670E10080000A441E26", digestMethod, Collections.singletonList(transformObj), null, null);
List<Transform> transforms = new ArrayList<Transform>(2);
Map<String, String> namespaces = new HashMap<String, String>(1);
namespaces.put("soap-env", "http://schemas.xmlsoap.org/soap/envelope/");
XPathFilterParameterSpec paramsXpath = new XPathFilterParameterSpec("/soap-env:Envelope/soap-env:Body", namespaces);
transforms.add(fac.newTransform(Transform.XPATH, (TransformParameterSpec) paramsXpath));

Transform transformObj = fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null);
transforms.add(transformObj);

Reference ref = fac.newReference("", digestMethod, transforms, null, null);