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

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|JavaScript|易語(yǔ)言|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - java結(jié)合keytool如何實(shí)現(xiàn)非對(duì)稱簽名和驗(yàn)證詳解

java結(jié)合keytool如何實(shí)現(xiàn)非對(duì)稱簽名和驗(yàn)證詳解

2021-05-24 13:43imaidata Java教程

這篇文章主要給大家介紹了關(guān)于java結(jié)合keytool如何實(shí)現(xiàn)非對(duì)稱簽名和驗(yàn)證的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

本文主要介紹了關(guān)于java結(jié)合keytool實(shí)現(xiàn)非對(duì)稱簽名和驗(yàn)證的相關(guān)內(nèi)容,分享出來(lái)供大家參考學(xué)習(xí),下面話不多說(shuō)了,來(lái)一起看看詳細(xì)的介紹吧

參考 還有姊妹篇:java結(jié)合keytool實(shí)現(xiàn)非對(duì)稱加密和解密

keytool的使用

keytool是JDK自帶的一個(gè)密鑰庫(kù)管理工具。這里只用到了keytool的部分功能,包括生成密鑰對(duì),導(dǎo)出公鑰等。keytool生成的公鑰/私鑰對(duì)存放到一個(gè)到了一個(gè)文件中,這個(gè)文件有密碼保護(hù),通稱為keystore。

生成密鑰對(duì)

?
1
$ keytool -genkey -alias signLegal -keystore examplestanstore -validity 1800

生成別名為signLegal的密鑰對(duì),存放在密鑰庫(kù)examplestanstore中,證書的有效期是1800天(默認(rèn)是90天)。

輸入一系列的參數(shù)。輸入的參數(shù)遵循了LDAP的風(fēng)格和標(biāo)準(zhǔn)。可以想象,生成的密鑰對(duì)可以看成LDAP的一個(gè)條目。

命令執(zhí)行成功后會(huì)在當(dāng)前目錄下創(chuàng)建一個(gè)叫examplestanstore的文件。

查看密鑰對(duì)

?
1
$ keytool -list -keystore examplestanstore -v

列出了examplestanstore密鑰庫(kù)的中所有密鑰對(duì)。-v參數(shù)表示詳細(xì)信息,詳細(xì)信息中有證書的失效時(shí)間。

導(dǎo)出公鑰證書

?
1
$ keytool -export -keystore examplestanstore -alias signLegal -file StanSmith.cer

導(dǎo)出的公鑰存放在當(dāng)前目錄的StanSmith.cer文件中,是個(gè)二進(jìn)制文件。

java簽名和驗(yàn)證

參考了java安全官方教程

在該官方教程中,GenSig.java類生成密鑰對(duì),對(duì)輸入的文件進(jìn)行簽名,輸出了一個(gè)簽名結(jié)果文件sig和公鑰suepk。

VerSig.java類接受三個(gè)參數(shù):公鑰文件名(suepk)、簽名文件(sig)、被簽名的源文件名(hello.txt)。

該教程解釋了兩個(gè)類的原理,并附加有源碼。將源碼下載并編譯。創(chuàng)建一個(gè)hello.txt的文件作為被簽名的目標(biāo)文件,里面隨便放點(diǎn)字符串。然后執(zhí)行:

?
1
2
3
$ java GenSig hello.txt   (生成文件sig和suepk)
$ java VerSig suepk sig hello.txt
signature verifies: true

在實(shí)際使用時(shí),密鑰對(duì)不可能每次在程序中重新生成。而keytool恰好可以生成并相對(duì)安全保存密鑰對(duì)。所以下面結(jié)合了keytool和java實(shí)現(xiàn)的功能。

結(jié)合keytool與java簽名/驗(yàn)證

參考

密鑰對(duì)由keytool生成并保存到keystore中保護(hù)起來(lái)(keystore有密碼)。公鑰也從keystore中導(dǎo)出。GenSig.java類只需要從keystore中取得私鑰進(jìn)行簽名即可。

VerSig.java也要做適當(dāng)?shù)男薷摹C菜埔驗(yàn)閺膋eystore中導(dǎo)出的是證書而不是公鑰,兩者的封裝格式估計(jì)有差異。

