zoukankan      html  css  js  c++  java
  • 数字证书生成--加密密/加签验签

    最近一个项目,处于安全上的考虑,前后端需要使用安全证书加密通信,涉及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

  • 相关阅读:
    寻找项目中顶级Vue对象 (一)
    vue文件中style标签的几个标识符
    vue中methods中的方法闭包缓存问题
    斐波那契数列实现
    ECMAScript 6 入门学习笔记(零)——开始
    Extjs6(三)——用extjs6.0写一个简单页面
    同域和不同域长啥样
    Extjs6组件——Form大家族成员介绍
    Extjs6官方文档译文——应用架构简介(MVC,MVVM)
    Extjs6(特别篇)——项目自带例子main.js拆分详解
  • 原文地址:https://www.cnblogs.com/shindo/p/6346971.html
Copyright © 2011-2022 走看看