2010-02-11 63 views
19

Tôi có một XML như thế nàyChữ ký XML: Cách tính giá trị thông báo?

<?xml version="1.0" encoding="utf-8"?> 
<foo> 
    <bar> 
    <value>A</value> 
    </bar> 
    <bar> 
    <value>B</value> 
    </bar> 
    <baz> 
    <value>C</value> 
    </baz><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /><DigestValue>WqpRWHxXA0YgH+p3Sxy6hRo1XIk=</DigestValue></Reference></SignedInfo><SignatureValue>EoRk/GhR4UA4D+8AzGPPkeim1dZrlSy88eF73n/T9Lpeq9IxoGRHNUA8FEwuDNJuz3IugC0n2RHQQpQajiYvhlY3XG+z742pgsdMfFE4Pddk4gF1T8CVS1rsF7bjX+FKT/c8B2/C8FNgmfkxDlB/ochtbRvuAGPQGtgJ3h/wjSg=</SignatureValue><KeyInfo><X509Data><X509Certificate>MIIB8zCCAVygAwIBAgIQgfzbrIjhLL9FobStI2ub3zANBgkqhkiG9w0BAQQFADATMREwDwYDVQQDEwhUZXN0ZUFjbjAeFw0wMDAxMDEwMDAwMDBaFw0zNjAxMDEwMDAwMDBaMBMxETAPBgNVBAMTCFRlc3RlQWNuMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDO+yAZ8/qJbhSVH/+2wMmzix3jM/CExb6sTgaiPwe6ylcHgF45zeQDq06OSJZCSns34em/ULINZddDf8z0b9uk/2sOGr1pYqsunLLBvw2FkvWJQDkhx2SzCm8v4xGX2kyXNbjiY/K56oPOMjpayKoAFnnvk7p2iFAxNZK/6lpZ7wIDAQABo0gwRjBEBgNVHQEEPTA7gBCOOHcajwnATYZ0t6w7LVU0oRUwEzERMA8GA1UEAxMIVGVzdGVBY26CEIH826yI4Sy/RaG0rSNrm98wDQYJKoZIhvcNAQEEBQADgYEABL9Qhi6f1Z+/t8oKXBQFx3UUsNF9N2o4k6q1c3CKZYqx2E/in+nARIYRdh5kbeLfomi6GIyVFeXExp8crob3MAzOQMvXf9+ByuezimMPIHDvv0u3kmmeITXfoZrHCDxLoWWlESN1owBfKPqe7JKAuu9ORDC0pUiUfCHWxCoqNos=</X509Certificate></X509Data></KeyInfo></Signature> 
</foo> 

Làm thế nào giá trị digest (WqpRWHxXA0YgH + p3Sxy6hRo1XIk =) trong tài liệu tham khảo được tạo ra? Tôi có nghĩa là làm thế nào tôi có thể tính toán giá trị này bằng tay?

+0

Tại sao bạn muốn để tính toán nó bằng tay? Đó sẽ là một quá trình tẻ nhạt và dễ bị lỗi. – HerbN

+0

Tôi đang sử dụng các chức năng .net để xác thực chữ ký. Nó trả về chữ ký không hợp lệ. Vì vậy, tôi muốn kiểm tra nó theo cách thủ công hoặc nếu có bất kỳ công cụ nào để kiểm tra chữ ký ... – user252816

+0

Tôi hiểu rằng bạn đã giải quyết lỗi "Xác minh thông báo không thành công cho tham chiếu"? nó sẽ có thể để có được một lời giải thích chi tiết về cách bạn trong thực tế đã làm nó? Tôi đang có vấn đề với một tin nhắn xà phòng đã ký bằng cách sử dụng Metro và một ứng dụng Net WCF sẽ không nhận ra giá trị Digest. –

Trả lời

-1

This tài liệu phải chứa cách tính giá trị thông báo.

Tôi hy vọng điều đó sẽ hữu ích!

2

Tôi đã gặp chính xác vấn đề này: Tôi đã tạo một chữ ký XML trong Java & xác thực trong .NET và việc xác thực luôn thất bại. Trong trường hợp của tôi nguyên nhân là chức năng 'in XML để tập tin' XMLWrite.m (có, trong MATLAB *) mà là 'khá in ấn' XML, chèn các tab, dấu cách và dòng mới khi nó thấy phù hợp. Vì đây là một phần của tài liệu, tự nhiên xác thực không thành công (nó cũng không thành công trong Java). Nhìn vào nguồn của bạn, điều này có thể xảy ra với bạn. Sử dụng Trình biến đổi (javax.xml.transform. *) Để tuần tự hóa DOM của bạn đúng cách mà không thay đổi nội dung.

* Bạn có biết rằng MATLAB cũng hiểu Java không? Bạn có thể chỉ cần gõ các câu lệnh Java vào bảng điều khiển thông dịch & chúng sẽ được thực hiện như mã m bản địa.

+2