具體步驟

  • 利用keytool -genkey生成密鑰對(duì)保存在keystore中(庫(kù)文件是examplestanstore)
  • 利用`keytool -export'從keystore中導(dǎo)出公鑰證書(StanSmith.cer)
  • 利用新類GenSig2.java生成簽名(文件名是sig),GenSig2.java會(huì)從keystore中取私鑰
  • 將公鑰(StanSmith.cer)、簽名(sig)、被簽名文件(hello.txt)發(fā)給驗(yàn)證方
  • 驗(yàn)證方利用VerSig2.java進(jìn)行驗(yàn)證

下面是GenSig2.java和VerSig2.java的源碼和執(zhí)行方式。

GenSig2.java

?
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
import java.io.*;
import java.security.*;
 
class GenSig2 {
 
 public static void main(String[] args) {
 
 if (args.length != 1) {
  System.out.println("Usage: java GenSig2 <nameOfFileToSign>");
  }
 else try{
 
  /*create key paire use keytool:
  $ keytool -genkey -alias signLegal -keystore examplestanstore -validity 1800*/
  // read keystore file
  KeyStore ks = KeyStore.getInstance("JKS");
  FileInputStream ksfis = new FileInputStream("examplestanstore");
  BufferedInputStream ksbufin = new BufferedInputStream(ksfis);
 
  // open keystore and get private key
  // alias is 'signLeal', kpasswd/spasswd is 'vagrant'
  ks.load(ksbufin, "vagrant".toCharArray());
  PrivateKey priv = (PrivateKey) ks.getKey("signLegal", "vagrant".toCharArray());
 
  /* Create a Signature object and initialize it with the private key */
 
  Signature dsa = Signature.getInstance("SHA1withDSA", "SUN");
 
  dsa.initSign(priv);
  /* Update and sign the data */
 
  FileInputStream fis = new FileInputStream(args[0]);
  BufferedInputStream bufin = new BufferedInputStream(fis);
  byte[] buffer = new byte[1024];
  int len;
  while (bufin.available() != 0) {
  len = bufin.read(buffer);
  dsa.update(buffer, 0, len);
  };
 
  bufin.close();
 
  /* Now that all the data to be signed has been read in,
   generate a signature for it */
  byte[] realSig = dsa.sign();
 
  /* Save the signature in a file */
  FileOutputStream sigfos = new FileOutputStream("sig");
  sigfos.write(realSig);
 
  sigfos.close();
 
  /* public key file can export from keystore use keytool:
  $ keytool -export -keystore examplestanstore -alias signLegal -file StanSmith.cer */
 
 } catch (Exception e) {
  System.err.println("Caught exception " + e.toString());
 }
 };

編譯后,這樣運(yùn)行:

?
1
$ java GenSig2 hello.txt

會(huì)生成簽名文件sig。

VerSig2.java

?
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
import java.io.*;
import java.security.*;
import java.security.spec.*;
 
class VerSig2 {
 
 public static void main(String[] args) {
 
 /* Verify a DSA signature */
 
 if (args.length != 3) {
  System.out.println("Usage: VerSig publickeyfile signaturefile datafile");
  }
 else try{
 
  /* import encoded public cert */
  FileInputStream certfis = new FileInputStream(args[0]);
  java.security.cert.CertificateFactory cf =
  java.security.cert.CertificateFactory.getInstance("X.509");
  java.security.cert.Certificate cert = cf.generateCertificate(certfis);
  PublicKey pubKey = cert.getPublicKey();
 
  /* input the signature bytes */
  FileInputStream sigfis = new FileInputStream(args[1]);
  byte[] sigToVerify = new byte[sigfis.available()];
  sigfis.read(sigToVerify );
 
  sigfis.close();
 
  /* create a Signature object and initialize it with the public key */
  Signature sig = Signature.getInstance("SHA1withDSA", "SUN");
  sig.initVerify(pubKey);
 
  /* Update and verify the data */
 
  FileInputStream datafis = new FileInputStream(args[2]);
  BufferedInputStream bufin = new BufferedInputStream(datafis);
  byte[] buffer = new byte[1024];
  int len;
  while (bufin.available() != 0) {
  len = bufin.read(buffer);
  sig.update(buffer, 0, len);
  };
 
  bufin.close();
 
  boolean verifies = sig.verify(sigToVerify);
 
  System.out.println("signature verifies: " + verifies);
 
 } catch (Exception e) {
  System.err.println("Caught exception " + e.toString());
 };
 }
}

編譯后,這樣運(yùn)行(StanSmith.cer是利用keytool導(dǎo)出的公鑰證書,見(jiàn)前文):

?
1
2
$ java VerSig2 StanSmith.cer sig hello.txt
signature verifies: true

openssl

雖然也研究了一下openssl,但發(fā)現(xiàn)與java難以結(jié)合,難度也很大。例如它的教程中采用的是RSA,而上面的java使用的是DSA。所以只是貼在這里備忘,可以忽略。

參考

生成私鑰

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ openssl genrsa -out key.pem 1024
$ cat key.pem
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCzVDmu6Cf2QF7cERCGYU3B8Epm6pkkpMZFgotphXMgAmBBNJbh
Si7qPH4R5JlEm1ZXPr5DZH/pyJBWQhiiHGeUAOve+GOgvt9Rk25r7OEWYvn/GCr/
JBfLBGqwtlzn/t2s2x04IooshsGkOd6YpZoztkEDtu2gKHedFczF607IvwIDAQAB
AoGAMdbIqUmwQYomUvcTJqXIXIwRwYSVx09cI1lisZL7Kfw/ECAzhq19WHAzgXmM
9zpMxraTXluCCVFKfA6mlfda+ZoBlKSYdOecwNB+TSAumf9XK8uHW/g8C+Ykq9OG
g9Uiy8rKnl12Zaiu9H8L82ud0CkTFW2636/PuKgtp+4YbXECQQDhKdh8lwgumg7H
YIw5476QOHnPL7c3OFPGtaOZMZJkjMPfRzgR4B5PjcGnOLDoTlkATcBPmXtLwwJJ
SzaBdaRjAkEAy+NwdOzC1yQrTrkZQx1brNjO3iytfkl3t1xAWyz5Sy1IB7+4fsod
Eh3br5E1o5YRipY2GJZvp2OAAt3tz6iS9QJASvIYwu+qo4hX3vk9847gwTRrJxFk
1JaFHCEdgUJEzf8ku08DVL/alvRCPxzZlZluenFmz5fwuDkCq87DJ7g2rQJBAMDM
+SnIPdMeA8n0pRvfJjLD7pMP4pu6M3fzx3Owiqj5T9TsCjXzQBxCmdxizzs7DKll
tA/6Kek64PFVFa25tgUCQQCTM1VwfNKjFbd+0HuF6WAs3Odjuo0gKk/QIjdn7M5/
I0kxEApKxTto3oiuCQGeYL/sqy3WjM0476w48+xUsQeF
-----END RSA PRIVATE KEY-----

導(dǎo)出公鑰

?
1
2
3
4
5
6
7
8
$ openssl rsa -in key.pem -pubout -out pub-key.pem
$ cat pub-key.pem
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzVDmu6Cf2QF7cERCGYU3B8Epm
6pkkpMZFgotphXMgAmBBNJbhSi7qPH4R5JlEm1ZXPr5DZH/pyJBWQhiiHGeUAOve
+GOgvt9Rk25r7OEWYvn/GCr/JBfLBGqwtlzn/t2s2x04IooshsGkOd6YpZoztkED
tu2gKHedFczF607IvwIDAQAB
-----END PUBLIC KEY-----

摘要計(jì)算

創(chuàng)建一個(gè)內(nèi)容是1234的文本文件hello.txt。用openssl計(jì)算它的SHA256摘要(SHA256是jarsigner的默認(rèn)摘要算法):

?
1
2
3
4
5
$ cat hello.txt
1234
$ openssl dgst -SHA256 -out hello.sha256 hello.txt
$ cat hello.sha256
SHA256(hello.txt)= a883dafc480d466ee04e0d6da986bd78eb1fdd2178d04693723da3a8f95d42f4

簽名和驗(yàn)證

對(duì)摘要文件hello.sha256進(jìn)行簽名:

?
1
$ openssl rsautl -sign -in hello.sha256 -out hello.sign -inkey key.pem

用公鑰對(duì)簽名進(jìn)行驗(yàn)證:

?
1
2
$ openssl rsautl -verify -in hello.sign -inkey pub-key.pem -pubin
SHA256(hello.txt)= a883dafc480d466ee04e0d6da986bd78eb1fdd2178d04693723da3a8f95d42f4

用公鑰驗(yàn)證必須加上-pubin參數(shù)。 用私鑰對(duì)簽名進(jìn)行驗(yàn)證:

?
1
2
$ openssl rsautl -verify -in hello.sign -inkey key.pem
SHA256(hello.txt)= a883dafc480d466ee04e0d6da986bd78eb1fdd2178d04693723da3a8f95d42f4

驗(yàn)證的STD輸出與摘要文件hello.sha256的內(nèi)容一樣,說(shuō)明驗(yàn)證可以通過(guò)。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)服務(wù)器之家的支持。

原文鏈接:https://imaidata.github.io/blog/2017/07/29/java結(jié)合keytool實(shí)現(xiàn)非對(duì)稱簽名與驗(yàn)證/

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 精品一区二区三区免费毛片 | 媚药按摩痉挛w中文字幕 | 一级在线免费观看视频 | 久久亚洲精品久久国产一区二区 | 日本在线国产 | 精品久久999 | 亚洲电影在线观看高清免费 | 免费在线国产精品 | 欧美成人免费在线视频 | 亚洲午夜一区二区三区 | 九九热精品在线视频 | 色av成人天堂桃色av | 亚洲射逼| 奇米影视888狠狠狠777不卡 | 日本在线免费观看 | 黄色网战在线看 | 亚洲第一页夜 | 亚洲一区二区三区在线免费观看 | 激情午夜天 | 免费三级大片 | 最新中文字幕日本 | 在线免费视频a | 国产精品观看在线亚洲人成网 | 男女生羞羞视频网站在线观看 | 国产精品成人一区二区三区电影毛片 | 久草在线资源观看 | 国产精品久久久久永久免费 | 欧美黄色一级片在线观看 | 欧美久久久久久久久 | 香蕉成人在线视频 | 香蕉久久久 | 毛片成人 | 一区二区三区四区五区中文字幕 | 男男啪羞羞视频网站 | 成人激情视频网站 | 一级电影在线免费观看 | 天天艹综合 | 性欧美xxxx免费岛国不卡电影 | 免费久久久 | 一边吃奶一边摸下娇喘 | free性欧美hd另类 |