2012-09-20 15 views
7

के केवल विशिष्ट भाग पर हस्ताक्षर कैसे करें मैं एक्सएमएल के केवल हिस्सों पर हस्ताक्षर करके कुछ एक्सएमएल हस्ताक्षर करने की कोशिश कर रहा हूं हालांकि बहुत अधिक खोज के बाद मैं समाधान ढूंढने में सक्षम नहीं हूं।एक्सएमएल

मैं एक्सपीएथ 2 ट्रांसफॉर्म और अनन्य कैनोलिकलाइजेशन का उपयोग कर एक्सएमएल पर हस्ताक्षर करने के लिए जावा का उपयोग कर रहा हूं। अगर मैं निम्न XML

<?xml version="1.0" encoding="UTF-8"?> 
<msg xmlns="http://someaddress/ad/m1" xmlns:ns1="http://someotheraddres/ad/m2" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#"> 
<header> 
    <id>wsfrwerwerwer</id> 
    <name>addr</name> 
    <somenode> 
     <trace>ND</trace> 
    </somenode> 
</header> 
<payload><ns0:addr xmlns:ns0="http://someaddres/ad/m3"><ns2:data xmlns:ns2="http://someaddres/ad/m3"> 
      <ns2:name>somevalue</ns2:name> 
      <ns2:value>354</ns2:value> 
     </ns2:data> 
    </ns0:addr> 
</payload> 
</msg> 

है और इस पर हस्ताक्षर, मैं निम्नलिखित उत्पादन (रियल डेटा डमी के साथ प्रतिस्थापित)

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<msg xmlns="http://someaddress/ad/m1" xmlns:ns1="http://someotheraddres/ad/m2" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#"> 
<header> 
    <id>wsfrwerwerwer</id> 
    <name>addr</name> 
    <somenode> 
     <trace>ND</trace> 
    </somenode> 
</header> 
<payload> 
    <ns0:addr xmlns:ns0="http://someaddres/ad/m3"> 
     <ns2:data xmlns:ns2="http://someaddres/ad/m3"> 
      <ns2:name>somevalue</ns2:name> 
      <ns2:value>354</ns2:value> 
     </ns2:data> 
    </ns0:addr> 
    <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> 
     <SignedInfo> 
      <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> 
      <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/> 
      <Reference URI=""> 
       <Transforms> 
        <Transform Algorithm="http://www.w3.org/2002/06/xmldsig-filter2"> 
         <XPath xmlns="http://www.w3.org/2002/06/xmldsig-filter2" xmlns:ns0="http://someaddres/ad/m3" Filter="intersect">//*[local-name()='addr']/*</XPath> 
        </Transform> 
       </Transforms> 
       <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> 
       <DigestValue>sdlfjdeklsdfngf</DigestValue> 
      </Reference> 
     </SignedInfo> 
     <SignatureValue>femhjgklnlkl</SignatureValue> 
     <KeyInfo> 
      <X509Data> 
       <X509Certificate>swerwerwrwerwerwe</X509Certificate> 
      </X509Data> 
     </KeyInfo> 
    </Signature> 
</payload> 
</msg> 

अगर मैं हस्ताक्षर मान्य, सब कुछ ठीक है लेकिन यहां मुद्दा यह है मिल इसके ठीक बाद मैं एक्सएमएल में एक एक्सएसएलटी करता हूं जो कुछ तत्वों में कुछ बदलाव करता है लेकिन हस्ताक्षरित तत्व नहीं (ns0:addr) जो बरकरार रहता है। भले ही मैं स्पष्ट रूप से कहूं कि केवल "addr" तत्व पर हस्ताक्षर किए जाने चाहिए, अगर मैं अपने किसी भी माता-पिता (payload, msg या addr) में परिवर्तन करने का प्रयास करता हूं, तो यह हस्ताक्षर विफल हो जाता है जब (मेरी समझ के अनुसार) यह नहीं होना चाहिए । यदि मैं हेडर के अंदर कुछ भी तत्वों में परिवर्तन करता हूं, तो हस्ताक्षर अभी भी मान्य है।