Điều này đã được giải quyết bằng Chữ ký XML dựa trên XML Canonicalization. XML được chuẩn hóa trước và các khác biệt cú pháp (khoảng trắng, không gian tên, v.v.) sẽ được xử lý chính xác. – ewernli

+1

Đúng: nhưng đó là DOM, không phải là mã hóa của nó, đã được chuẩn hóa. Các ký tự khoảng trống thừa được chèn vào trong quá trình tuần tự hóa (thành tệp) SAU thông báo đã được tính toán, và chúng vẫn ở đó khi mã xác nhận đã tạo ra DOM của nó, đã chuẩn hóa nó và tính toán lại thông báo. Khoảng trắng là quan trọng trong các nút dữ liệu ký tự được phân tích cú pháp. – Max

16

Tôi đã xem qua câu hỏi này khi cố gắng tìm ra chính xác điều tương tự. Sau đó tôi đã tìm ra cách để làm điều đó, vì vậy tôi đã tìm ra câu trả lời ở đây.

Những điều cần xảy ra là:

  • canonicalization
  • tạo tiêu hóa giá trị, điển hình là SHA1 (nhưng có thể được SHA256 giữa những người khác)
  • base64 mã hóa nó

Các hợp quy một phần là khá đơn giản, như các thư viện Java đã làm điều đó cho tôi. Những gì tôi gặp khó khăn là bit tiếp theo, việc tạo ra các tiêu hóa, bởi vì tôi đã thực hiện một lỗi nghiêm trọng trong đó tiêu hóa SHA1 tôi tạo ra là SHA1 ở dạng HEX. SHA1 là 160 bit, vì vậy 20 byte, nhưng nếu bạn xuất ra 160 bit này trong HEX, bạn nhận được 40 ký tự. Nếu sau đó bạn mã hóa base64, bạn nhận được hoàn toàn sai giá trị so với những gì phải ở trong DigestValue.

Thay vào đó, bạn nên tạo mã hóa tiêu hóa SHA1 và base64 với đầu ra 20 byte. Đừng cố gắng xuất ra 20 byte thành STDOUT vì nó rất khó đọc được (đó là lý do tại sao mọi người thường xuất tương đương HEX, vì nó có thể đọc được). Thay vào đó, chỉ base64 mã hóa 20 byte và đó là DigestValue của bạn.

+0

Tôi nghĩ như vậy, nhưng tôi nhận được giá trị khác nhau cũng như thế. Bạn đã tiêu hóa trực tiếp Canonicalization Bytes hoặc byte chuỗi được phân tích chưa? –

+0

SHA1 tiêu hóa cái gì? – lonelyloner

0

là rất đơn giản, sử dụng openssl trong giao diện điều khiển:

openssl dgst tập tin -sha1 -binary | openssl enc -base64

Xong

+0

OP không chỉ định 'thủ công' là 'lập trình'. Đây là cách tốt để kiểm tra. – Vbakke

0

Đây là một giải pháp JAVA đòi hỏi các lọ sau:

  • commons-logging-1.2.jar
  • commons-codec-1.6.jar
  • Saxon-HE-9.4.jar
  • xmlsec-1.3.0.jar

giải pháp này sử dụng http://www.w3.org/2001/10/xml-exc-c14n# như các thuật toán chuẩn hoá, và sử dụng SHA256 như các thuật toán băm và mã hóa base64.

Lưu ý: document đại diện cho tài liệu XML làm đối tượng DOM trong JAVA.

mẫu Mã số:

 // create the transformer in order to transform the document from 
     // DOM Source as a JAVA document class, into a character stream (StreamResult) of 
     // type String writer, in order to be converted to a string later on 
     TransformerFactory tf = new net.sf.saxon.TransformerFactoryImpl(); 
     Transformer transformer = tf.newTransformer(); 
     transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
     transformer.setOutputProperty(OutputKeys.METHOD, "xml"); 
     transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); 

     // create the string writer and transform the document to a character stream 
     StringWriter sw = new StringWriter(); 
     transformer.transform(new DOMSource(document), new StreamResult(sw)); 

     String documentAsString = sw.toString(); 

     // initialize the XML security object, which is necessary to run the apache canonicalization 
     com.sun.org.apache.xml.internal.security.Init.init(); 

     // canonicalize the document to a byte array and convert it to string 
     Canonicalizer canon = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); 
     byte canonXmlBytes[] = canon.canonicalize(documentAsString.getBytes()); 
     String canonXmlString = new String(canonXmlBytes); 

     // get instance of the message digest based on the SHA-256 hashing algorithm 
     MessageDigest digest = MessageDigest.getInstance("SHA-256"); 

     // call the digest method passing the byte stream on the text, this directly updates the message 
     // being digested and perform the hashing 
     byte[] hash = digest.digest(canonXmlString.getBytes(StandardCharsets.UTF_8)); 

     // encode the endresult byte hash 
     byte[] encodedBytes = Base64.encodeBase64(hash); 

     return new String(encodedBytes); 
Các vấn đề liên quan