十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團隊
量身定制 + 運營維護+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
用Java數(shù)字簽名提供XML安全
創(chuàng)新互聯(lián)公司專注于寬城網(wǎng)站建設(shè)服務及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供寬城營銷型網(wǎng)站建設(shè),寬城網(wǎng)站制作、寬城網(wǎng)頁設(shè)計、寬城網(wǎng)站官網(wǎng)定制、小程序定制開發(fā)服務,打造寬城網(wǎng)絡公司原創(chuàng)品牌,更為您提供寬城網(wǎng)站排名全網(wǎng)營銷落地服務。
眾所周知,XML在產(chǎn)品和項目開發(fā)中起著非常重要的作用。通過XML文檔可以獲取很多信息,還可以使用XML文件進行CRUD(增加、查詢、更新和 刪除)操作。然而值得注意的是,我們?nèi)绾未_保XML中的數(shù)據(jù)是來自經(jīng)過認證的可信和可靠的來源。關(guān)于XML文件數(shù)據(jù)的可靠性和真實性存在很多問題。通常的 情況是,開發(fā)者直接處理XML文件而不去考慮數(shù)據(jù)的可靠性。有一些情況提出了上面的所有問題。現(xiàn)實生活中,每當我們從郵局收到一封信件時我們?nèi)绾未_定這封 信是來自我們的朋友?依據(jù)可能是他/她的習慣用語、用詞或者郵件詳細地址。也可能是他/她的個性簽名。如今,我們收到的信件可能被某人進行了篡改,添加了 其他內(nèi)容?;谏鲜鲈?,通常我們會驗證朋友的手寫簽名。當然這些是關(guān)于來自郵局的普通郵件。電子消息又該如何?我們?nèi)绾悟炞C電子消息的真實性?這種情況 我們會采用數(shù)字簽名。本文會對保證數(shù)據(jù)完整性的XML數(shù)字簽名技術(shù)進行簡要介紹,并且展示如何為XML文件附加電子簽名及其驗證過程。
使用的技術(shù)
過去幾年里,XML數(shù)字簽名取得了快速發(fā)展,在金融領(lǐng)域尤其如此。在開始討論之前,讓我們考慮一個典型場景:想象一下,某個組織將所有雇員的薪資內(nèi) 容用XML文件發(fā)送給所得稅部門。那么現(xiàn)在的問題是:所得稅部門如何驗證這份XML文件?這就是說,IT部門需要驗證該組織的敏感信息。IT部門需要確保 XML文件的來源可信,并且在IT部門收到之前沒有經(jīng)過篡改——也就是說文檔的內(nèi)容沒有在傳遞中被修改。首先,我們需要理解數(shù)字簽名的概念。數(shù)字簽名是一 種用來驗證文檔發(fā)自可信方的電子簽名。它確保了文檔的原始內(nèi)容在傳輸中沒有受到修改。數(shù)字簽名可以用于任何加密和非加密消息,因此接收方可以識別發(fā)送者的 身份,并確認消息沒有被其他人修改。根據(jù)維基百科的定義:“數(shù)字簽名是一種驗證數(shù)字信息或文檔的數(shù)學方法”。一個有效的數(shù)字簽名可以讓接收者確認收到的消 息來自已知發(fā)送方,發(fā)送者不能否認自己發(fā)送了此消息(提供認證和不可否認性)并且此消息在傳輸中未經(jīng)修改(提供完整性)。數(shù)字簽名通常被用在軟件發(fā)布、金 融事務和其他需要檢測偽造或篡改的重要場合。
下面讓我們來看完整的一個帶有數(shù)字簽名的XML文件:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>DDLab Inc SBC-12345789 John Abraham SB-001 1234 Bipasha Basu SB-002 2334 Vidya Balan SB-003 3465 Debadatta Mishra SB-007 5789 Priti Zinta SB-009 1234 bHS+6uf8KbJV4AGzoHNHLfnXvKM= aUEMrCT5dzeOfSNaznzoT0If8WZ8KQcMNXDqtoeseonVk3NqOk9ctcxrf3QVX3wP6810DDRPdI6l e8ccG64Ge0HjkO+aYC5+c2L/qKBzwtSbl/olJEuFU2DVxBQO+K29TTUJfxpVzC9Zf2pvT+1NRj0f 2/ofHujYZ01D6+YqI8c= jfAd5uV38L36+lDZJrqfH9oLN86VJezXYfAeU+lrFoHlKAXVJLAi9hKvBHQRer4tPfdez6iSBKsl 6IHkPnVRAKt0xU99uxi5QpymsWAX3qnBqHlw9Z70PwyZ+Xysfw4Q2tK2HtSgUOhMuaUcIf9sbHvf gbvcRPgxDZZqfIzDmDU= AQAB
上面是一個帶有簽名的XML文件,該文件可以隨時進行驗證。文件中包了含雇員名稱、帳號和薪資信息。然而,實際的數(shù)字簽名通 過
基本上數(shù)字簽名有三種類型:
封內(nèi)簽名
這種簽名是將簽名作為XML對象的子信息,也就是說
…… RootElement>
本文會介紹如何創(chuàng)建XML封內(nèi)數(shù)字簽名。
封外簽名
這種簽名將XML文檔包含到Signature對象,也就是說
< MyXMLDocument > …… MyXMLDocument >
分離簽名
這種情況下,簽名是獨立生成的不作為XML的一部分。也就是說你會擁有兩個XML文件:一個待簽名的XML文件,另一個是XML簽名。下面是分離簽名的XML結(jié)構(gòu):
……
XML數(shù)字簽名文件結(jié)構(gòu)如下:
XML中
這里
bHS+6uf8KbJV4AGzoHNHLfnXvKM=
當使用Java創(chuàng)建XML數(shù)字簽名時,SignedInfo對象被用來在數(shù)字簽名的Signature標簽內(nèi)創(chuàng)建元素。這也是W3C建議的XML簽名標準中的一部分。
XML標簽
KeyInfo>標記包含了需要數(shù)學計算的相關(guān)信息,主要有公鑰的系數(shù)和指數(shù)。
要創(chuàng)建XML數(shù)字簽名可以遵循下列步驟:
讓我們看看使用Java生成XML簽名的相關(guān)代碼:
public void generateXMLDigitalSignature(String originalXmlFilePath, String destnSignedXmlFilePath, String privateKeyFilePath, String publicKeyFilePath) { // 獲取XML文檔對象 Document doc = getXmlDocument(originalXmlFilePath); // 創(chuàng)建XML簽名工廠 XMLSignatureFactory xmlSigFactory = XMLSignatureFactory.getInstance("DOM"); PrivateKey privateKey = new KryptoUtil().getStoredPrivateKey(privateKeyFilePath); DOMSignContext domSignCtx = new DOMSignContext(privateKey, doc.getDocumentElement()); Reference ref = null; SignedInfo signedInfo = null; try { ref = xmlSigFactory.newReference("", xmlSigFactory.newDigestMethod(DigestMethod.SHA1, null), Collections.singletonList(xmlSigFactory.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)), null, null); signedInfo = xmlSigFactory.newSignedInfo( xmlSigFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null), xmlSigFactory.newSignatureMethod(SignatureMethod.RSA_SHA1, null), Collections.singletonList(ref)); } catch (NoSuchAlgorithmException ex) { ex.printStackTrace(); } catch (InvalidAlgorithmParameterException ex) { ex.printStackTrace(); } // 傳入公鑰路徑 KeyInfo keyInfo = getKeyInfo(xmlSigFactory, publicKeyFilePath); // 創(chuàng)建新的XML簽名 XMLSignature xmlSignature = xmlSigFactory.newXMLSignature(signedInfo, keyInfo); try { // 對文檔簽名 xmlSignature.sign(domSignCtx); } catch (MarshalException ex) { ex.printStackTrace(); } catch (XMLSignatureException ex) { ex.printStackTrace(); } // 存儲簽名過的文檔 storeSignedDoc(doc, destnSignedXmlFilePath); }
XML簽名驗證
數(shù)字簽名的驗證包含以下操作:
驗證數(shù)字簽名
為了驗證XML簽名文檔,需要完成下列步驟
讓我們看看下面這段XML數(shù)字簽名示例代碼:
public static boolean isXmlDigitalSignatureValid(String signedXmlFilePath, String pubicKeyFilePath) throws Exception { boolean validFlag = false; Document doc = getXmlDocument(signedXmlFilePath); NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); if (nl.getLength() == 0) { throw new Exception("No XML Digital Signature Found, document is discarded"); } PublicKey publicKey = new KryptoUtil().getStoredPublicKey(pubicKeyFilePath); DOMValidateContext valContext = new DOMValidateContext(publicKey, nl.item(0)); XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM"); XMLSignature signature = fac.unmarshalXMLSignature(valContext); validFlag = signature.validate(valContext); return validFlag; }
如上面示例代碼所示,XML簽名可以通過重新計算
XMLSignatureFactory
XMLSignatureFactory是生成XML文檔數(shù)字簽名的工廠對象。對象的創(chuàng)建如下列代碼所示:
XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM");
DOMSignContext
DOMSignContext對象用來生成DOM樹。在創(chuàng)建數(shù)字簽名的過程中,DOM樹會被附上XML數(shù)字簽名。DOMSignContext對象要求輸入私鑰和XML文檔的根元素。
Reference
Reference對象用來在Signature 標記的SignedInfo內(nèi)部創(chuàng)建XML數(shù)字簽名。對象創(chuàng)建的遵循“W3C XML簽名文法和處理”規(guī)則。Reference的基本結(jié)構(gòu)如下:
bHS+6uf8KbJV4AGzoHNHLfnXvKM=
SignedInfo
類似的,SignedInfo對象可以在數(shù)字簽名的Signature標記內(nèi)部創(chuàng)建元素。創(chuàng)建的規(guī)則同樣遵循“W3C XML數(shù)字簽名協(xié)議”。SignedInfo的基本結(jié)構(gòu)如下:
bHS+6uf8KbJV4AGzoHNHLfnXvKM=
XMLSignature
最后,XMLSignature對象用來創(chuàng)建XML文檔的封面簽名。按照W3C的建議,簽名對象應該作為XML數(shù)字簽名的根元素。
完整的結(jié)構(gòu)如下:
bHS+6uf8KbJV4AGzoHNHLfnXvKM= aUEMrCT5dzeOfSNaznzoT0If8WZ8KQcMNXDqtoeseonVk3NqOk9ctcxrf3QVX3wP6810DDRPdI6l e8ccG64Ge0HjkO+aYC5+c2L/qKBzwtSbl/olJEuFU2DVxBQO+K29TTUJfxpVzC9Zf2pvT+1NRj0f 2/ofHujYZ01D6+YqI8c= jfAd5uV38L36+lDZJrqfH9oLN86VJezXYfAeU+lrFoHlKAXVJLAi9hKvBHQRer4tPfdez6iSBKsl 6IHkPnVRAKt0xU99uxi5QpymsWAX3qnBqHlw9Z70PwyZ+Xysfw4Q2tK2HtSgUOhMuaUcIf9sbHvf gbvcRPgxDZZqfIzDmDU= AQAB
為了有一個完成的理解,可以從這里下載完整的Netbeans項目代碼。
可以用你最喜歡的Java IDE對項目進行配置;也可以在source文件夾下運行程序。這個項目已經(jīng)包含了公鑰和私鑰。如果想要自己生成,可以運行 “TestGenerateKeys”類生成一對公鑰和私鑰。通過指定自己的XMI文件,還可以查看XML簽名的生成過程。
以上就是本次我們給大家整理的內(nèi)容的全部,感謝大家對創(chuàng)新互聯(lián)的支持,如果大家還有不明白的可以在下方留言區(qū)討論。