激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - Java教程 - 詳解Java數字簽名提供XML安全

詳解Java數字簽名提供XML安全

2021-05-27 13:22weistar Java教程

在本篇文章中我們給大家整理了關于Java數字簽名提供XML安全的知識點內容,有需要的朋友們可以學習下。

用java數字簽名提供xml安全

眾所周知,xml在產品和項目開發中起著非常重要的作用。通過xml文檔可以獲取很多信息,還可以使用xml文件進行crud(增加、查詢、更新和 刪除)操作。然而值得注意的是,我們如何確保xml中的數據是來自經過認證的可信和可靠的來源。關于xml文件數據的可靠性和真實性存在很多問題。通常的 情況是,開發者直接處理xml文件而不去考慮數據的可靠性。有一些情況提出了上面的所有問題。現實生活中,每當我們從郵局收到一封信件時我們如何確定這封 信是來自我們的朋友?依據可能是他/她的習慣用語、用詞或者郵件詳細地址。也可能是他/她的個性簽名。如今,我們收到的信件可能被某人進行了篡改,添加了 其他內容。基于上述原因,通常我們會驗證朋友的手寫簽名。當然這些是關于來自郵局的普通郵件。電子消息又該如何?我們如何驗證電子消息的真實性?這種情況 我們會采用數字簽名。本文會對保證數據完整性的xml數字簽名技術進行簡要介紹,并且展示如何為xml文件附加電子簽名及其驗證過程。

使用的技術

過去幾年里,xml數字簽名取得了快速發展,在金融領域尤其如此。在開始討論之前,讓我們考慮一個典型場景:想象一下,某個組織將所有雇員的薪資內 容用xml文件發送給所得稅部門。那么現在的問題是:所得稅部門如何驗證這份xml文件?這就是說,it部門需要驗證該組織的敏感信息。it部門需要確保 xml文件的來源可信,并且在it部門收到之前沒有經過篡改——也就是說文檔的內容沒有在傳遞中被修改。首先,我們需要理解數字簽名的概念。數字簽名是一 種用來驗證文檔發自可信方的電子簽名。它確保了文檔的原始內容在傳輸中沒有受到修改。數字簽名可以用于任何加密和非加密消息,因此接收方可以識別發送者的 身份,并確認消息沒有被其他人修改。根據維基百科的定義:“數字簽名是一種驗證數字信息或文檔的數學方法”。一個有效的數字簽名可以讓接收者確認收到的消 息來自已知發送方,發送者不能否認自己發送了此消息(提供認證和不可否認性)并且此消息在傳輸中未經修改(提供完整性)。數字簽名通常被用在軟件發布、金 融事務和其他需要檢測偽造或篡改的重要場合。

下面讓我們來看完整的一個帶有數字簽名的xml文件:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<?xml version="1.0" encoding="utf-8" standalone="no"?><salarydeposit>
  <organisation>
    <name>ddlab inc</name>
    <accountno>sbc-12345789</accountno>
  </organisation>
  <employees>
    <emp>
      <name>john abraham</name>
      <accountno>sb-001</accountno>
      <amount>1234</amount>
    </emp>
    <emp>
      <name>bipasha basu</name>
      <accountno>sb-002</accountno>
      <amount>2334</amount>
    </emp>
    <emp>
      <name>vidya balan</name>
      <accountno>sb-003</accountno>
      <amount>3465</amount>
    </emp>
    <emp>
      <name>debadatta mishra</name>
      <accountno>sb-007</accountno>
      <amount>5789</amount>
    </emp>
    <emp>
      <name>priti zinta</name>
      <accountno>sb-009</accountno>
      <amount>1234</amount>
    </emp>
  </employees>
  <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>bhs+6uf8kbjv4agzohnhlfnxvkm=</digestvalue>
      </reference>
    </signedinfo>
    <signaturevalue>
auemrct5dzeofsnaznzot0if8wz8kqcmnxdqtoeseonvk3nqok9ctcxrf3qvx3wp6810ddrpdi6l
   e8ccg64ge0hjko+ayc5+c2l/qkbzwtsbl/oljeufu2dvxbqo+k29ttujfxpvzc9zf2pvt+1nrj0f
   2/ofhujyz01d6+yqi8c=
    </signaturevalue>
    <keyinfo>
      <keyvalue>
       <rsakeyvalue>
         <modulus>
jfad5uv38l36+ldzjrqfh9oln86vjezxyfaeu+lrfohlkaxvjlai9hkvbhqrer4tpfdez6isbksl
      6ihkpnvrakt0xu99uxi5qpymswax3qnbqhlw9z70pwyz+xysfw4q2tk2htsguohmuaucif9sbhvf
      gbvcrpgxdzzqfizdmdu=</modulus>
         <exponent>aqab</exponent>
       </rsakeyvalue>
      </keyvalue>
    </keyinfo>
  </signature>
