2012-09-20 112 views
7

Tôi đang cố gắng thực hiện một số Chữ ký XML bằng cách chỉ ký các phần của xml sau khi tìm kiếm nhiều, tôi không thể tìm được giải pháp.Cách chỉ đăng ký một phần cụ thể của XML

Tôi đang sử dụng java để ký một XML bằng cách sử dụng phép biến đổi Xpath2 và chuẩn hóa ĐỘC QUYỀN. Nếu tôi có XML sau

<?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> 

Và ký tên, tôi nhận được kết quả như sau (dữ liệu Bất động thay thế bằng hình nộm)

<?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> 

Nếu tôi xác nhận chữ ký, mọi thứ đều tốt tuy nhiên vấn đề ở đây là ngay sau đó, tôi thực hiện XSLT trong XML thực hiện một số thay đổi đối với một số phần tử chứ không phải phần tử đã ký (ns0:addr) còn nguyên vẹn. Mặc dù tôi nói rõ ràng rằng chỉ cần ký tên "addr", nếu tôi cố gắng thực hiện thay đổi đối với bất kỳ phụ huynh nào của nó (payload, msg hoặc addr), thì chữ ký sẽ không thành công khi (theo sự hiểu biết của tôi) . Nếu tôi thực hiện thay đổi đối với các yếu tố khác như bất kỳ nội dung nào bên trong tiêu đề, chữ ký vẫn hợp lệ.

Tôi đã thử nghiệm biểu thức XPath (//*[local-name()='addr']/*) và nó chọn dữ liệu chính xác sẽ được ký kết (ns2:data) nhưng nó dường như được tham gia cũng tất cả các yếu tố dẫn đến nó bắt đầu từ phần tử gốc (msg, addr).

Tôi cũng đã cố gắng sử dụng các biến đổi khác nhau chẳng hạn như UNION nhưng điều đó không hoạt động chút nào.

Có ai biết vấn đề có thể là gì không? Có cách nào, trong Java, để xem chính xác những gì đang được ký kết khi ký XML cho mục đích gỡ lỗi?

EDIT:

Việc chạy XSLT sau này sẽ được làm những việc như di chuyển không gian tên từ ns0: addr yếu tố để các phần tử gốc (msg) và cũng có thể nó sẽ được đổi tên thành phần chính và không gian tên từ msg để newmsg (và không gian tên mặc định khác) nhưng vẫn giữ nguyên dữ liệu đã ký (ns2:data).

Mã sử ​​dụng để đăng nó là nhiều hơn hoặc ít mã đề cập ở đây http://docs.oracle.com/javase/7/docs/technotes/guides/security/xmldsig/XMLDigitalSignature.html

Trừ thay vì một bao bọc transform Tôi đang sử dụng một XPATH2 transform:

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); 

Và cũng thay vì bao bọc tôi sử dụng ĐỘC QUYỀN

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

EDIT2:

tôi đã quản lý để cho phép gỡ lỗi tốt hơn trong quá trình ký kết xml và đã nhận như sau:

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>

Nó dường như được ký kết dữ liệu chính xác tuy nhiên nó cũng được bổ sung thêm một số không gian tên bổ sung cho các chữ ký mà làm cho tôi tự hỏi nếu đó là vấn đề vì các không gian tên đó được lấy từ các phần tử cha.

Bất kỳ ai biết cách làm cho nó không nhận được tất cả các không gian tên bổ sung được thêm vào?

+0

Có, bạn đang ký XML hoàn chỉnh (chỉ bằng cách xem ' '). Bạn có thể cho chúng tôi thấy mã bạn sử dụng để ký vào tài liệu XML không? – dusan

+0

Tôi sẽ cố gắng đặt một số mã sau khi tôi đang ở phía trước nó một lần nữa. Có 'uri =" "' tuy nhiên điều này là do sử dụng xpath thay vào đó để chọn nút nào được ký. Điều đó có đúng không? Ngoài ra nếu tôi thay đổi các nút bên trong khác như tiêu đề chữ ký vẫn còn hợp lệ mà dẫn tôi để tin rằng một cái gì đó đang làm việc chỉ không phải là cách nó nên được. – ByteFlinger

+0

Có vẻ ổn với tôi. Bạn có thể liệt kê XML của mình sau biến đổi xslt không? Ngoài ra, khi bạn nói bạn đã sửa đổi 'msg' hoặc' payload', bạn đã thêm một nút con hay đổi tên? – pd40

Trả lời

1

Sau nhiều cuộc chiến với Chữ ký XML, cuối cùng tôi đã đến một giải pháp có thể chấp nhận được (mặc dù không phải là lý tưởng).

Khi hóa ra một quy trình chuẩn hóa độc quyền là không đủ. Bạn cũng cần thêm một biến đổi Độc quyền sau tất cả các máy biến áp khác. Sau khi đoạn mã tôi đã viết ở trên:

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

Điều này sẽ làm cho nó để cho bất kỳ không gian tên khác ngoài các yếu tố ký sẽ không được đưa vào tính toán (mặc dù nó có tác dụng bổ sung mà chèn namespace (s) bên trong phần tử đã ký được cho phép). Ngoài ra có vẻ như bất kỳ phần tử nào trong đường dẫn đến phần tử đã ký sẽ được tính đến vì vậy nếu bạn có xpath /root/A/B thì nó sẽ ký thẻ B tuy nhiên bạn sẽ không thể thay đổi tên thẻ của A hoặc phần tử gốc.

Điều này có thể khắc phục bằng cách sử dụng đường cắt xén có ít phần tử hơn trong đó chẳng hạn như //B.

Tôi tin rằng có thể khắc phục được sự cố này mặc dù tôi chưa thể làm được.

0

Có các tham số, liên quan đến không gian tên, có thể được chuyển đến Exclusive XML Canonicalization mô tả InclusiveNamespaces PrefixList.

Bạn có thể thử chuyển một số ExcC14NParameterSpec đến newCanonicalizationMethod() bằng danh sách tiền tố để xem điều đó có ảnh hưởng đến việc chuẩn hóa không gian tên.

+1

Cảm ơn. Tôi đã thử sử dụng tính năng này: 'Danh sách prefixList = new ArrayList (); prefixList.add ("ns2"); C14NMethodParameterSpec c14NMethodParameterSpec = new ExcC14NParameterSpec (prefixList); canonicalisationMethod = xmlSigFactory.newCanonicalizationMethod (CanonicalizationMethod.EXCLUSIVE, c14NMethodParameterSpec); ' nhưng không có thay đổi nào xảy ra. Các signture dường như thay đổi tùy thuộc vào nếu tôi thêm tiền tố nhiều hơn hoặc ít hơn vào danh sách nhưng nó vẫn không cho phép tôi thay đổi các yếu tố trên những gì cần được ký kết. – ByteFlinger

Các vấn đề liên quan