麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 開發(fā) > Java > 正文

java結合keytool如何實現(xiàn)非對稱簽名和驗證詳解

2024-07-14 08:41:58
字體:
來源:轉載
供稿:網(wǎng)友

前言

本文主要介紹了關于java結合keytool實現(xiàn)非對稱簽名和驗證的相關內(nèi)容,分享出來供大家參考學習,下面話不多說了,來一起看看詳細的介紹吧

keytool的使用

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

生成密鑰對

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

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

輸入一系列的參數(shù)。輸入的參數(shù)遵循了LDAP的風格和標準。可以想象,生成的密鑰對可以看成LDAP的一個條目。

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

查看密鑰對

$ keytool -list -keystore examplestanstore -v

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

導出公鑰證書

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

導出的公鑰存放在當前目錄的StanSmith.cer文件中,是個二進制文件。

java簽名和驗證

參考了java安全官方教程。 

在該官方教程中,GenSig.java類生成密鑰對,對輸入的文件進行簽名,輸出了一個簽名結果文件sig和公鑰suepk。

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

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

$ java GenSig hello.txt   (生成文件sig和suepk)$ java VerSig suepk sig hello.txtsignature verifies: true

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

結合keytool與java簽名/驗證

參考

密鑰對由keytool生成并保存到keystore中保護起來(keystore有密碼)。公鑰也從keystore中導出。GenSig.java類只需要從keystore中取得私鑰進行簽名即可。

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

具體步驟

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

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

GenSig2.java

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()); } };

編譯后,這樣運行:

$ java GenSig2 hello.txt

會生成簽名文件sig。

VerSig2.java

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()); }; }}

編譯后,這樣運行(StanSmith.cer是利用keytool導出的公鑰證書,見前文):

$ java VerSig2 StanSmith.cer sig hello.txtsignature verifies: true

openssl

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

參考

生成私鑰

$ openssl genrsa -out key.pem 1024$ cat key.pem-----BEGIN RSA PRIVATE KEY-----MIICXQIBAAKBgQCzVDmu6Cf2QF7cERCGYU3B8Epm6pkkpMZFgotphXMgAmBBNJbhSi7qPH4R5JlEm1ZXPr5DZH/pyJBWQhiiHGeUAOve+GOgvt9Rk25r7OEWYvn/GCr/JBfLBGqwtlzn/t2s2x04IooshsGkOd6YpZoztkEDtu2gKHedFczF607IvwIDAQABAoGAMdbIqUmwQYomUvcTJqXIXIwRwYSVx09cI1lisZL7Kfw/ECAzhq19WHAzgXmM9zpMxraTXluCCVFKfA6mlfda+ZoBlKSYdOecwNB+TSAumf9XK8uHW/g8C+Ykq9OGg9Uiy8rKnl12Zaiu9H8L82ud0CkTFW2636/PuKgtp+4YbXECQQDhKdh8lwgumg7HYIw5476QOHnPL7c3OFPGtaOZMZJkjMPfRzgR4B5PjcGnOLDoTlkATcBPmXtLwwJJSzaBdaRjAkEAy+NwdOzC1yQrTrkZQx1brNjO3iytfkl3t1xAWyz5Sy1IB7+4fsodEh3br5E1o5YRipY2GJZvp2OAAt3tz6iS9QJASvIYwu+qo4hX3vk9847gwTRrJxFk1JaFHCEdgUJEzf8ku08DVL/alvRCPxzZlZluenFmz5fwuDkCq87DJ7g2rQJBAMDM+SnIPdMeA8n0pRvfJjLD7pMP4pu6M3fzx3Owiqj5T9TsCjXzQBxCmdxizzs7DKlltA/6Kek64PFVFa25tgUCQQCTM1VwfNKjFbd+0HuF6WAs3Odjuo0gKk/QIjdn7M5/I0kxEApKxTto3oiuCQGeYL/sqy3WjM0476w48+xUsQeF-----END RSA PRIVATE KEY-----

導出公鑰

$ openssl rsa -in key.pem -pubout -out pub-key.pem$ cat pub-key.pem-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzVDmu6Cf2QF7cERCGYU3B8Epm6pkkpMZFgotphXMgAmBBNJbhSi7qPH4R5JlEm1ZXPr5DZH/pyJBWQhiiHGeUAOve+GOgvt9Rk25r7OEWYvn/GCr/JBfLBGqwtlzn/t2s2x04IooshsGkOd6YpZoztkEDtu2gKHedFczF607IvwIDAQAB-----END PUBLIC KEY-----

摘要計算

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

$ cat hello.txt1234$ openssl dgst -SHA256 -out hello.sha256 hello.txt$ cat hello.sha256SHA256(hello.txt)= a883dafc480d466ee04e0d6da986bd78eb1fdd2178d04693723da3a8f95d42f4

簽名和驗證

對摘要文件hello.sha256進行簽名:

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

用公鑰對簽名進行驗證:

$ openssl rsautl -verify -in hello.sign -inkey pub-key.pem -pubinSHA256(hello.txt)= a883dafc480d466ee04e0d6da986bd78eb1fdd2178d04693723da3a8f95d42f4

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

$ openssl rsautl -verify -in hello.sign -inkey key.pemSHA256(hello.txt)= a883dafc480d466ee04e0d6da986bd78eb1fdd2178d04693723da3a8f95d42f4

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

總結

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VeVb武林網(wǎng)的支持。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 日韩精品99久久久久久 | 成人一级免费视频 | 一级黄色av电影 | 99极品视频 | 99热99精品| 亚洲第一精品在线 | 免费一级欧美大片视频 | 北原夏美av | 伊人yinren22综合网色 | 午夜视频你懂的 | 亚洲综合精品成人 | 九一传媒在线观看 | 欧美精品一区二区三区久久久 | 欧美日韩中文字幕在线 | 黑人操穴| 国产1区在线 | 久草经典视频 | 久久美女色视频 | 成人免费观看在线 | 色网在线视频 | 欧美黄 片免费观看 | 免费一及片 | 精品国产高清一区二区三区 | 天天色综合6 | 日韩精品99久久久久久 | 斗破苍穹在线观看免费完整观看 | 国产一级毛片国产 | 色阁阁69婷婷 | 国产做爰| 一区二区三高清 | 99在线在线视频免费视频观看 | 欧美黄色大片免费观看 | 黄视频网站免费观看 | 看一级大毛片 | 成人在线视频播放 | 国产人成免费爽爽爽视频 | 国产精品1区2区在线观看 | 国产一区二区三区四区五区精品 | 在线日韩av电影 | 亚洲国产精久久久久久久 | 成人免费影院 |