</salarydeposit>

上面是一個帶有簽名的xml文件,該文件可以隨時進行驗證。文件中包了含雇員名稱、帳號和薪資信息。然而,實際的數字簽名通 過<signature></signature>標記進行附加。<signature> 標記中的信息提供了文檔的真實性。正如你看到的那樣,雖然你可以隨意修改其中的數據,但是這種修改會在隨后的簽名驗證中被查到。
基本上數字簽名有三種類型:

  1. 封內簽名
  2. 封外簽名
  3. 分離簽名

封內簽名

這種簽名是將簽名作為xml對象的子信息,也就是說 <signature>是郵件中xml文件的子標簽。封內數字簽名的結構如下:

?
1
2
3
4
5
<rootelement>
 <signature>
 ……
 </signature>
</ rootelement>

本文會介紹如何創建xml封內數字簽名。

封外簽名

這種簽名將xml文檔包含到signature對象,也就是說<signature>標簽是簽名xml文件的根元素。封外簽名結構如下:

?
1
2
3
4
5
<signature >
  < myxmldocument >
  ……
  </ myxmldocument >
</signature>

分離簽名

這種情況下,簽名是獨立生成的不作為xml的一部分。也就是說你會擁有兩個xml文件:一個待簽名的xml文件,另一個是xml簽名。下面是分離簽名的xml結構:

?
1
2
3
<signature>
……
</signature>

xml數字簽名文件結構如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<signature xmlns="">
  <signedinfo>
    <canonicalizationmethod algorithm="" />
    <signaturemethod algorithm="" />
    <reference uri="">
      <transforms>
        <transform algorithm="" />
        </transforms>
      <digestmethod algorithm="" />
      <digestvalue></digestvalue>
    </reference>
  </signedinfo>
  <signaturevalue></signaturevalue>
  <keyinfo>
    <keyvalue>
      <rsakeyvalue>
        <modulus></modulus>
        <exponent></exponent>
      </rsakeyvalue>
    </keyvalue>
  </keyinfo>
</signature>

xml中<signature>有3個子標簽,結構如下:

?
1
2
3
4
5
<signature>
  <signedinfo></signedinfo>
  <signaturevalue></signaturevalue>
  <keyinfo></keyinfo>
</signature>

這里<signature>是xml數字簽名的根元素,這一點由w3c建議并且必須遵守。<signedinfo>元素是你的簽名信息;<signaturevalue>包含了實際的簽名以及使用base64加密的內容;最后<keyinfo>表示公鑰。讓我們再看一下<signedinfo>標簽,結構如下:

?
1
2
3
4
5
6
7
8
9
10
11
<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>bhs+6uf8kbjv4agzohnhlfnxvkm=</digestvalue>
  </reference>
</signedinfo>

當使用java創建xml數字簽名時,signedinfo對象被用來在數字簽名的signature標簽內創建元素。這也是w3c建議的xml簽名標準中的一部分。

xml標簽<keyinfo>的結構如下:

?
1
2
3
4
5
6
7
8
<keyinfo>
  <keyvalue>
    <rsakeyvalue>
      <modulus></modulus>
      <exponent></exponent>
    </rsakeyvalue>
  </keyvalue>
</keyinfo>

keyinfo>標記包含了需要數學計算的相關信息,主要有公鑰的系數和指數。
要創建xml數字簽名可以遵循下列步驟:

  1. 生成一組私鑰和公鑰。
  2. 獲得原始xml文件。
  3. 通過java api使用私鑰和公鑰為原始的xml文件簽名,生成帶有xml簽名的文檔。

