# XML簽章筆記 原文:[Programming With the Java XML Digital Signature API](https://www.oracle.com/technical-resources/articles/java/dig-signature-api.html) > 其實大部分是邊讀邊翻譯而已,並擷取大部分我需要的東西,怕缺漏也可以讀原文就好,這不是什麼精華文章,啊有寫錯記得跟我講。 # 正文 原文是要介紹Java XML Digital Signature API,此API是用來產生及驗證XML簽章(但我不會Java所以不介紹),也會大致介紹XML簽章的內容物。 XML簽章是種製作XML資料的數位簽章的規範,你可以透過該簽章來驗證及用來保護XML資料的完整性及網路交易。 # XML簽章內容總覽 [在RFC2828](http://www.ietf.org/rfc/rfc2828.txt)中定義數位簽章是 > 資料物件與附帶一個使用密碼學演算法計算出的值,而任何接收者能使用該簽章來驗證資料的原始值及完整性。 XML簽章是一個包含數個key屬性的數位簽章,它定義製作XML簽章的流程及格式。且還擁有許多額外的功能,例如你可以簽署多於一段的二進制或XML資料,且可以使用各種底層的加密演算法。 XML簽章可以簽署任意XML或者二進制的文件,甚至可以透過URIs(Uniform Resource Identifiers)只簽署一部份或是一個子區塊的XML文件。 通常XML簽章會被敘述為符合1~3種種類: * Detached signature:用於對包含該簽名的XML文檔之外的資源簽名 * Enveloped signature:用於對包含它的XML文檔的某個部分進行簽名 * Enveloping signature:XML簽名包含被簽名的數據 下方範例為Enveloped signature類的XML文件,並分段落來講解: ```xml= <?xml version="1.0" encoding="UTF-8"?> <PurchaseOrder> <Item number="130046593231"> <Description>Video Game</Description> <Price>10.29</Price> </Item> <Buyer id="8492340"> <Name>My Name</Name> <Address> <Street>One Network Drive</Street> <Town>Burlington</Town> <State>MA</State> <Country>United States</Country> <PostalCode>01803</PostalCode> </Address> </Buyer> </PurchaseOrder> ``` 最開始為簽署前的訂單內容,而經過簽章後會變成下方範例: ```xml= <?xml version="1.0" encoding="UTF-8"?> <PurchaseOrder> <Item number="130046593231"> <Description>Video Game</Description> <Price>10.29</Price> </Item> <Buyer id="8492340"> <Name>My Name</Name> <Address> <Street>One Network Drive</Street> <Town>Burlington</Town> <State>MA</State> <Country>United States</Country> <PostalCode>01803</PostalCode> </Address> </Buyer> <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"/> </Transforms> <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <DigestValue>tVicGh6V+8cHbVYFIU91o5+L3OQ=</DigestValue> </Reference> </SignedInfo> <SignatureValue> dJDHiGQMaKN8iPuWApAL57eVnxz2BQtyujwfPSgE7HyKoxYtoRB97ocxZ 8ZU440wHtE39ZwRGIjvwor3WfURxnIgnI1CChMXXwoGpHH//Zc0z4ejaz DuCNEq4Mm4OUVTiEVuwcWAOMkfDHaM82awYQiOGcwMbZe38UX0oPJ2DOE= </SignatureValue> <KeyInfo> <X509Data> <X509SubjectName> CN=My Name,O=Test Certificates Inc.,C=US </X509SubjectName> <X509Certificate> MIIB9zCCAWCgAwIBAgIERZwdkzANBgkqhkiG9w0BAQUFADBAMQswCQYD VQQGEwJVUzEfMB0GA1UEChMWVGVzdCBDZXJ0aWZpY2F0ZXMgSW5jLjEQ MA4GA1UEAxMHTXkgTmFtZTAeFw0wNzAxMDMyMTE4MTFaFw0zMTA4MjUy ... </X509Certificate> </X509Data> </KeyInfo> </Signature> </PurchaseOrder> ``` 這邊可以看到簽章中有個`Signature`元素(line 17~50),從而表示這是份已經被封裝過的簽章。而接下來要介紹`SignedInfo`元素(line 18~31),這是用來表示簽章的資訊: ```xml= <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"/> </Transforms> <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <DigestValue>tVicGh6V+8cHbVYFIU91o5+L3OQ=</DigestValue> </Reference> </SignedInfo> ``` * `CanonicalizationMethod`元素 - 用來規範`SignedInfo`元素的演算法的URI。*Canonicalization* 是用來將XML內容轉換為物理上的表示法的流程,也稱為規範形式(*canonical form*),是用來消除可能使簽章無效的微小變化。因為XML的性質以及不同處理器、中介者解析的方始可能造成其中資料更動,進而導致簽章失效,儘管已簽章的資料邏輯上還是相等的。*Canonicalization* 可以透過在製作/驗證簽章前將XML資料轉換為規範形式,來消除這些合法的句法變動。 * `SignatureMethod`元素 - 用來產生簽章的數位簽章演算法的URI,例如範例中使用*PKCS#1 RSA-SHA1*。 * `Reference`元素 - 一份簽章可能有數個`Reference`元素,各個元素透過URI來證明資料已經被簽署過。範例中有一個`Reference`元素,範例中的URI為空值,表示的是文件的root,也就是整份文件;URIs也可以指向額外的文件,例如`"http://java[dot]sun[dot]com"`,又或者指向自身段落,例如`"#purchaseOr * `Transforms`元素 - 為可自選的,其中包含一或多個`Transform`元素,各元素都會表示一個用來摘要、簽章或驗證的演算法,例如範例中的元素就是用來封裝轉換的演算法,封裝轉換的動作對於封裝的簽章是必須的,由此`Signature`元素在計算簽章值實惠先被移除,否則簽章會錯誤地將該元素包含進待簽署的資料中。另外有個好用的演算法:[XPath Filter transform](http://www.w3.org/TR/xmldsig-filter2/),它可以讓你指名一個XPath表達式來選擇一個子區段加以簽署。 * `DigestMethod`元素 - 定義一個演算法URI,用來摘要資料,像範例中是使用SHA1。 * `DigestValue`元素 - 為摘要後再轉換為base64的值。 ```xml= <SignatureValue> dJDHiGQMaKN8iPuWApAL57eVnxz2BQtyujwfPSgE7HyKoxYtoRB97ocxZ 8ZU440wHtE39ZwRGIjvwor3WfURxnIgnI1CChMXXwoGpHH//Zc0z4ejaz DuCNEq4Mm4OUVTiEVuwcWAOMkfDHaM82awYQiOGcwMbZe38UX0oPJ2DOE= </SignatureValue> ``` * `SignatureValue`元素 - 為將整個`SignedInfo`元素轉換為base64的簽章 ```xml= <KeyInfo> <X509Data> <X509SubjectName>CN=My Name,O=Test Certificates Inc.,C=US</X509SubjectName> <X509Certificate> MIIB9zCCAWCgAwIBAgIERZwdkzANBgkqhkiG9w0BAQUFADBAMQswCQYD VQQGEwJVUzEfMB0GA1UEChMWVGVzdCBDZXJ0aWZpY2F0ZXMgSW5jLjEQ MA4GA1UEAxMHTXkgTmFtZTAeFw0wNzAxMDMyMTE4MTFaFw0zMTA4MjUy ... </X509Certificate> </X509Data> </KeyInfo> ``` * `KeyInfo`元素 - 為可自選的,其中包含需要用來驗證簽章的key。此元素中可以帶有多種內容,例如`X.509 certificates`、`Pretty Good Privacy (PGP) `,可以查看[KeyInfo](http://www.w3.org/TR/xmldsig-core/#sec-KeyInfo)章節來取得更多資訊。在此範例中該元素包含了`X509Data`元素,其中還有個`X509SubjectName`元素,是用來識別簽署者的 X.509憑證附屬的識別名稱,及`X509Certificate`中包含簽署者base64加密後的憑證,憑證中包含著用來驗證及簽章的公鑰。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up