1. java註解怎麼驗證參數和簽名
一般介面為了安全需要,都會這么做。可能你的思路還不明確。我的做法是這樣的,雙方約定好,參數按特定順序排列,比如按首字母的順序排列,如url:http://xxx/xxx.do?a=wersd&b=sd2354&c=4&signature=XXXXXXXXXXXX(signature為傳入的簽名),你拿到入參後,將參數串a=wersd&b=sd2354&c=4按你們約定的簽名規則,自己用md5加簽一次,然後和入參的signature值對比,以確認調用者是否合法,這就是介面簽名驗證的思路。
希望有幫到你,記得採納。
2. 基於java語言的數字簽名
Java加密和數字簽名編程快速入門
本文主要談一下密碼學中的加密和數字簽名,以及其在java中如何進行使用。對密碼學有興趣的夥伴,推薦看Bruce Schneier的著作:Applied Crypotography。在jdk1.5的發行版本中安全性方面有了很大的改進,也提供了對RSA演算法的直接支持,現在我們從實例入手解決問題(本文僅是作為簡單介紹):
一、密碼學上常用的概念
1)消息摘要:
這是一種與消息認證碼結合使用以確保消息完整性的技術。主要使用單向散列函數演算法,可用於檢驗消息的完整性,和通過散列密碼直接以文本形式保存等,目前廣泛使用的演算法有MD4、MD5、SHA-1,jdk1.5對上面都提供了支持,在java中進行消息摘要很簡單, java.security.MessageDigest提供了一個簡易的操作方法:
/**
*MessageDigestExample.java
*Copyright 2005-2-16
*/
import java.security.MessageDigest;
/**
*單一的消息摘要演算法,不使用密碼.可以用來對明文消息(如:密碼)隱藏保存
*/
public class MessageDigestExample{
public static void main(String[] args) throws Exception{
if(args.length!=1){
System.err.println("Usage:java MessageDigestExample text");
System.exit(1);
}
byte[] plainText=args[0].getBytes("UTF8");
//使用getInstance("演算法")來獲得消息摘要,這里使用SHA-1的160位演算法
MessageDigest messageDigest=MessageDigest.getInstance("SHA-1");
System.out.println("\n"+messageDigest.getProvider().getInfo());
//開始使用演算法
messageDigest.update(plainText);
System.out.println("\nDigest:");
//輸出演算法運算結果
System.out.println(new String(messageDigest.digest(),"UTF8"));
}
}
還可以通過消息認證碼來進行加密實現,javax.crypto.Mac提供了一個解決方案,有興趣者可以參考相關API文檔,本文只是簡單介紹什麼是摘要演算法。
2)私鑰加密:
消息摘要只能檢查消息的完整性,但是單向的,對明文消息並不能加密,要加密明文的消息的話,就要使用其他的演算法,要確保機密性,我們需要使用私鑰密碼術來交換私有消息。
這種最好理解,使用對稱演算法。比如:A用一個密鑰對一個文件加密,而B讀取這個文件的話,則需要和A一樣的密鑰,雙方共享一個私鑰(而在web環境下,私鑰在傳遞時容易被偵聽):
使用私鑰加密的話,首先需要一個密鑰,可用javax.crypto.KeyGenerator產生一個密鑰(java.security.Key),然後傳遞給一個加密工具(javax.crypto.Cipher),該工具再使用相應的演算法來進行加密,主要對稱演算法有:DES(實際密鑰只用到56位),AES(支持三種密鑰長度:128、192、256位),通常首先128位,其他的還有DESede等,jdk1.5種也提供了對對稱演算法的支持,以下例子使用AES演算法來加密:
/**
*PrivateExmaple.java
*Copyright 2005-2-16
*/
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.security.Key;
/**
*私鈅加密,保證消息機密性
*/
public class PrivateExample{
public static void main(String[] args) throws Exception{
if(args.length!=1){
System.err.println("Usage:java PrivateExample <text>");
System.exit(1);
}
byte[] plainText=args[0].getBytes("UTF8");
//通過KeyGenerator形成一個key
System.out.println("\nStart generate AES key");
KeyGenerator keyGen=KeyGenerator.getInstance("AES");
keyGen.init(128);
Key key=keyGen.generateKey();
System.out.println("Finish generating DES key");
//獲得一個私鈅加密類Cipher,ECB是加密方式,PKCS5Padding是填充方法
Cipher cipher=Cipher.getInstance("AES/ECB/PKCS5Padding");
System.out.println("\n"+cipher.getProvider().getInfo());
//使用私鈅加密
System.out.println("\nStart encryption:");
cipher.init(Cipher.ENCRYPT_MODE,key);
byte[] cipherText=cipher.doFinal(plainText);
System.out.println("Finish encryption:");
System.out.println(new String(cipherText,"UTF8"));
System.out.println("\nStart decryption:");
cipher.init(Cipher.DECRYPT_MODE,key);
byte[] newPlainText=cipher.doFinal(cipherText);
System.out.println("Finish decryption:");
System.out.println(new String(newPlainText,"UTF8"));
}
}
3)公鑰加密:
上面提到,私鑰加密需要一個共享的密鑰,那麼如何傳遞密鑰呢?web環境下,直接傳遞的話很容易被偵聽到,幸好有了公鑰加密的出現。公鑰加密也叫不對稱加密,不對稱演算法使用一對密鑰對,一個公鑰,一個私鑰,使用公鑰加密的數據,只有私鑰能解開(可用於加密);同時,使用私鑰加密的數據,只有公鑰能解開(簽名)。但是速度很慢(比私鑰加密慢100到1000倍),公鑰的主要演算法有RSA,還包括Blowfish,Diffie-Helman等,jdk1.5種提供了對RSA的支持,是一個改進的地方:
/**
*PublicExample.java
*Copyright 2005-2-16
*/
import java.security.Key;
import javax.crypto.Cipher;
import java.security.KeyPairGenerator;
import java.security.KeyPair;
/**
*一個簡單的公鈅加密例子,Cipher類使用KeyPairGenerator生成的公鈅和私鈅
*/
public class PublicExample{
public static void main(String[] args) throws Exception{
if(args.length!=1){
System.err.println("Usage:java PublicExample <text>");
System.exit(1);
}
byte[] plainText=args[0].getBytes("UTF8");
//構成一個RSA密鑰
System.out.println("\nStart generating RSA key");
KeyPairGenerator keyGen=KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024);
KeyPair key=keyGen.generateKeyPair();
System.out.println("Finish generating RSA key");
//獲得一個RSA的Cipher類,使用公鈅加密
Cipher cipher=Cipher.getInstance("RSA/ECB/PKCS1Padding");
System.out.println("\n"+cipher.getProvider().getInfo());
System.out.println("\nStart encryption");
cipher.init(Cipher.ENCRYPT_MODE,key.getPublic());
byte[] cipherText=cipher.doFinal(plainText);
System.out.println("Finish encryption:");
System.out.println(new String(cipherText,"UTF8"));
//使用私鈅解密
System.out.println("\nStart decryption");
cipher.init(Cipher.DECRYPT_MODE,key.getPrivate());
byte[] newPlainText=cipher.doFinal(cipherText);
System.out.println("Finish decryption:");
System.out.println(new String(newPlainText,"UTF8"));
}
}
4)數字簽名:
數字簽名,它是確定交換消息的通信方身份的第一個級別。上面A通過使用公鑰加密數據後發給B,B利用私鑰解密就得到了需要的數據,問題來了,由於都是使用公鑰加密,那麼如何檢驗是A發過來的消息呢?上面也提到了一點,私鑰是唯一的,那麼A就可以利用A自己的私鑰進行加密,然後B再利用A的公鑰來解密,就可以了;數字簽名的原理就基於此,而通常為了證明發送數據的真實性,通過利用消息摘要獲得簡短的消息內容,然後再利用私鑰進行加密散列數據和消息一起發送。java中為數字簽名提供了良好的支持,java.security.Signature類提供了消息簽名:
/**
*DigitalSignature2Example.java
*Copyright 2005-2-16
*/
import java.security.Signature;
import java.security.KeyPairGenerator;
import java.security.KeyPair;
import java.security.SignatureException;
/**
*數字簽名,使用RSA私鑰對對消息摘要簽名,然後使用公鈅驗證 測試
*/
public class DigitalSignature2Example{
public static void main(String[] args) throws Exception{
if(args.length!=1){
System.err.println("Usage:java DigitalSignature2Example <text>");
System.exit(1);
}
byte[] plainText=args[0].getBytes("UTF8");
//形成RSA公鑰對
System.out.println("\nStart generating RSA key");
KeyPairGenerator keyGen=KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024);
KeyPair key=keyGen.generateKeyPair();
System.out.println("Finish generating RSA key");
//使用私鈅簽名
Signature sig=Signature.getInstance("SHA1WithRSA");
sig.initSign(key.getPrivate());
sig.update(plainText);
byte[] signature=sig.sign();
System.out.println(sig.getProvider().getInfo());
System.out.println("\nSignature:");
System.out.println(new String(signature,"UTF8"));
//使用公鈅驗證
System.out.println("\nStart signature verification");
sig.initVerify(key.getPublic());
sig.update(plainText);
try{
if(sig.verify(signature)){
System.out.println("Signature verified");
}else System.out.println("Signature failed");
}catch(SignatureException e){
System.out.println("Signature failed");
}
}
}
5)數字證書。
還有個問題,就是公鑰問題,A用私鑰加密了,那麼B接受到消息後,用A提供的公鑰解密;那麼現在有個討厭的C,他把消息攔截了,然後用自己的私鑰加密,同時把自己的公鑰發給B,並告訴B,那是A的公鑰,結果....,這時候就需要一個中間機構出來說話了(相信權威,我是正確的),就出現了Certificate Authority(也即CA),有名的CA機構有Verisign等,目前數字認證的工業標準是:CCITT的X.509:
數字證書:它將一個身份標識連同公鑰一起進行封裝,並由稱為認證中心或 CA 的第三方進行數字簽名。
密鑰庫:java平台為你提供了密鑰庫,用作密鑰和證書的資源庫。從物理上講,密鑰庫是預設名稱為 .keystore 的文件(有一個選項使它成為加密文件)。密鑰和證書可以擁有名稱(稱為別名),每個別名都由唯一的密碼保護。密鑰庫本身也受密碼保護;您可以選擇讓每個別名密碼與主密鑰庫密碼匹配。
使用工具keytool,我們來做一件自我認證的事情吧(相信我的認證):
1、創建密鑰庫keytool -genkey -v -alias feiUserKey -keyalg RSA 默認在自己的home目錄下(windows系統是c:\documents and settings\<你的用戶名> 目錄下的.keystore文件),創建我們用 RSA 演算法生成別名為 feiUserKey 的自簽名的證書,如果使用了-keystore mm 就在當前目錄下創建一個密鑰庫mm文件來保存密鑰和證書。
2、查看證書:keytool -list 列舉了密鑰庫的所有的證書
也可以在dos下輸入keytool -help查看幫助。
3. Java2下Applet數字簽名實現方法
Java2下Applet數字簽名具體實現方法我的項目是使用APPLET製作一個實時消息隊列監控程序,由於涉及到了本地資源,對APPLET一定要進行數字簽名和認證。我使用的環境是WINDOWS2000,應用伺服器是WEBLOGIC6.0,開發環境是JBUILDER4.0。之前我提醒大家一定要注意伺服器端和客戶端的概念。那些文件應該在伺服器端,那些文件應該在客戶端。
首先在客戶端使用JRE1.3.0_01(JAVA運行環境1.3.0.1版本)以取代IE的JVM(JAVA虛擬機),可以到www.JAVA.SUN.COM網站上去下載,下載好了先在客戶端安裝好,安裝過程非常簡單。
在伺服器端的調用APPLET的HTML文件中也需要將它包含進來,以便沒有事先安裝JRE的客戶端下載,具體的寫法,請接著往下看;
具體步驟如下:
伺服器端:
1.將程序需要用到的各種包文件全部解壓(我這兒要用到WEBLOGIC的JMS包使用命令jar xf weblogicc.jar),然後使用JDK的打包命令將編譯好的監控程序.class和剛才解壓的包一起打包到一個包中。(前提我已經將監控程序和解開的包都放在同一個目錄下了),都是dos狀態下的命令,具體命令見jdk1.3(1.2)的bin目錄下,
命令如下:
jar cvf monitor.jar *.class
此命令生成一個名為monitor.jar的包
2.為剛才創建的包文件(monitor.jar)創建keystore和keys。其中,keystore將用來存放密匙(private keys)和公共鑰匙的認證,alias別名這兒取為monitor。
命令如下:
keytool -genkey -keystore monitor.keystore –alias monitor
此命令生成了一個名為monitor.keystore的keystore文件,接著這條命令,系統會問你好多問題,比如你的公司名稱,你的地址,你要設定的密碼等等,都由自己的隨便寫。
3.使用剛才生成的鑰匙來對jar文件進行簽名
命令如下:
jarsigner -keystore monitor.keystore monitor.jar monitor
這個命令將對monitor.jar文件進行簽名,不會生成新文件。
4.將公共鑰匙導入到一個cer文件中,這個cer文件就是要拷貝到客戶端的唯一文件 。
命令如下:
keytool -export -keystore monitor.keystore -alias monitor -file monitor.cer
此條命令將生成monitor.cer認證文件,當然這幾步都有可能問你剛才設置的密碼。這樣就完成了伺服器端的設置。這時你就可以將jar文件和keystore文件以及cer文件(我這兒是monitor.jar,monitor.keystore,monitor.cer)拷貝到伺服器的目錄下了,我用的是weblogic6.0,所以就拷貝到C:\bea\wlserver6.0\config\mydomain\applications\DefaultWebApp_myserver下的自己建的一個目錄下了。
客戶端:
1. 首先應該安裝jre1.3.0_01,然後將伺服器端生成的monitor.cer 文件拷貝到jre的特定目錄下,我這兒是:
c:\program files\javasoft\jre\1.3.0_01\lib\security目錄下。
2. 將公共鑰匙倒入到jre的cacerts(這是jre的默認keystore)
命令如下:
keytool -import -alias monitor -file monitor.cer
-keystore cacerts
注意這兒要你輸入的是cacerts的密碼,應該是changeit,而不是你自己設定的keystore的密碼。
3. 修改policy策略文件,在dos狀態下使用命令 policytool
系統會自動彈出一個policytool的對話框,如圖4所示,在這裡面首先選擇file菜單的open項,打開c:\program files\javasoft\jre\1.3.0_01\lib\security目錄下的java.poliy文件,然後在edit菜單中選擇Change keystore ,在對話框中new keystore url:中輸入
file:/c:/program files /javasoft/jre/1.3.0_01/lib/security/cacerts, 這兒要注意反斜杠,在new keystore type 中輸入JKS,這是cacerts的固定格式,然後單擊Add Policy Entry,在出現的對話框中CodeBase中輸入:
http://URL:7001/*
其中的URL是伺服器的IP地址,7001是我的weblogic的埠,如果你是在別的應用伺服器上比如說是apache,那埠號就可以省略掉。
在SignedBy中輸入(別名alias):這兒是Monitor然後單擊add peimission按鈕,在出現的對話框中permission中選擇你想給這個applet的許可權,這兒具體有許多許可權,讀者可以自己找資料看看。我這兒就選用allpeimission,右邊的signedBy中輸入別名:monitor
最後保存,在file菜單的save項。
當然你可以看見我已經對多個包實現了簽名認證。
這樣客戶端的設置就完成了。在客戶端用ie運行該applet程序時,會詢問你是不是對該簽名授權,選擇授權後,包會自動從伺服器下載到本地計算機,而且ie會自動啟動jre,在右下欄中可以看見,相當於ie的java控制台。
4.調用applet的html文件
大家都知道由於java2的安全性,對applet的正常調用的html文件已經不能再使用了,而改為ActiveX類型的調用。具體的又分ie和nescape的不同寫法,這一些在sun網上都能找到現成的教程。我就不多說了,只是將我的這個小程序為ie寫的的html給大家看看。
<html>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=gb2312">
<center>
<h3>消息中心實時監控平台</h3>
<hr>
<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
width="900" height="520" align="baseline" codebase="http://192.168.2.217:7001/j2re-1_3_0_01-win-i.exe#Version=1,3,0,0">
<PARAM NAME="java_code" VALUE="wise.monitor.applet.monitorApplet">
<PARAM NAME="java_codebase" VALUE="monitor/classes">
<PARAM NAME="java_type" VALUE="application/x-java-applet;version=1.3">
<PARAM NAME="ARCHIVE" VALUE="monitor.jar" >
<PARAM NAME="scriptable" VALUE="true">
</OBJECT>
</center>
</html>
其中我要強調一點,因為applet每一次的改動都需要重新打包簽名,手續非常繁瑣,所以在具體的實現中要將一些會變化參數放到html文件中來,傳到applet中去,這一點網上文章好多,自己去看吧。
另外一個就是有朋友問我,那這樣不是太麻煩了,每一個客戶端都要進行復雜的dos命令操作,我只能說一目前我的水平只能將一個已經做好的客戶端文件cer文件和java.policy以及cacerts文件直接拷貝到客戶端,當然這也有缺陷,如果別人的計算機已經有了認證,就會丟失。就這些問題我們可以一起探討。
另外還有一點優化,就是在打包的時候,我這兒只講了把所有要用的涉及到安全性的包和源程序到要打到一個包中。這樣如果包非常大的話,會非常影響下載的速度,如果可以使用本地計算機的包就好了,這一點jre也做到了,具體的要到控制面板的jre控制台上去設置。這個就留著讀者自己去摸索吧。
結束語
我發現網上java相關的資料非常少,中文的更少,所以希望自己能將一些小知識和大家共享,省掉許多重復的無用功。如果大家對這個問題還有不清楚的地方,或者就這問題相進一步展開討論的,請和我聯系,我的信箱是[email protected]。希望我們能共同進步!
http://java.chinaitlab.com/advance/520330.html
4. cryptapi結合java進行數字簽名與驗證簽名的困惑
程序沒問題,,應該是其它的問題吧
5. java如何對pdf文件實現數字簽名
用Spire.Doc for Java 可以添加及驗證數字簽名,參考代碼:
importcom.spire.pdf.*;
importcom.spire.pdf.graphics.PdfImage;
importcom.spire.pdf.graphics.PdfTrueTypeFont;
importcom.spire.pdf.security.GraphicMode;
importcom.spire.pdf.security.PdfCertificate;
importcom.spire.pdf.security.PdfCertificationFlags;
importcom.spire.pdf.security.PdfSignature;
importjava.awt.*;
importjava.awt.geom.Point2D;
importjava.awt.geom.Rectangle2D;
publicclassAddCertificate{
publicstaticvoidmain(String[]args){
//載入PDF文檔
PdfDocumentdoc=newPdfDocument();
doc.loadFromFile("test.pdf");
//載入pfx證書,及證書秘鑰
PdfCertificatecert=newPdfCertificate("Cermia.pfx","123654yes!");
//添加數字簽名到指定頁面,並設置其位置和大小
PdfSignaturesignature=newPdfSignature(doc,doc.getPages().get(2),cert,"MySignature");
Rectangle2Drect=newRectangle2D.Float();
rect.setFrame(newPoint2D.Float((float)doc.getPages().get(0).getActualSize().getWidth()-340,(float)doc.getPages().get(0).getActualSize().getHeight()-230),newDimension(280,150));
signature.setBounds(rect);
//設置簽名為圖片加文本模式
signature.setGraphicMode(GraphicMode.Sign_Image_And_Sign_Detail);
//設置簽名的內容
signature.setNameLabel("簽字者:");
signature.setName("Mia");
signature.setContactInfoLabel("聯系電話:");
signature.setContactInfo("02881705109");
signature.setDateLabel("日期:");
signature.setDate(newjava.util.Date());
signature.setLocationInfoLabel("地點:");
signature.setLocationInfo("成都");
signature.setReasonLabel("原因:");
signature.setReason("文檔所有者");
signature.setDistinguishedNameLabel("DN:");
signature.setDistinguishedName(signature.getCertificate().get_IssuerName().getName());
signature.setSignImageSource(PdfImage.fromFile("sign.png"));
//設置簽名的字體
signature.setSignDetailsFont(newPdfTrueTypeFont(newFont("ArialUnicodeMS",Font.PLAIN,9)));
//設置文檔許可權為禁止更改
signature.setDocumentPermissions(PdfCertificationFlags.Forbid_Changes);
signature.setCertificated(true);
//保存文檔
doc.saveToFile("AddSignature.pdf");
doc.close();
}
}
數字簽名添加效果:
數字簽名效果
參考原文
6. java中簽名是什麼意思
簽名一般是使用公私密鑰對。自己使用私鑰加密,其他人可以任意獲取到公鑰用來解密,既然解出來了,就說明是私鑰加密的。 用私鑰加密的過程叫做簽名。
當然實際過程沒這么簡單,還包括,找個合適的第三方再次簽名公鑰已證明公鑰的安全性等。不過只要知道上面的東西基本就可以了。
7. java 數字簽名自驗證該如何實現
沒有看到所謂的簽名自驗證的說法。 我想你指的應該是數字簽名自帶證書,然後用證書來驗證簽名吧。
其實這是一種簽名的格式。被稱為P7。 就是在信息中包含長度,演算法,明文,簽名串和證書公鑰。 收到以後,可以自動用證書來驗證。 這些演算法很多。你可以去找,很容易查到。
這種簽名的關鍵是證書也需要被驗證。這種做法一般是雙方擁有發證CA的公鑰,來驗證證書的合法性。這也有很多的。
8. 用java怎麼實現CA頒發的數字證書的認證功能
PKI 目前使用最多的非對稱演算法是 RSA。對於基於 RSA 的 PKI 而言,CA 應有一對 RSA 的公私鑰對,私鑰是 CA 的生命,嚴格保密,而公鑰則發布給使用方。CA 簽發一張證書的話,主要是使用 CA 的 RSA 私鑰對證書進行簽名,並將簽名結果保存在證書當中。使用者通過 CA 發布的公鑰來驗證證書中的簽名值,就可以確定該證書是否是由該 CA 簽發的。自己要做的就是從證書中提取簽名數據和用於簽名的原始數據,再使用 CA 的公鑰驗證這個簽名就可以了。
9. java 怎麼驗證文件為數字簽名認證文件
1)從密鑰庫中讀取CA的證書
FileInputStream in=new FileInputStream(".keystore");
KeyStore ks=KeyStore.getInstance("JKS");
ks.load(in,storepass.toCharArray());
java.security.cert.Certificate c1=ks.getCertificate("caroot");
(2)從密鑰庫中讀取CA的私鑰
PrivateKey caprk=(PrivateKey)ks.getKey(alias,cakeypass.toCharArray());
(3)從CA的證書中提取簽發者的信息
byte[] encod1=c1.getEncoded(); 提取CA證書的編碼
X509CertImpl cimp1=new X509CertImpl(encod1); 用該編碼創建X509CertImpl類型對象
X509CertInfo cinfo1=(X509CertInfo)cimp1.get(X509CertImpl.NAME+"."+X509CertImpl.INFO); 獲取X509CertInfo對象
X500Name issuer=(X500Name)cinfo1.get(X509CertInfo.SUBJECT+"."+CertificateIssuerName.DN_NAME); 獲取X509Name類型的簽發者信息
(4)獲取待簽發的證書
CertificateFactory cf=CertificateFactory.getInstance("X.509");
FileInputStream in2=new FileInputStream("user.csr");
java.security.cert.Certificate c2=cf.generateCertificate(in);
(5)從待簽發的證書中提取證書信息
byte [] encod2=c2.getEncoded();
X509CertImpl cimp2=new X509CertImpl(encod2); 用該編碼創建X509CertImpl類型對象
X509CertInfo cinfo2=(X509CertInfo)cimp2.get(X509CertImpl.NAME+"."+X509CertImpl.INFO); 獲取X509CertInfo對象
(6)設置新證書有效期
Date begindate=new Date(); 獲取當前時間
Date enddate=new Date(begindate.getTime()+3000*24*60*60*1000L); 有效期為3000天
CertificateValidity cv=new CertificateValidity(begindate,enddate); 創建對象
cinfo2.set(X509CertInfo.VALIDITY,cv); 設置有效期
(7)設置新證書序列號
int sn=(int)(begindate.getTime()/1000); 以當前時間為序列號
CertificateSerialNumber csn=new CertificateSerialNumber(sn);
cinfo2.set(X509CertInfo.SERIAL_NUMBER,csn);
(8)設置新證書簽發者
cinfo2.set(X509CertInfo.ISSUER+"."+CertificateIssuerName.DN_NAME,issuer);應用第三步的結果
(9)設置新證書簽名演算法信息
AlgorithmId algorithm=new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
cinfo2.set(CertificateAlgorithmId.NAME+"."+CertificateAlgorithmId.ALGORITHM,algorithm);
(10)創建證書並使用CA的私鑰對其簽名
X509CertImpl newcert=new X509CertImpl(cinfo2);
newcert.sign(caprk,"MD5WithRSA"); 使用CA私鑰對其簽名
(11)將新證書寫入密鑰庫
ks.setCertificateEntry("lf_signed",newcert);
FileOutputStream out=new FileOutputStream("newstore");
ks.store(out,"newpass".toCharArray()); 這里是寫入了新的密鑰庫,也可以使用第七條來增加條目
10. 電子簽名用Java怎麼實現
importjava.security.InvalidKeyException;
importjava.security.Key;
importjava.security.KeyPair;
importjava.security.KeyPairGenerator;
importjava.security.NoSuchAlgorithmException;
importjava.security.PrivateKey;
importjava.security.PublicKey;
importjava.security.SecureRandom;
importjava.security.Signature;
importjava.security.SignatureException;
importjava.util.logging.Level;
importjava.util.logging.Logger;
/**
*ECDSA160bit簽名及簽名驗證例子
*/
publicclassECDSASignature{
publicstaticvoidmain(Stringargv[]){
signatureTest();
}
publicstaticvoidsignatureTest(){
/**
*密鑰對生成
*/
=null;
try{
keyPairGenerator=KeyPairGenerator.getInstance("EC");
}catch(NoSuchAlgorithmExceptionex){
return;
}
SecureRandomsecureRandom=newSecureRandom();
keyPairGenerator.initialize(160,secureRandom);
KeyPairpair=keyPairGenerator.generateKeyPair();
KeypublicKey=pair.getPublic();
KeyprivateKey=pair.getPrivate();
//字元串
Stringhako="test";
/**
*私鑰簽名(ECDSA160bit)
*/
byte[]sign=null;
try{
SignaturesignatureSign=null;
signatureSign=Signature.getInstance("NONEwithECDSA");
signatureSign.initSign((PrivateKey)privateKey,secureRandom);
signatureSign.update(hako.getBytes());
sign=signatureSign.sign();
System.out.println("sign:"+newString(sign));
}catch(InvalidKeyException|NoSuchAlgorithmException|SignatureExceptionex){
Logger.getLogger(ECDSASignature.class.getName()).log(Level.SEVERE,null,ex);
}
/**
*用公鑰進行簽名驗證
*/
SignaturesignatureVerify=null;
try{
signatureVerify=Signature.getInstance("NONEwithECDSA");
signatureVerify.initVerify((PublicKey)publicKey);
signatureVerify.update(hako.getBytes());
booleanverifyResult=signatureVerify.verify(sign);
System.out.println(verifyResult?"簽名OK":"簽名NG");
}catch(NoSuchAlgorithmException|InvalidKeyException|SignatureExceptione){
Logger.getLogger(ECDSASignature.class.getName()).log(Level.SEVERE,null,e);
}
}
}
http://www.huuinn.com/java-%E7%94%B5%E5%AD%90%E7%AD%BE%E5%90%8D%E8%8C%83%E4%BE%8B%E4%BB%A3%E7%A0%81/