讓我們看看使用java生成xml簽名的相關代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public void generatexmldigitalsignature(string originalxmlfilepath,
string destnsignedxmlfilepath, string privatekeyfilepath, string publickeyfilepath) {
  // 獲取xml文檔對象
  document doc = getxmldocument(originalxmlfilepath);
  
  // 創建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);
  
  // 創建新的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簽名驗證

數字簽名的驗證包含以下操作:

驗證數字簽名

  • 計算<signedinfo>元素摘要。
  • 使用公鑰解密<signaturevalue>元素。
  • 比較上面兩個值。
  • 計算引用摘要
  • 重新計算<signedinfo>元素引用摘要。
  • 將它們與<digestvalue>中的摘要比較。

為了驗證xml簽名文檔,需要完成下列步驟

  1. 得到xml文檔和公鑰。
  2. 驗證<signedinfo> 元素的數字簽名。
  3. 計算<signedinfo> 元素的摘要并對值進行比較。

讓我們看看下面這段xml數字簽名示例代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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簽名可以通過重新計算<signedinfo>的摘要值進行驗證,驗證算法由 <signaturemethod>元素指定;使用公鑰可以驗證<signedinfo>摘要中 的<signaturevalue>值是否正確。 引用摘要會在<signedinfo>元素中重新計算,并與<reference> 元素中對應的<digestvalue> 進行比對。接下來,讓我們熟悉一下xml數字簽名相關的java組件。

xmlsignaturefactory

xmlsignaturefactory是生成xml文檔數字簽名的工廠對象。對象的創建如下列代碼所示:

?
1
xmlsignaturefactory factory = xmlsignaturefactory.getinstance("dom");

domsigncontext

domsigncontext對象用來生成dom樹。在創建數字簽名的過程中,dom樹會被附上xml數字簽名。domsigncontext對象要求輸入私鑰和xml文檔的根元素。

reference

reference對象用來在signature 標記的signedinfo內部創建xml數字簽名。對象創建的遵循“w3c xml簽名文法和處理”規則。reference的基本結構如下:

?
1
2
3
4
5
6
7
<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>bhs+6uf8kbjv4agzohnhlfnxvkm=</digestvalue>
</reference>

signedinfo

類似的,signedinfo對象可以在數字簽名的signature標記內部創建元素。創建的規則同樣遵循“w3c xml數字簽名協議”。signedinfo的基本結構如下:

?
1
2
3
4
5
6
7
8
9
10
11
<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>bhs+6uf8kbjv4agzohnhlfnxvkm=</digestvalue>
  </reference>
</signedinfo>

xmlsignature

最后,xmlsignature對象用來創建xml文檔的封面簽名。按照w3c的建議,簽名對象應該作為xml數字簽名的根元素。
完整的結構如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<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>bhs+6uf8kbjv4agzohnhlfnxvkm=</digestvalue>
    </reference>
  </signedinfo>
  <signaturevalue>auemrct5dzeofsnaznzot0if8wz8kqcmnxdqtoeseonvk3nqok9ctcxrf3qvx3wp6810ddrpdi6l
  e8ccg64ge0hjko+ayc5+c2l/qkbzwtsbl/oljeufu2dvxbqo+k29ttujfxpvzc9zf2pvt+1nrj0f
  2/ofhujyz01d6+yqi8c=</signaturevalue>
  <keyinfo>
    <keyvalue>
    <rsakeyvalue>
      <modulus>jfad5uv38l36+ldzjrqfh9oln86vjezxyfaeu+lrfohlkaxvjlai9hkvbhqrer4tpfdez6isbksl
      6ihkpnvrakt0xu99uxi5qpymswax3qnbqhlw9z70pwyz+xysfw4q2tk2htsguohmuaucif9sbhvf
      gbvcrpgxdzzqfizdmdu=</modulus>
      <exponent>aqab</exponent>
    </rsakeyvalue>
    </keyvalue>
  </keyinfo>
</signature>

為了有一個完成的理解,可以從這里下載完整的netbeans項目代碼。

可以用你最喜歡的java ide對項目進行配置;也可以在source文件夾下運行程序。這個項目已經包含了公鑰和私鑰。如果想要自己生成,可以運行 “testgeneratekeys”類生成一對公鑰和私鑰。通過指定自己的xmi文件,還可以查看xml簽名的生成過程。

以上就是本次我們給大家整理的內容的全部,感謝大家對服務器之家的支持,如果大家還有不明白的可以在下方留言區討論。

原文鏈接:http://weistar.iteye.com/blog/1982979

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久艹艹艹 | 亚洲网站免费观看 | av在线在线| 九九热视频免费观看 | 欧美爱爱一区二区 | 奇米影视奇奇米色狠狠色777 | 久久综合色区 | 手机av在线电影 | 欧洲黄色一级视频 | 国产精品久久久久国产精品三级 | 久久久www成人免费精品 | 一级毛片在线看 | 亚洲一区 国产精品 | 日韩欧美精品中文字幕 | 香蕉秀 | 亚洲精品成人久久 | 粉嫩av一区二区三区四区在线观看 | 国产成人在线播放视频 | 中文字幕网址 | 羞羞的视频在线免费观看 | 毛片一级片 | 成年免费观看视频 | 国产成人精品免费视频大全最热 | 一级成人毛片 | 国产一区二区欧美精品 | 久久色播 | 亚洲一区二区免费 | 精品一区二区三区在线观看国产 | 日本aⅴ在线 | 国产一区二区亚洲 | 91久久久久久久 | 国产黄色一级大片 | 日韩精品中文字幕一区二区三区 | 最近免费观看高清韩国日本大全 | 激情大乳女做爰办公室韩国 | 狠狠操你| 成人免费入口 | www.91sese| 免费一级高清毛片 | 日韩视频一区二区 | 亚洲精品xxx |