一:需要包含的包
成都創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都做網(wǎng)站、網(wǎng)站建設(shè)、外貿(mào)營銷網(wǎng)站建設(shè)、阿巴嘎網(wǎng)絡(luò)推廣、重慶小程序開發(fā)、阿巴嘎網(wǎng)絡(luò)營銷、阿巴嘎企業(yè)策劃、阿巴嘎品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);成都創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供阿巴嘎建站搭建服務(wù),24小時(shí)服務(wù)熱線:028-86922220,官方網(wǎng)址:www.cdcxhl.com
import java.security.*;
import java.io.*;
import java.util.*;
import java.security.*;
import java.security.cert.*;
import sun.security.x509.*
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
二:從文件中讀取證書
用keytool將.keystore中的證書寫入文件中,然后從該文件中讀取證書信息
CertificateFactory cf=CertificateFactory.getInstance("X.509");
FileInputStream in=new FileInputStream("out.csr");
Certificate c=cf.generateCertificate(in);
String s=c.toString();
三:從密鑰庫中直接讀取證書
String pass="123456";
FileInputStream in=new FileInputStream(".keystore");
KeyStore ks=KeyStore.getInstance("JKS");
ks.load(in,pass.toCharArray());
java.security.cert.Certificate c=ks.getCertificate(alias);//alias為條目的別名
四:JAVA程序中顯示證書指定信息
System.out.println("輸出證書信息:\n"+c.toString());
System.out.println("版本號(hào):"+t.getVersion());
System.out.println("序列號(hào):"+t.getSerialNumber().toString(16));
System.out.println("主體名:"+t.getSubjectDN());
System.out.println("簽發(fā)者:"+t.getIssuerDN());
System.out.println("有效期:"+t.getNotBefore());
System.out.println("簽名算法:"+t.getSigAlgName());
byte [] sig=t.getSignature();//簽名值
PublicKey pk=t.getPublicKey();
byte [] pkenc=pk.getEncoded();
System.out.println("公鑰");
for(int i=0;ipkenc.length;i++)System.out.print(pkenc[i]+",");
五:JAVA程序列出密鑰庫所有條目
String pass="123456";
FileInputStream in=new FileInputStream(".keystore");
KeyStore ks=KeyStore.getInstance("JKS");
ks.load(in,pass.toCharArray());
Enumeration e=ks.aliases();
while(e.hasMoreElements())
java.security.cert.Certificate c=ks.getCertificate((String)e.nextElement());
六:JAVA程序修改密鑰庫口令
String oldpass="123456";
String newpass="654321";
FileInputStream in=new FileInputStream(".keystore");
KeyStore ks=KeyStore.getInstance("JKS");
ks.load(in,oldpass.toCharArray());
in.close();
FileOutputStream output=new FileOutputStream(".keystore");
ks.store(output,newpass.toCharArray());
output.close();
七:JAVA程序修改密鑰庫條目的口令及添加條目
FileInputStream in=new FileInputStream(".keystore");
KeyStore ks=KeyStore.getInstance("JKS");
ks.load(in,storepass.toCharArray());
Certificate [] cchain=ks.getCertificate(alias);獲取別名對(duì)應(yīng)條目的證書鏈
PrivateKey pk=(PrivateKey)ks.getKey(alias,oldkeypass.toCharArray());獲取別名對(duì)應(yīng)條目的私鑰
ks.setKeyEntry(alias,pk,newkeypass.toCharArray(),cchain);向密鑰庫中添加條目
第一個(gè)參數(shù)指定所添加條目的別名,假如使用已存在別名將覆蓋已存在條目,使用新別名將增加一個(gè)新條目,第二個(gè)參數(shù)為條目的私鑰,第三個(gè)為設(shè)置的新口令,第四個(gè)為該私鑰的公鑰的證書鏈
FileOutputStream output=new FileOutputStream("another");
ks.store(output,storepass.toCharArray())將keystore對(duì)象內(nèi)容寫入新文件
八:JAVA程序檢驗(yàn)別名和刪除條目
FileInputStream in=new FileInputStream(".keystore");
KeyStore ks=KeyStore.getInstance("JKS");
ks.load(in,storepass.toCharArray());
ks.containsAlias("sage");檢驗(yàn)條目是否在密鑰庫中,存在返回true
ks.deleteEntry("sage");刪除別名對(duì)應(yīng)的條目
FileOutputStream output=new FileOutputStream(".keystore");
ks.store(output,storepass.toCharArray())將keystore對(duì)象內(nèi)容寫入文件,條目刪除成功
九:JAVA程序簽發(fā)數(shù)字證書
(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的證書中提取簽發(fā)者的信息
byte[] encod1=c1.getEncoded(); 提取CA證書的編碼
X509CertImpl cimp1=new X509CertImpl(encod1); 用該編碼創(chuàng)建X509CertImpl類型對(duì)象
X509CertInfo cinfo1=(X509CertInfo)cimp1.get(X509CertImpl.NAME+"."+X509CertImpl.INFO); 獲取X509CertInfo對(duì)象
X500Name issuer=(X500Name)cinfo1.get(X509CertInfo.SUBJECT+"."+CertificateIssuerName.DN_NAME); 獲取X509Name類型的簽發(fā)者信息
(4)獲取待簽發(fā)的證書
CertificateFactory cf=CertificateFactory.getInstance("X.509");
FileInputStream in2=new FileInputStream("user.csr");
java.security.cert.Certificate c2=cf.generateCertificate(in);
(5)從待簽發(fā)的證書中提取證書信息
byte [] encod2=c2.getEncoded();
X509CertImpl cimp2=new X509CertImpl(encod2); 用該編碼創(chuàng)建X509CertImpl類型對(duì)象
X509CertInfo cinfo2=(X509CertInfo)cimp2.get(X509CertImpl.NAME+"."+X509CertImpl.INFO); 獲取X509CertInfo對(duì)象
(6)設(shè)置新證書有效期
Date begindate=new Date(); 獲取當(dāng)前時(shí)間
Date enddate=new Date(begindate.getTime()+3000*24*60*60*1000L); 有效期為3000天
CertificateValidity cv=new CertificateValidity(begindate,enddate); 創(chuàng)建對(duì)象
cinfo2.set(X509CertInfo.VALIDITY,cv); 設(shè)置有效期
(7)設(shè)置新證書序列號(hào)
int sn=(int)(begindate.getTime()/1000); 以當(dāng)前時(shí)間為序列號(hào)
CertificateSerialNumber csn=new CertificateSerialNumber(sn);
cinfo2.set(X509CertInfo.SERIAL_NUMBER,csn);
(8)設(shè)置新證書簽發(fā)者
cinfo2.set(X509CertInfo.ISSUER+"."+CertificateIssuerName.DN_NAME,issuer);應(yīng)用第三步的結(jié)果
(9)設(shè)置新證書簽名算法信息
AlgorithmId algorithm=new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
cinfo2.set(CertificateAlgorithmId.NAME+"."+CertificateAlgorithmId.ALGORITHM,algorithm);
(10)創(chuàng)建證書并使用CA的私鑰對(duì)其簽名
X509CertImpl newcert=new X509CertImpl(cinfo2);
newcert.sign(caprk,"MD5WithRSA"); 使用CA私鑰對(duì)其簽名
(11)將新證書寫入密鑰庫
ks.setCertificateEntry("lf_signed",newcert);
FileOutputStream out=new FileOutputStream("newstore");
ks.store(out,"newpass".toCharArray()); 這里是寫入了新的密鑰庫,也可以使用第七條來增加條目
十:數(shù)字證書的檢驗(yàn)
(1)驗(yàn)證證書的有效期
(a)獲取X509Certificate類型對(duì)象
CertificateFactory cf=CertificateFactory.getInstance("X.509");
FileInputStream in1=new FileInputStream("aa.crt");
java.security.cert.Certificate c1=cf.generateCertificate(in1);
X509Certificate t=(X509Certificate)c1;
in2.close();
(b)獲取日期
Date TimeNow=new Date();
(c)檢驗(yàn)有效性
try{
t.checkValidity(TimeNow);
System.out.println("OK");
}catch(CertificateExpiredException e){ //過期
System.out.println("Expired");
System.out.println(e.getMessage());
}catch((CertificateNotYetValidException e){ //尚未生效
System.out.println("Too early");
System.out.println(e.getMessage());}
(2)驗(yàn)證證書簽名的有效性
(a)獲取CA證書
CertificateFactory cf=CertificateFactory.getInstance("X.509");
FileInputStream in2=new FileInputStream("caroot.crt");
java.security.cert.Certificate cac=cf.generateCertificate(in2);
in2.close();
(c)獲取CA的公鑰
PublicKey pbk=cac.getPublicKey();
(b)獲取待檢驗(yàn)的證書(上步已經(jīng)獲取了,就是C1)
(c)檢驗(yàn)證書
boolean pass=false;
try{
c1.verify(pbk);
pass=true;
}catch(Exception e){
pass=false;
System.out.println(e);
}
用Spire.Doc? for Java 可以添加及驗(yàn)證數(shù)字簽名,參考代碼:
import?com.spire.pdf.*;
import?com.spire.pdf.graphics.PdfImage;
import?com.spire.pdf.graphics.PdfTrueTypeFont;
import?com.spire.pdf.security.GraphicMode;
import?com.spire.pdf.security.PdfCertificate;
import?com.spire.pdf.security.PdfCertificationFlags;
import?com.spire.pdf.security.PdfSignature;
import?java.awt.*;
import?java.awt.geom.Point2D;
import?java.awt.geom.Rectangle2D;
public?class?AddCertificate?{
public?static?void?main(String[]args){
//加載PDF文檔
PdfDocument?doc?=?new?PdfDocument();
doc.loadFromFile("test.pdf");
//加載pfx證書,及證書秘鑰
PdfCertificate?cert?=?new?PdfCertificate("Cermia.pfx","123654yes!");
//添加數(shù)字簽名到指定頁面,并設(shè)置其位置和大小
PdfSignature?signature?=?new?PdfSignature(doc,?doc.getPages().get(2),?cert,?"MySignature");
Rectangle2D?rect?=?new?Rectangle2D.Float();
rect.setFrame(new?Point2D.Float((float)?doc.getPages().get(0).getActualSize().getWidth()?-?340,?(float)?doc.getPages().get(0).getActualSize().getHeight()?-?230),?new?Dimension(280,?150));
signature.setBounds(rect);
//設(shè)置簽名為圖片加文本模式
signature.setGraphicMode(GraphicMode.Sign_Image_And_Sign_Detail);
//設(shè)置簽名的內(nèi)容
signature.setNameLabel("簽字者:");
signature.setName("Mia");
signature.setContactInfoLabel("聯(lián)系電話:");
signature.setContactInfo("02881705109");
signature.setDateLabel("日期:");
signature.setDate(new?java.util.Date());
signature.setLocationInfoLabel("地點(diǎn):");
signature.setLocationInfo("成都");
signature.setReasonLabel("原因:");
signature.setReason("文檔所有者");
signature.setDistinguishedNameLabel("DN:?");
signature.setDistinguishedName(signature.getCertificate().get_IssuerName().getName());
signature.setSignImageSource(PdfImage.fromFile("sign.png"));
//設(shè)置簽名的字體
signature.setSignDetailsFont(new?PdfTrueTypeFont(new?Font("Arial?Unicode?MS",?Font.PLAIN,?9)));
//設(shè)置文檔權(quán)限為禁止更改
signature.setDocumentPermissions(PdfCertificationFlags.Forbid_Changes);
signature.setCertificated(true);
//保存文檔
doc.saveToFile("AddSignature.pdf");
doc.close();
}
}
數(shù)字簽名添加效果:
數(shù)字簽名效果
參考原文
生成簽名以后的URL的示例代碼如下:
// Generate a presigned URL
Date expires = new Date (new Date().getTime() + 1000 * 60); // 1 minute to expire
GeneratePresignedUrlRequest generatePresignedUrlRequest =
new GeneratePresignedUrlRequest(bucketName, key);
generatePresignedUrlRequest.setExpiration(expires);
URL url = client.generatePresignedUrl(generatePresignedUrlRequest);
System.out.println(url.toString());
這段代碼假定指定bucketName和key的Object已經(jīng)上傳到OSS,用戶可以根據(jù)修改設(shè)定expires,即過期時(shí)間。更詳細(xì)的操作可以參考OSSClient#generatePresignedUrl方法和GeneratePresignedUrlRequest類的幫助。