天天看點

java 使用CA認證

本文轉自:

數字證書簡介及Java編碼實作

CA認證原理以及實作

java CA憑證制作和代碼中使用

名詞大意

秘鑰庫:存儲了

公鑰

私鑰

資訊,一個秘鑰庫可以存儲

多對

的密鑰對(密鑰對可以了解為就是

數字證書

),通過alias别名來取出需要的密鑰對,存放于

伺服器

xxx.keystore

檔案

數字證書:隻能存儲

公鑰

,可以從

xxxx.keystore

中導出某個

密鑰對

公鑰證書

,存放于

用戶端

xxx.cer

檔案

java使用數字證書

Java 6提供了完善的數字證書管理實作,我們幾乎無需關注,僅通過操作

密鑰庫

數字證書

就可完成相應的

加密解密

簽名驗簽

過程。

密鑰庫

管理

私鑰

數字證書

管理

公鑰

,公鑰和私鑰分屬消息傳遞雙方,進行

加密消息傳遞

CertificateCoder工具類

/****
     * 獲得私鑰,獲得私鑰後,通過RSA算方法實作進行"私鑰加密,公鑰解密"和"公鑰加密,私鑰解密"操作
     * @param keyStorePath 密鑰庫路徑
     * @param alias 别名
     * @param keystore_password 秘鑰庫密碼
     * @param ca_password 證書密碼
     * @return  私鑰
     */
    private static PrivateKey getPrivateKeyByKeyStore(String keyStorePath, String alias, String keystore_password,String ca_password)throws Exception{
        //獲得密鑰庫
        KeyStore ks = getKeyStore(keyStorePath,keystore_password);
        //獲得私鑰
        return  (PrivateKey)ks.getKey(alias, ca_password.toCharArray());

    }

    /****
     * 由Certificate獲得公鑰,獲得公鑰後,通過RSA算方法實作進行"私鑰加密,公鑰解密"和"公鑰加密,私鑰解密"操作
     * @param certificatePath  證書路徑
     * @return 公鑰
     */
    private static PublicKey getPublicKeyByCertificate(String certificatePath)throws Exception {
        //獲得證書
        Certificate certificate = getCertificate(certificatePath);
        //獲得公鑰
        return certificate.getPublicKey();
    }

    /****
     * 加載數字證書,JAVA 6僅支援x.509的數字證書
     * @param certificatePath  證書路徑
     * @return   證書
     * @throws Exception
     */
    private static Certificate getCertificate(String certificatePath) throws Exception{
        //執行個體化證書工廠
        CertificateFactory certificateFactory = CertificateFactory.getInstance("x.509");
        //取得證書檔案流
        FileInputStream in = new FileInputStream(certificatePath);
        //生成證書
        Certificate certificate = certificateFactory.generateCertificate(in);
        //關閉證書檔案流
        in.close();
        return certificate;
    }

    /****
     * 獲得Certificate
     * @param keyStorePath 密鑰庫路徑
     * @param alias 别名
     * @param keystore_password  秘鑰庫密碼
     * @return  證書
     * @throws Exception
     */
    private static Certificate getCertificate(String keyStorePath,String alias,String keystore_password) throws Exception{
        //由密鑰庫獲得數字證書建構數字簽名對象
        //獲得密鑰庫
        KeyStore ks = getKeyStore(keyStorePath,keystore_password);
        //獲得證書
        return ks.getCertificate(alias);
    }

    /****
     * 加載密鑰庫,加載了以後,我們就能通過相應的方法獲得私鑰,也可以獲得數字證書
     * @param keyStorePath 密鑰庫路徑
     * @param keystore_password 密碼
     * @return  密鑰庫
     * @throws Exception
     */
    private static KeyStore getKeyStore(String keyStorePath,String keystore_password) throws Exception{
        //執行個體化密鑰庫
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        //獲得密鑰庫檔案流
        FileInputStream is = new FileInputStream(keyStorePath);
        //加載密鑰庫
        ks.load(is,keystore_password.toCharArray());
        //關閉密鑰庫檔案流
        is.close();
        return ks;
    }

    /****
     * 私鑰加密
     * @param data  待加密的資料
     * @param keyStorePath  密鑰庫路徑
     * @param alias  别名
     * @param keystore_password   秘鑰庫密碼
     * @param ca_password   證書密碼
     * @return  加密資料
     * @throws Exception
     */
    public static byte[] encryptByPriateKey(byte[] data,String keyStorePath,String alias,String keystore_password,String ca_password) throws Exception{
        //獲得私鑰
        PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath,alias,keystore_password,ca_password);
        //對資料加密
        Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE,privateKey);
        return cipher.doFinal(data);
    }

    /****
     * 私鑰解密
     * @param data  待解密資料
     * @param keyStorePath 密鑰庫路徑
     * @param alias  别名
     * @param keystore_password   秘鑰庫密碼
     * @param ca_password   證書密碼
     * @return  解密資料
     * @throws Exception
     */
    public static byte[] decryptByPrivateKey(byte[] data,String keyStorePath,String alias,String keystore_password,String ca_password) throws Exception{
        //取得私鑰
        PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath,alias,keystore_password,ca_password);
        //對資料解密
        Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE,privateKey);
        return cipher.doFinal(data);
    }

    /****
     * 公鑰加密
     * @param data  等待加密資料
     * @param certificatePath  證書路徑
     * @return   加密資料
     * @throws Exception
     */
    public static byte[] encryptByPublicKey(byte[] data,String certificatePath) throws Exception{
        //取得公鑰
        PublicKey publicKey = getPublicKeyByCertificate(certificatePath);
        //對資料加密
        Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE,publicKey);
        return cipher.doFinal(data);
    }

    /****
     * 公鑰解密
     * @param data  等待解密的資料
     * @param certificatePath  證書路徑
     * @return  解密資料
     * @throws Exception
     */
    public static byte[] decryptByPublicKey(byte[] data,String certificatePath)throws Exception{
        //取得公鑰
        PublicKey publicKey = getPublicKeyByCertificate(certificatePath);
        //對資料解密
        Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        return cipher.doFinal(data);
    }

    /****
     * @param sign  簽名
     * @param keyStorePath 密鑰庫路徑
     * @param alias 别名
     * @param keystore_password   秘鑰庫密碼
     * @param ca_password   證書密碼
     * @return 簽名
     * @throws Exception
     */
    public static byte[] sign(byte[] sign,String keyStorePath,String alias,String keystore_password,String ca_password)throws Exception{
        //獲得證書
        X509Certificate x509Certificate = (X509Certificate) getCertificate(keyStorePath,alias,keystore_password);
        //建構簽名,由證書指定簽名算法
        Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());
        //擷取私鑰
        PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath,alias,keystore_password,ca_password);
        //初始化簽名,由私鑰建構
        signature.initSign(privateKey);
        signature.update(sign);
        return signature.sign();
    }


    /****
     * 驗證簽名
     * @param data  資料
     * @param sign  簽名
     * @param certificatePath  證書路徑
     * @return  驗證通過為真
     * @throws Exception
     */
    public static boolean verify(byte[] data,byte[] sign,String certificatePath) throws Exception{
        //獲得證書
        X509Certificate x509Certificate = (X509Certificate)getCertificate(certificatePath);
        //由證書建構簽名
        Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());
        //由證書初始化簽名,實際上是使用了證書中的公鑰
        signature.initVerify(x509Certificate);
        signature.update(data);
        return signature.verify(sign);
    }
           

CertificateCoderTest測試類

/** 秘鑰庫密碼. */
    private static final String keystore_password  = "123456";
    /** 證書密碼. */
    private static final String ca_password   = "111111";
    /** 證書别名. */
    private static final String alias = "ljw";
    /** 密鑰庫檔案. */
    private static final String keyStorePath = "F:\\Certifacate\\ljw.keystore";
    /** 數字證書檔案. */
    private static final String certificatePath = "F:\\Certifacate\\ljw.cer";

    //我們假定密鑰庫檔案yale.keystore存儲在D盤根目錄,數字證書檔案yale.cer也存儲在D盤根目錄
    /****
     * 公鑰加密---私鑰解密
     * @throws Exception
     */
    @Test
    public void test1() throws Exception{
        System.err.println("公鑰加密---私鑰解密");
        String inputStr = "數字證書";
        byte[] data = inputStr.getBytes();
        //公鑰加密
        byte[] encrypt = CertificateCoder.encryptByPublicKey(data, certificatePath);
        //私鑰解密
        byte[] decrypt = CertificateCoder.decryptByPrivateKey(encrypt, keyStorePath, alias, keystore_password, ca_password);
        String outputStr = new String(decrypt);
        System.err.println("加密前:\n" + inputStr);
        System.err.println("解密後:\n" + outputStr);
    }

    /****
     * 私鑰加密---公鑰解密
     * @throws Exception
     */
    @Test
    public  void test2()throws Exception{
        System.err.println("私鑰加密---公鑰解密");
        String inputStr = "數字簽名";
        byte[] data = inputStr.getBytes();
        //私鑰加密
        byte[] encodedData = CertificateCoder.encryptByPriateKey(data, keyStorePath, alias, keystore_password, ca_password);
        //公鑰解密
        byte[] decodeData = CertificateCoder.decryptByPublicKey(encodedData, certificatePath);
        String outputStr = new String (decodeData);
        System.err.println("加密前:\n" + inputStr);
        System.err.println("解密後:\n" + outputStr);
    }

    @Test
    public  void testSign()throws Exception{
        String inputStr = "簽名";
        byte[] data = inputStr.getBytes();
        System.err.println("私鑰簽名---公鑰驗證");
        //産生簽名
        byte[] sign = CertificateCoder.sign(data, keyStorePath, alias, keystore_password, ca_password);
        System.err.println("簽名:\n" + sign);
        //驗證簽名
        boolean status = CertificateCoder.verify(data, sign, certificatePath);
        System.err.println("狀态:\n " + status);
    }