码迷,mamicode.com
首页 > 编程语言 > 详细

如何用JAVA代码签发数字证书

时间:2015-11-15 01:04:59      阅读:412      评论:0      收藏:0      [点我收藏+]

标签:

用JAVA签发数字证书

打开cmd

1.输入D:

2.输入cd keys

3.输入命令查看创建的密钥库的证书列表

keytool -list -v -keystore mykey.keystore -storepass 123456

 4. 之前导出过server.cer文件,把这个文件安装到操作系统,过程默认。

 

5.创建一个密钥对,和之前一样,输入如下命令:

 

--创建密钥对

keytool -genkey -dname "CN=tmp, OU=NC, O=Shanghai University, L=ZB, ST=Shanghai,C=CN" -alias client  -keyalg RSA -keystore myclientkey.store -keypass 654321 -storepass 654321 -validity 1000

 

--导出公钥

keytool -export -trustcacerts -alias client  -file client.cer -keystore  myclientkey.store -storepass 654321

 

双击client.cer可以看到:



 该证书不被系统信任,且颁发者和颁发给都是tmp

 

5.签发证书,这里采用的是JAVA程序来签发。可以用OPENSSL签发或者到正式CA机构签发。

 

由于已经把server.cer安装到客户机电脑上,所以客户机操作系统会信任server.cer中的机构签发的证书。

 

这里就用server.cer中的机构来签发client.cer

 

签发代码:

package com.syspro.test;  

  

import java.io.*;  

import java.security.*;  

import java.security.cert.*;  

import java.util.*;  

import java.math.*;  

import sun.security.x509.*;  

public class SignCert {  

      

    private String mKeystore = "D:/keys/mykey.keystore"; // 密锁库路径  

    private char[] mKeystorePass = "123456".toCharArray();// 密锁库密码  

    private char[] mSignPrivateKeyPass = "123456".toCharArray();// 取得签发者私锁所需的密码  

    private String mSignCertAlias = "keytest";// 签发者别名  

    private String mSignedCert = "D:/keys/client.cer"; // 被签证书  

    private String mNewCert = "D:/keys/clientSignKey.cer"; // 签发后的新证书全名  

    private int mValidityDay = 3000; // 签发后的新证书有效期(天)  

    private PrivateKey mSignPrivateKey = null;// 签发者的私锁  

    private X509CertInfo mSignCertInfo = null;// 签发证书信息  

    private X509CertInfo mSignedCertInfo = null;// 被签证书信息  

         

     public void  Sign() throws Exception{  

            try {  

                /** 

                 * 证书签名 

                 */  

                getSignCertInfo(); // 获取签名证书信息  

                signCertificate(); // 用签名证书信息签发待签名证书  

                createNewCertificate(); // 创建并保存签名后的新证书  

            } catch (Exception e) {  

                System.out.println("Error:" + e.getMessage());  

            }  

     }  

       

     /** 

     * 取得签名证书信息 

     * @throws Exception 

     */  

     private void getSignCertInfo() throws Exception  

     {  

     FileInputStream vFin=null;  

     KeyStore vKeyStore=null;  

     java.security.cert.Certificate vCert=null;  

     X509CertImpl vCertImpl=null;  

     byte[] vCertData=null;  

  

     //获取签名证书密锁库  

     vFin=new FileInputStream(mKeystore);   

     vKeyStore=KeyStore.getInstance("JKS");  

     vKeyStore.load(vFin,mKeystorePass);  

     //获取签名证书  

     vCert= vKeyStore.getCertificate(mSignCertAlias);  

     vCertData=vCert.getEncoded();  

     vCertImpl=new X509CertImpl(vCertData);  

     //获取签名证书信息  

     mSignCertInfo=(X509CertInfo)vCertImpl.get(X509CertImpl.NAME+"."+X509CertImpl.INFO);  

     mSignPrivateKey=(PrivateKey)vKeyStore.getKey(mSignCertAlias,mSignPrivateKeyPass);  

     vFin.close();  

     }  

  

  

  

    /** 

     * 取得待签证书信息,并签名待签证书 

     *  

     * @throws Exception 

     */  