मैं XPath अभिव्यक्ति (//*[local-name()='addr']/*) का परीक्षण किया है और यह चयन करता है सही डेटा हस्ताक्षर किए जाने (ns2:data) लेकिन यह भी मूल तत्व (msg, addr) से शुरू यह करने के लिए अग्रणी सभी तत्वों को लग रहा है।

मैंने यूनियन जैसे विभिन्न परिवर्तनों का उपयोग करने की भी कोशिश की है लेकिन यह बिल्कुल काम नहीं करता है।

क्या कोई जानता है कि समस्या क्या हो सकती है? क्या जावा में कोई तरीका है, यह देखने के लिए कि डीबगिंग उद्देश्यों के लिए एक्सएमएल पर हस्ताक्षर करते समय क्या हस्ताक्षर किया जा रहा है?

संपादित करें:

xslt रन बाद में ns0 से नामस्थान चलती तरह बातें कर रही होगी: मूल तत्व (एमएसजी) के लिए addr तत्व है और यह भी यह newmsg के संदेश से मुख्य तत्व नाम और नाम स्थान बदल जाएगी (और एक अलग डिफ़ॉल्ट नामस्थान) लेकिन हस्ताक्षरित डेटा (ns2:data) बरकरार छोड़कर।

बदलने मैं एक XPATH2 उपयोग कर रहा हूँ बदलने अधिक या एक छा के बजाय छोड़कर यहाँ http://docs.oracle.com/javase/7/docs/technotes/guides/security/xmldsig/XMLDigitalSignature.html

उल्लेख कोड कम है पर हस्ताक्षर करने के लिए इस्तेमाल कोड:

Map<String, String> namespaceMap = new HashMap<String, String>(0); 
namespaceMap.put("ns0", "http://someaddres/ad/m3"); 
XPathType xPathType = new XPathType(xPathParameters, Filter.INTERSECT, namespaceMap); 
List<XPathType> xPathList = new ArrayList<XPathType>(0); 
xPathList.add(xPathType) 
XPathFilter2ParameterSpec xPathFilter2ParameterSpec = new XPathFilter2ParameterSpec(xPathList); 
transform = fac.newTransform(CanonicalizationMethod.XPATH2, xPathFilter2ParameterSpec); 

और यह भी छा के बजाय मैं कर रहा हूँ का उपयोग करते हुए विशेष

canonicalisationMethod = fac.newCanonicalizationMethod(CanonicalizationMethod.EXCLUSIVE, (C14NMethodParameterSpec) null); 

EDIT2:

मैं एक्सएमएल हस्ताक्षर किए जाने की प्रक्रिया के महीन डिबगिंग को सक्षम करने में कामयाब रहे और निम्नलिखित मिल गया है:

FINER: Pre-digested input: 21-Sep-2012 10:51:39 org.jcp.xml.dsig.internal.DigesterOutputStream write FINER: <ns2:data xmlns="http://someaddress/ad/m1" xmlns:ns0="http://someaddres/ad/m3" xmlns:ns1="http://someotheraddres/ad/m2" xmlns:ns2="http://someaddres/ad/m3"> <ns2:name>somevalue</ns2:name> <ns2:value>354</ns2:value> </ns2:data>

हालांकि यह भी हस्ताक्षर जो बनाता है मुझे आश्चर्य है कुछ अतिरिक्त नामस्थान जोड़ रहा है सही डेटा पर हस्ताक्षर किया जा रहा है यदि यह मुद्दा है क्योंकि उन नम्सस्पेस को मूल तत्वों से लिया जाता है।

कोई भी जानता है कि इसे सभी अतिरिक्त नामस्थान कैसे नहीं मिलते हैं?

+0

हां, आप पूर्ण एक्सएमएल पर हस्ताक्षर कर रहे हैं (बस '<संदर्भ यूआरआई = ""> '' देखकर)। क्या आप हमें वह कोड दिखा सकते हैं जिसका उपयोग आप XML दस्तावेज़ पर हस्ताक्षर करने के लिए करते हैं? – dusan

+0

एक बार बाद में मैं इसके सामने एक कोड डालने की कोशिश करूंगा। हां 'uri = "" हालांकि यह चुनने के लिए कि कौन सा नोड हस्ताक्षरित है, xpath का उपयोग करने के कारण यह है। क्या यह मामला नहीं होना चाहिए? इसके अलावा यदि मैं हेडर जैसे अन्य आंतरिक नोड्स को बदलता हूं तो हस्ताक्षर अभी भी मान्य है जो मुझे विश्वास दिलाता है कि कुछ ऐसा काम नहीं कर रहा है जिस तरह से होना चाहिए। – ByteFlinger

+0

यह मेरे लिए ठीक लग रहा है। क्या आप xslt ट्रांसफॉर्म के बाद अपने एक्सएमएल को सूचीबद्ध कर सकते हैं? साथ ही, जब आप कहते हैं कि आपने 'msg' या' पेलोड 'संशोधित किया है, तो क्या आपने कोई बच्चा नोड जोड़ा है या नाम बदलना है? – pd40

उत्तर

1

एक्सएमएल हस्ताक्षर के साथ बहुत लड़ने के बाद मैं अंत में एक स्वीकार्य समाधान (हालांकि आदर्श नहीं) पर पहुंचा।

जैसा कि यह पता चला है कि एक विशेष कैनोनिकललाइजेशन पर्याप्त नहीं है। आपको अन्य सभी ट्रांसफार्मर के बाद एक एक्सक्लूसिव ट्रांसफॉर्म भी जोड़ना होगा। कोड के टुकड़े मैंने ऊपर लिखा था के बाद:

List<Transform> transforms = new ArrayList<Transform>() 
transforms.add(transform) 
fac.newTransform(CanonicalizationMethod.EXCLUSIVE, (TransformParameterSpec) null) 

यह कर देगा ताकि हस्ताक्षर किए तत्वों के बाहर किसी अन्य नामस्थान को ध्यान में नहीं ले जाया जाएगा (हालांकि यह जोड़ा प्रभाव है कि अंदर नाम स्थान (रों) डालने है हस्ताक्षरित तत्व की अनुमति है)।

यह भी लगता है कि हस्ताक्षरित तत्व के लिए xpath में कोई भी तत्व ध्यान में रखा जाएगा, इसलिए यदि आपके पास निम्न xpath /root/A/B है तो यह टैग बी पर हस्ताक्षर करेगा हालांकि आप या तो ए या टैग टैग को बदलने में सक्षम नहीं होंगे जड़ तत्व

इसे //B जैसे कम तत्वों वाले एक्सपैथ का उपयोग करके दूर किया जा सकता है।

मेरा मानना ​​है कि इस मुद्दे को दूर करना संभव हो सकता है, हालांकि अब तक मैं सक्षम नहीं हूं।

0

नामस्थान से संबंधित पैरामीटर हैं, जिन्हें Exclusive XML Canonicalization पर InclusiveNamespaces PrefixList का वर्णन किया जा सकता है।

आप एक ExcC14NParameterSpecको newCanonicalizationMethod() गुजर एक उपसर्ग सूची का उपयोग कर देखने के लिए कि अगर नामस्थान के कैनॉनिकलाइज़ेशन को प्रभावित करता है की कोशिश कर सकते।

+1

धन्यवाद। मैंने इसका उपयोग करने का प्रयास किया है: 'सूची उपसर्ग सूची = नया ArrayList (); prefixList.add ("ns2"); C14NMethodParameterSpec c14NMethodParameterSpec = नया ExcC14NParameterSpec (उपसर्ग सूची); canonicalisationMethod = xmlSigFactory.newCanonicalizationMethod (CanonicalizationMethod.EXCLUSIVE, c14NMethodParameterSpec); ' लेकिन कोई परिवर्तन नहीं हुआ। अगर मैं सूची में कम या ज्यादा उपसर्ग जोड़ता हूं, तो यह संकेत बदलता प्रतीत होता है कि यह अभी भी उन तत्वों को बदलने की अनुमति नहीं देता है जिन्हें हस्ताक्षर किया जाना चाहिए। – ByteFlinger