XML簽名技術,這項在W3C建議中指定的XML簽名語法及處理方法(XML-Signature Syntax and Processing),成為解決SOA開發中消息級安全性方案的基礎。被普遍接受的OASIS標準WS-安全性(WS-Security)正是構建在這一技術(以及XML加密)基礎之上。JSR-105規范又對在Java平臺應用XML簽名技術進一步標準化,并且將成為即將到來的Java SE 6發行版本的一個組成部分。本系列兩篇文章(《理論篇》與《實踐篇》)將基于Java SE 6的試發行版本對JSR-105作入門性介紹;在第二篇(即《實踐篇》)中,我們將討論一個具體的應用案例。
查看第二篇
一、 數據一致性和消息認證
XML數字簽名的主要目的是確保數據一致性。RFC 2828,因特網安全詞匯表(Internet Security Glossary),把"一致性"定義為"在一種未授權的或偶然方式下確保數據沒有改變、破壞或丟失的屬性"。在這種意義上,與一個校驗和一起存儲或傳遞數據就可以實現數據的一致性。嚴格地說,XML簽名能夠實現比這種一致性更為豐富的內涵-它能夠為在RFC 2828中所謂的消息認證提供支持。
二、 簽名元素結構
實質上,XML簽名使用XML語義描述一個數字簽名。下列層次捕獲頂級的元素和屬性以及它們之間的結構化關系。
<Signature ID?> <SignedInfo> <CanonicalizationMethod/> <SignatureMethod/> (<Reference URI? > (<Transforms>)? <DigestMethod> <DigestValue> </Reference>)+ </SignedInfo> <SignatureValue> (<KeyInfo>)? (<Object ID?>)* </Signature> |
在這個示例中,?表示零個或一個出現,+表示一個或多個出現,而*表示零或多個出現。在此,所有的元素和屬性被定義于命名空間http://www.w3.org/2000/09/XMLdsig#。
在此,Reference擔當連接要簽名的數據對象與一個XML簽名之間的橋梁作用(通過URI屬性)。一個應用程序選擇這里的digest方法來計算一個數據對象的digest值,并且把這二者作為相應的Reference元素的一部分。
對于digest方法,W3C建議實現對SHA-1的支持。而且,這種實現通常還支持其它交互式單向哈希函數-例如SHA-256,SHA-512和RIPEMD 160。
實際上,我們很少直接從數據對象本身計算一個digest值。通常,一個應用程序需要首先對數據對象應用一些轉換。例如,我們可以使用XPath來從一個XML文檔中僅提取關鍵元素以實現簽名;或者,我們也可能在使用XSLT經過一些轉換后對一個XML文檔進行簽名。這樣的轉換是在Transforms元素中指定的-其中包含一個有關實現轉換算法及其它相關信息的Transforms的有序列,當然也包括在相應的Reference元素之內。
SignedInfo是數字簽名算法實際應用的元素。該算法通過SignatureMethod元素捕獲;W3C建議中要求實現對DSA_SHA1,RSA_SHA1和HMAC_SHA1(由JSR-105所注釋)的支持。前兩個是基于公鑰的,而HMAC是一種對稱密鑰密碼學算法。三、 簽名過程
在XML簽名中,簽名過程包括兩個步驟。首先,它計算每一步的digest值以及確定要簽名的每一個數據對象,并且把該值包括為相應的Reference元素的一部分。在第二步中,它使用一個密碼學密鑰在SignedInfo元素上應用一種數字簽名算法來生成簽名值,并且把它包括為結果Reference元素的一部分。
第二步的實際機制往往隨著數字簽名算法的不同而不同,或更通常的是,因算法類別的不同而不同。
實踐中,一個數字簽名算法從未直接操作給定SignedInfo的XML格式,而是操作由SignedInfo元素的物理描述轉換而來的流數據(八位)。為了允許SignedInfo元素的邏輯上的等價表示,這種到八位的流的轉換基于SignedInfo元素的規范形式。存在兩個W3C規范,Canonical XML和Exclusive XML Canonicalization,定義了XML的規范化。獲得一個給定XML文檔(或元素)的規范形式的方法是很復雜的。但是,一般地,所有的XML簽名應用程序需要實現的就是,基于它們的上下文環境從四種已定義規范化方法中進行現成的選擇-EXCLUSIVE,EXCLUSIVE_WITH_COMMENTS,INCLUSIVE和INCLUSIVE_WITH_COMMENTS(列舉于JSR-105注釋中)。注意,SignedInfo中的CanonicalizationMethod元素負責捕獲這一選擇。
四、 XML簽名中的核心校驗
XML簽名中確保數據一致性和消息認證的機制基于核心校驗過程。它包括兩部分:引用校驗和簽名校驗。
引用校驗驗證在一個XML簽名中的每一個Reference元素都是有效的。在此,單詞"有效"的含義是:在對相應的數據對象(一般情況下通過URI屬性加以引用)應用相同的轉換之后,使用在Reference元素中指定的digest方法,我們應該能夠獲得一個已經記錄在Reference元素中的相同的digest值。這個digest值就是我們以前提及的校驗和。這種校驗對XML簽名中的數據一致性提供了支持。
簽名校驗的實際機制依賴于在SignedInfo元素中引用的特定的簽名算法(更精確地說是,簽名算法的類別)。它們的共同要求是,校驗應用程序必須擁有相應的密碼學密鑰:使用HMAC_SHA1(或使用其它哈希函數的HMAC)加密的密鑰,或使用RSA_SHA1和DSA_SHA1(或使用其它哈希函數的RSA和DSA)加密的公共密鑰。
References是SignedInfo元素的一部分,這是確保實現在XML簽名中的消息認證(這是一種比數據一致性更為安全的屬性)的結構機制。
五、 三種類型的XML簽名
W3C建議允許簽名任何數字數據,并且這包括一個XML文檔,一個文檔的XML元素以及一個XML元素的內容(作為特定的情形)。
當我們談及一個XML簽名時,我們實際上指的是一個XML文檔,它把Signature(在命名空間http://www.w3.org/2000/09/XMLdsig#中定義)包含為一個元素(這可以是根元素)。但是,該文檔可能還包含其它元素,這其中最為重要的當然要數要簽名的原始數據對象。
根據那些數據對象在一個XML Signature文檔中與Signature元素的關聯方式,我們考慮三種不同類型的XML簽名。
- · Enveloping-數據對象包含在與Signature元素相同的XML文檔中,并且被進一步包含在Signature元素(例如作為Object的子元素)中。
- · Enveloped-數據對象包含在與Signature元素相同的XML文檔中,并且實際上把Signature包括為一個子元素。
- · Detached-Signature引用外部網絡資源,或數據對象包含在與Signature元素相同的XML文檔中,但是作為一個兄弟元素或它的兄弟元素的一個子元素。
【注意】一些關于XML簽名的文章中讓讀者感覺到這是一個獨占分類的XML簽名;另一些則含蓄地建議,在enveloping或enveloped簽名中,實際上在包含該簽名的XML文檔中還存在一個Envelop元素;而且,還有一些文章則暗示:對一個enveloping簽名來說,Signature是XML文檔的根元素。其實,所有這些都不對。
六、 Object和KeyInfo
在我們繼續介紹JSR-105之前,我們需要簡短地討論兩個可選的簽名子元素-Object和KeyInfo。
W3C建議中的Object元素是一個占位符,用于在一個XML簽名應用程序承載實現若干不同目的之信息。例如,一種可能的應用是,一個Object包含一個enveloping簽名中被簽名的數據對象。這正是我們的示例所適用的情形。
XML簽名的KeyInfo元素可以用于簽名應用程序實現與加密(私有)密鑰相關信息的通訊,以便校驗程序可以獲得相關的(公共)密鑰。在接下來的【實踐篇】中,我們的示例將包括若干場所來說明KeyInfo的使用情形。
凡是有該標志的文章,都是該blog博主Caoer(草兒)原創,凡是索引、收藏
、轉載請注明來處和原文作者。非常感謝。