    private void signCertificate() throws Exception {  

        FileInputStream vFin = null;  

        java.security.cert.Certificate vCert = null;  

        CertificateFactory vCertFactory = null;  

        byte[] vCertData = null;  

        X509CertImpl vCertImpl = null;  

  

        // 获取待签名证书  

        vFin = new FileInputStream(mSignedCert);  

        vCertFactory = CertificateFactory.getInstance("X.509");  

        vCert = vCertFactory.generateCertificate(vFin);  

        vFin.close();  

        vCertData = vCert.getEncoded();  

        // 设置签名证书信息:有效日期、序列号、签名者、数字签名算发  

        vCertImpl = new X509CertImpl(vCertData);  

        mSignedCertInfo = (X509CertInfo) vCertImpl.get(X509CertImpl.NAME + "."  

                + X509CertImpl.INFO);  

        mSignedCertInfo.set(X509CertInfo.VALIDITY, getCertValidity());  

        mSignedCertInfo.set(X509CertInfo.SERIAL_NUMBER, getCertSerualNumber());  

        mSignedCertInfo.set(X509CertInfo.ISSUER + "."  

                + CertificateIssuerName.DN_NAME,  

                mSignCertInfo.get(X509CertInfo.SUBJECT + "."  

                        + CertificateIssuerName.DN_NAME));  

        mSignedCertInfo.set(CertificateAlgorithmId.NAME + "."  

                + CertificateAlgorithmId.ALGORITHM, getAlgorithm());  

  

    }  

  

    /** 

     * 待签签证书被签名后,保存新证书 

     *  

     * @throws Exception 

     */  

    private void createNewCertificate() throws Exception {  

        FileOutputStream vOut = null;  

        X509CertImpl vCertImpl = null;  

        // 用新证书信息封成为新X.509证书  

        vCertImpl = new X509CertImpl(mSignedCertInfo);  

        // 生成新正书验证码  

        vCertImpl.sign(mSignPrivateKey, "MD5WithRSA");  

        vOut = new FileOutputStream(mNewCert );  

        // 保存为der编码二进制X.509格式证书  

        vCertImpl.derEncode(vOut);  

        vOut.close();  

  

    }  

  

    // 辅助方法===========================================================================  

  

    /** 

     * 得到新证书有效日期 

     *  

     * @throws Exception 

     * @return CertificateValidity 

     */  

    private CertificateValidity getCertValidity() throws Exception {  

        long vValidity = (60 * 60 * 24 * 1000L) * mValidityDay;  

        Calendar vCal = null;  

        Date vBeginDate = null, vEndDate = null;  

        vCal = Calendar.getInstance();  

        vBeginDate = vCal.getTime();  

        vEndDate = vCal.getTime();  

        vEndDate.setTime(vBeginDate.getTime() + vValidity);  

        return new CertificateValidity(vBeginDate, vEndDate);  

    }  

  

    /** 

     * 得到新证书的序列号 

     *  

     * @return CertificateSerialNumber 

     */  

    private CertificateSerialNumber getCertSerualNumber() {  

        Calendar vCal = null;  

        vCal = Calendar.getInstance();  

        int vSerialNum = 0;  

        vSerialNum = (int) (vCal.getTimeInMillis() / 1000);  

        return new CertificateSerialNumber(vSerialNum);  

    }  

  

    /** 

     * 得到新证书的签名算法 

     *  

     * @return AlgorithmId 

     */  

    private AlgorithmId getAlgorithm() {  

        AlgorithmId vAlgorithm = new AlgorithmId(  

                AlgorithmId.md5WithRSAEncryption_oid);  

        return vAlgorithm;  

    }  

      

    public static void main(String args[]) throws UnsupportedEncodingException  

    {  

        SignCert s = new SignCert();  

        try {  

            s.Sign();  

        } catch (Exception e) {  

            e.printStackTrace();  

        }  

    }  

  

}   

 打开签名完成后的新证书clientSignKey.cer,如下图:

 



 会看到此时,操作系统会信任该证书,而且颁发者变成了server.cer中的localhost

 

再将签名后的数字证书clientSignKey.cer和CA证书server.cer导入myclientkey.store库中,命令如下:注意先后顺序

先倒入CA证书

keytool -import -alias ca -keystore D:\keys\myclientkey.store  -trustcacerts -file D:\keys\server.cer -storepass 654321

注意-alias 和之前的不一样。

再导入签名后的证书:

keytool -import -alias client -keystore D:\keys\myclientkey.store  -trustcacerts -file D:\keys\

clientSignKey.cer -storepass 654321

 

注意-alias 和之前的一样。

 

操作完后修改tomcat的server


.xml文件,如下:

<Connector protocol="org.apache.coyote.http11.Http11NioProtocol"   

        port="8443"  enableLookups="true"   

        disableUploadTimeout="true" acceptCount="100"   

        maxThreads="200" scheme="https" secure="true"   

        SSLEnabled="true"  sslProtocol="TLS"   

        clientAuth="false"  

        keystoreFile="D:\keys\myclientkey.store"   

        keystorePass="654321" />  

 然后启动tomcat,就会发现不会再提示了。


如何用JAVA代码签发数字证书

标签:

原文地址:http://my.oschina.net/amoswork/blog/530420

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!