作者:陳振寰 / 臺灣大學計算機及資訊網路中心程式設計組
XML已成時下最流行的語言,而以XML為基礎的XML簽章也在這樣的情況產生了。XML簽章提供多種簽章的方式,可充分支援組織簽呈之用。本文簡略了介紹有關於XML的外觀、種類以及簽章的流程,以期讀者能夠了解XML簽章的相關內容。
前言
傳統的簽章是以墨水式簽名或蓋章方式滲透到紙張文件上,以達到簽署者「不可否認」之目的;電子簽章則是要在「電子文件」上產生「電子印記」,亦達到簽署者「不可否認」的結果。依據行政院所頒佈之電子簽章法,對電子簽章與數位簽章的定義如下:「電子簽章—指依附於電子文件並與其相關連,用以辨識及確認電子文件簽署人身分、資格及電子文件真偽者;數位簽章—指將電子文件以數學演算法或其他方式運算為一定長度之數位資料,以簽署人之私密金鑰對其加密,形成電子簽章,並得以公開金鑰加以驗證者」[1]。
什麼是 XML 簽章
在我們進行電子簽章時,該如何進行簽章的動作,簽章完成之後要組成何種格式,都是屬於一個完整簽章的範疇(如RSA 的 PKCS#7 與 W3C 的 XML 簽章)。而 XML 簽章則是以 XML 格式呈現,並包含簽什麼、如何簽、到簽後組成怎樣的 XML 資料文件。
XML簽章格式
圖 1顯示了一個 XML 的標準格式,是一個以Signature為根的XML結構,其中包含了最重要的部分SignedInfo,定義了如何「圈選」要簽署的資料區塊,如何進行資料轉換與計算摘要,最後如何簽章的訊息,而SignatureValue則放置實際上簽章的簽章值。KeyInfo是描述與簽署此份文件的金鑰訊息。而Object則是一個活用的欄位,可以描述資料的來源或描述簽章其他相關訊息 SignatureProperty,如Time Stamp 等…。
圖1、XML 結構
XML 簽章的類型
XML簽章可以分成三種類型:Enveloping Signatures、Enveloped Signatures與Detached Signatures。 Enveloping Signatures與Enveloped Signatures資料是與簽章放置在同一個文件檔案。而Detached Signatures顧名思義就是簽章的內容與欲簽署的資料是放置在不同的文件檔案內。
圖 2、Enveloping Signatures
圖3、Enveloped Signatures
依據使用特性可能簽署的種類
• Full Signature:對一整份的文章進行簽署
• Partial Signature:只簽署部分的區塊
• Single Signature:一份文件中用一個XML簽章
• Multiple Signature:一份文件中有多個XML簽章
• Signing Signature:重疊簽署XML簽章(簽署簽章)
XML 簽章的流程
XML簽章實際上是分成兩個區段來執行,分別為將所要簽署的資料轉換為摘要的Reference Generation與將SignedInfo 欄位進行簽章動作的Signature Generation。
圖4、XML 簽章範例
1.Reference Generation
從圖1的XML可以看的出來,一份XML簽章可以包含多個Reference Tag,這表示可以包含多個文件。檢視Reference區段的屬性與以下的幾個子項目 Transforms、DigestMethod與DigestValue,包含了「簽章資料來源」、「簽章資料的轉換與過濾」、「運算摘要」三個主要的步驟。
(1)簽章資料來源:
在Reference的URI屬性中標示資料來源的位置,如果URI為一個網址,則代表其資料來源為外部的一個網頁;若URI為空白則代表目前的「整份文件」(即Reference Tag所處的文件);若URL=#idName則為指向目前文件其ID為idName的區段。
(2)簽章資料的轉換與過濾:
Transforms則是指定資料來源如何轉換或過濾的資訊,使用者可以指定多種的轉換或過濾方式,常見的轉換與過濾為Base64與XPath,Base64即如果來源資料為Binary則需轉換為Base64,而如果資料為XML格式可用XPath方式擷取需要簽署的「部分」內容。[注意:在轉換之後XML簽章函式需要以XML-C14N的方式來正規化文件,此轉換不會包含在 Transforms Tag內]
(3)運算摘要:
將轉換或過濾完的資料,透過DigestMethod所指定的雜湊方法計算摘要後,將雜湊值以Base64編碼後放置於DigestValue欄位中
圖5、Reference Generation 流程
2.Signature Generation
在Signature的產生上,主要是三個步驟:一、產生SignedInfo區段;二、正規化產生簽章資料;三、對區段進行簽章。首先,檢視SignedInfo這個區段包含了先前的Reference Tag 區段,還有CanonicalizationMethod與SignatureMethod這Tag,CanonicalizationMethod則是指派整份文件預設的正規化方式(包含Transform後的正規化與SignedInfo的正規化),可選擇Canonical XML with Comments等演算法;而SignatureMethod則是指定SignedInfo區段的簽章演算法,通常為rsa-sha1。最後運算出的結果則為簽章值以Base64編碼至於SignatureValue欄位。
圖6、Reference Signature 流程
3.其他流程:將憑證資訊或金鑰資訊放入KeyInfo或放入Time Stamp 資訊等…
為何需要正規化
在前面的文章中,不斷的提到正規化Canonicalization,為何需要做整規化呢?這是由於XML簽章簽章的對象主要是資料內容本身,而不是資料的二進位碼。例如:我們簽署一個<申請單><姓名 > 王大頭</姓名></申請單>類似這樣一個簡單的XML,如果使用傳統的簽章(PKCS#7)則會將這一段文字包含空白轉換為二進位碼,在對此二進位碼進行簽章,因此可能會造成(<申請單><姓名 > 王大頭</姓名></申請單>)與(<申請單><姓名 >王大頭</姓名></申請單>)是不等於的,因此需要對資料的格式做一個正規化的動作使得資料相同的文件得以轉換成同一格式(同一編碼(UTF-8)、同一格式)。
圖7、不正規化發生的問題
總結
XML簽章是一種具備彈性的簽章程序格式,透過在Reference Tag內指定的位置與Transform Tag轉換與過濾的機制加以變化,可以做出三種不同的XML簽章方式,以實作出單簽、多簽、整體簽章、部分簽章、重疊簽章,可以符合現今組織的需求,然而此篇文章僅點出XML簽章大致上的流程,囿於版面無法詳談各種類型的XML簽章實作。其他需要討論的議題除了幾項簽章如何實作的問題,還包含如果遇到具備Namespace應該如何處理的問題,則可在XML-Signature Syntax and Processing的Security Considerations內容中可以找尋到。
參考文獻
[1] 電子簽章法
[2] XML-Signature Syntax and Processing,http://www.w3.org/TR/2001/PR-xmldsig-core-20010820/#sec-Security