zoukankan      html  css  js  c++  java
  • Java对文件添加数字签名

    一:需要包含的包
        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("输出证书信息: "+c.toString());
        System.out.println("版本号:"+t.getVersion());
        System.out.println("序列号:"+t.getSerialNumber().toString(16));
        System.out.println("主体名:"+t.getSubjectDN());
        System.out.println("签发者:"+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;i<pkenc.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);获取别名对应条目的证书链
        PrivateKey pk=(PrivateKey)ks.getKey(alias,oldkeypass.toCharArray());获取别名对应条目的私钥
        ks.setKeyEntry(alias,pk,newkeypass.toCharArray(),cchain);向密钥库中添加条目
        第一个参数指定所添加条目的别名,假如使用已存在别名将覆盖已存在条目,使用新别名将增加一个新条目,第二个参数为条目的私钥,第三个为设置的新口令,第四个为该私钥的公钥的证书链
        FileOutputStream output=new FileOutputStream("another");
        ks.store(output,storepass.toCharArray())将keystore对象内容写入新文件

    八:JAVA程序检验别名和删除条目
        FileInputStream in=new FileInputStream(".keystore");
        KeyStore ks=KeyStore.getInstance("JKS");
        ks.load(in,storepass.toCharArray());
        ks.containsAlias("sage");检验条目是否在密钥库中,存在返回true
        ks.deleteEntry("sage");删除别名对应的条目
        FileOutputStream output=new FileOutputStream(".keystore");
        ks.store(output,storepass.toCharArray())将keystore对象内容写入文件,条目删除成功

    九: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()); 这里是写入了新的密钥库,也可以使用第七条来增加条目

    十:数字证书的检验
        (1)验证证书的有效期
    (a)获取X509Certificate类型对象
    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)检验有效性
    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)验证证书签名的有效性
    (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)获取待检验的证书(上步已经获取了,就是C1)
    (c)检验证书
             boolean pass=false;
             try{
          c1.verify(pbk);
                 pass=true;
             }catch(Exception e){
                 pass=false;
                 System.out.println(e);
    }

  • 相关阅读:
    241. Different Ways to Add Parentheses java solutions
    89. Gray Code java solutions
    367. Valid Perfect Square java solutions
    46. Permutations java solutions
    116. Populating Next Right Pointers in Each Node java solutions
    153. Find Minimum in Rotated Sorted Array java solutions
    判断两颗树是否相同
    求二叉树叶子节点的个数
    求二叉树第k层的结点个数
    将二叉排序树转换成排序的双向链表
  • 原文地址:https://www.cnblogs.com/srluv/p/java_szqm.html
Copyright © 2011-2022 走看看