數字證書生成--加密密/加簽驗簽


最近一個項目,處於安全上的考慮,前后端需要使用安全證書加密通信,涉及ios/android-后台交互。在測試環境上沒有正式的CA證書,使用自簽證書開發。

下面把生成4套環境的自簽證書過程mark下,如有需要,可參考:

 

以下命令的執行環境均為windows-cmd界面(前提需安裝jdk,使用jdk自帶的keytool工具)

 

1、生成jks、csr證書(這倆證書暫時沒用):

keytool -genkey -alias *.test.com -sigalg SHA1withRSA -keyalg RSA -keysize 2048 -keystore D:/Citificate/testKey/test.jks -dname "C=CN,ST=珠海,L=珠海,O=測試樣例公司,OU=研發部,CN=*.test.com" && keytool -certreq -alias *.test.com -file D:/Citificate/testKey/test.csr -keystore D:/Citificate/testKey/test.jks && echo Your certificate signing request file is D:/Citificate/testKey/test.csr.  Your keystore file is D:/Citificate/testKey/test.jks.  Thanks for using the 亞洲誠信TrustAsia keytool CSR helper.

 

2、生成keystore密鑰庫:

keytool -genkey -alias *.test.com -keypass password -keyalg RSA -keysize 2048 -validity 730 -keystore D:/Citificate/testKey/test.keystore -dname "C=CN,ST=珠海,L=珠海,O=測試樣例公司,OU=研發部,CN=*.test.com" -storepass password

 

3、從密鑰庫導出cer、crt公鑰證書:

keytool -export -alias *.test.com -keystore D:/Citificate/testKey/test.keystore -storepass password -rfc -file D:/Citificate/testKey/test.cer

crt公鑰證書可以直接把這一步生成的cer證書修改文件后綴名得到

 

4、使用java工具類導出證書key

package test;

import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.PrivateKey;

import sun.misc.BASE64Encoder;

@SuppressWarnings("restriction")
public class SslKey {

    public static KeyStore getKeyStore(String keyStorePath, String password) throws Exception {
        FileInputStream is = new FileInputStream(keyStorePath);
        KeyStore ks = KeyStore.getInstance("JKS");
        ks.load(is, password.toCharArray());
        is.close();
        return ks;
    }

    public static PrivateKey getPrivateKey() {
        try {

            BASE64Encoder encoder = new BASE64Encoder();
            KeyStore ks = getKeyStore("D:/Citificate/testKey/test.keystore", "password");
            PrivateKey key = (PrivateKey) ks.getKey("*.test.com", "password".toCharArray());
            String encoded = encoder.encode(key.getEncoded());
            System.out.println("-----BEGIN RSA PRIVATE KEY-----");
            System.out.println(encoded);
            System.out.println("-----END RSA PRIVATE KEY-----");
            return key;
        } catch (Exception e) {
            return null;
        }
    }

    public static void main(String[] args) {
        getPrivateKey();
    }

}

執行方法后,將結果拷入新建的后綴名為:.key的文本文檔

 

5、使用openssl將上一步生成的.key文件做.unsecure文件輸出(nginx使用,使用.key.unsecure可以避免使用.key文件時每次訪問都要輸入密碼,本套方案前后端加密該文件未使用)-前提是先安裝openssl插件,不然cmd會報openssl命令錯誤

openssl rsa -in D:/Citificate/testKey/test.key -out D:/Citificate/testKey/test.key.unsecure

 

6、使用java工具類從密鑰庫導出pfx私鑰:

package test;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.Key;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.util.Enumeration;

public class CreatePfx {
    /** 
     * 將keystore轉為pfx
     * 
     * @param keyStoreFile 生成的文件名和路徑
     * @param pfxPsw 密碼
     * @param pfxFile 原文件路徑及名稱
     */
    public static void coverToPfx() throws Exception {
        String keyStoreFile = "D:/Citificate/testKey/test.keystore";
        String pfxPsw = "password";
        String pfxFile = "D:/Citificate/testKey/test.pfx";

        KeyStore inputKeyStore = null;
        FileInputStream input = null;
        FileOutputStream output = null;
        String keyAlias = "";
        try {
            inputKeyStore = KeyStore.getInstance("JKS");
            input = new FileInputStream(keyStoreFile);
            char[] password = null;
            if ((pfxPsw == null) || pfxPsw.trim().equals("")) {
                password = null;
            } else {
                password = pfxPsw.toCharArray();
            }
            inputKeyStore.load(input, password);
            KeyStore outputKeyStore = KeyStore.getInstance("PKCS12");
            outputKeyStore.load(null, pfxPsw.toCharArray());
            Enumeration enums = inputKeyStore.aliases();
            while (enums.hasMoreElements()) {
                keyAlias = (String) enums.nextElement();
                System.out.println("alias=[" + keyAlias + "]");
                if (inputKeyStore.isKeyEntry(keyAlias)) {
                    Key key = inputKeyStore.getKey(keyAlias, password);
                    Certificate[] certChain = inputKeyStore.getCertificateChain(keyAlias);
                    outputKeyStore.setKeyEntry(keyAlias, key, pfxPsw.toCharArray(), certChain);
                }
            }
            output = new FileOutputStream(pfxFile);
            outputKeyStore.store(output, password);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                    System.out.println(e.getMessage());
                }
            }
            if (output != null) {
                try {
                    output.close();
                } catch (IOException e) {
                    System.out.println(e.getMessage());
                }
            }
        }
    }

}

 

以上證書已經可以適應安卓端-后台加密通信

方案:

1)安卓端使用cer或crt公鑰加密,后台使用keystore解密

2)后台使用keystore簽名,安卓端使用使用cer或crt公鑰驗簽

 

ios還需要der和pem證書支持

7、使用openssl將cer類型公鑰轉換為ios能使用的der類型公鑰:

openssl x509 -outform der -in D:/Citificate/testKey/test.cer -out D:/Citificate/testKey/test.der

 

8、使用openssl生成ios端驗簽所需pem文件:

openssl rsa -in D:/Citificate/testKey/test.key -pubout -out D:/Citificate/testKey/test.pem

 

詳細的加解密及加簽驗簽方案見:http://www.cnblogs.com/shindo/p/6349070.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM