首页 > 代码库 > 前后端(支持app)RSA加密通信证书生成方法汇编
前后端(支持app)RSA加密通信证书生成方法汇编
最近一个项目,处于安全上的考虑,前后端需要使用安全证书加密通信,涉及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
详细的加解密及验签方案见:
前后端(支持app)RSA加密通信证书生成方法汇编