1 证书概念
- SSL
Secure Sockets Layer,一种加密协议规范,如https就使用它进行加解密
- OpenSSL
一种ssl规范的实现,可以帮助我们生成解析各类证书
- X.509
证书标准,比如证书应该包含哪些信息
- PEM
Privacy Enhanced Mail,一种编码格式,常用于Apache和UNIX服务器,查看证书信息:openssl x509 -in certificate.pem -text -noout
- DER
Distinguished Encoding Rules,一种编码格式,常用于Java和Windows服务器,查看证书的信息:openssl x509 -in certificate.der -inform der -text -noout
- 编码转换
PEM转为DER:openssl x509 -in cert.crt -outform der -out cert.der
DER转为PEM:openssl x509 -in cert.crt -inform der -outform pem -out cert.pem
- CRT:certificate,证书文件,常见于UNIX系统,大多应是PEM编码
- CER:certificate,证书文件,常见于Windows系统,大多应是DER编码.
- KEY:通常用来存放一个公钥或者私钥,查看不同编码格式文件内容
PEM格式:openssl rsa -in mykey.key -text -noout
DER格式:openssl rsa -in mykey.key -text -noout -inform der
- CSR : Certificate Signing Request,即证书签名请求,这个并不是证书,而是向权威证书颁发机构获得签名证书的申请,查看方法:openssl req -noout -text -in my.csr (DER格式同上后面加上-inform der)
- PFX/P12: predecessor of PKCS#12,对Unix服务器来说,一般CRT和KEY是分开存放在不同文件中的,但Windows的IIS则将它们存在一个PFX文件中,因此这个文件包含了证书及私钥。
生成pfx的命令:openssl pkcs12 -export -in certificate.crt -inkey privateKey.key -out certificate.pfx -certfile CACert.crt
其中CACert.crt是CA(权威证书颁发机构)的根证书,有的话也通过-certfile参数一起带进去.
- JKS :Java Key Storage,跟OpenSSL关系不大,Java的keytool工具可以将PFX转为JKS,也能直接生成JKS
2 证书转换
2.1 CRT证书转JKS证书
-
crt转为p12证书
openssl pkcs12 -export -in from.crt -inkey private.key -out to.p12 -name "alias"
- p12转为jks证书
keytool -importkeystore -srckeystore from.p12 -srcstoretype PKCS12 -deststoretype JKS -destkeystore to.jks
2.2 JKS证书转CRT证书和私钥
- jks转p12证书
keytool -importkeystore -srckeystore from.jks -srcstoretype JKS -deststoretype PKCS12 -destkeystore to.p12
- p12转crt证书
openssl pkcs12 -in from.p12 -nokeys -clcerts -out to.crt
- p12转私钥
openssl pkcs12 -in from.p12 -nocerts -nodes -out to.key
2.3 pfx与jks互相转换(Java代码)
/**
* pfx与jks互相转换
*/
public class ConvertPFX {
public static final String PKCS12 = "PKCS12";
public static final String JKS = "JKS";
public static final String PFX_KEYSTORE_FILE = "some.pfx";
public static final String KEYSTORE_PASSWORD = "123456";
public static final String JKS_KEYSTORE_FILE = "some.keystore";
/**
* 将pfx或p12的文件转为keystore
*/
public static void coverTokeyStore() {
try {
KeyStore inputKeyStore = KeyStore.getInstance("PKCS12");
FileInputStream fis = new FileInputStream(PFX_KEYSTORE_FILE);
char[] nPassword = null;
if ((KEYSTORE_PASSWORD == null)
|| KEYSTORE_PASSWORD.trim().equals("")) {
nPassword = null;
} else {
nPassword = KEYSTORE_PASSWORD.toCharArray();
}
inputKeyStore.load(fis, nPassword);
fis.close();
KeyStore outputKeyStore = KeyStore.getInstance("JKS");
outputKeyStore.load(null, KEYSTORE_PASSWORD.toCharArray());
Enumeration enums = inputKeyStore.aliases();
while (enums.hasMoreElements()) { // we are readin just one
// certificate.
String keyAlias = (String) enums.nextElement();
System.out.println("alias=[" + keyAlias + "]");
if (inputKeyStore.isKeyEntry(keyAlias)) {
Key key = inputKeyStore.getKey(keyAlias, nPassword);
Certificate[] certChain = inputKeyStore
.getCertificateChain(keyAlias);
outputKeyStore.setKeyEntry(keyAlias, key,
KEYSTORE_PASSWORD.toCharArray(), certChain);
}
}
FileOutputStream out = new FileOutputStream(JKS_KEYSTORE_FILE);
outputKeyStore.store(out, nPassword);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 将keystore转为pfx
*/
public static void coverToPfx() {
try {
KeyStore inputKeyStore = KeyStore.getInstance("JKS");
FileInputStream fis = new FileInputStream(JKS_KEYSTORE_FILE);
char[] nPassword = null;
if ((KEYSTORE_PASSWORD == null)
|| KEYSTORE_PASSWORD.trim().equals("")) {
nPassword = null;
} else {
nPassword = KEYSTORE_PASSWORD.toCharArray();
}
inputKeyStore.load(fis, nPassword);
fis.close();
KeyStore outputKeyStore = KeyStore.getInstance("PKCS12");
outputKeyStore.load(null, KEYSTORE_PASSWORD.toCharArray());
Enumeration enums = inputKeyStore.aliases();
while (enums.hasMoreElements()) { // we are readin just one
// certificate.
String keyAlias = (String) enums.nextElement();
System.out.println("alias=[" + keyAlias + "]");
if (inputKeyStore.isKeyEntry(keyAlias)) {
Key key = inputKeyStore.getKey(keyAlias, nPassword);
Certificate[] certChain = inputKeyStore
.getCertificateChain(keyAlias);
outputKeyStore.setKeyEntry(keyAlias, key,
KEYSTORE_PASSWORD.toCharArray(), certChain);
}
}
FileOutputStream out = new FileOutputStream(PFX_KEYSTORE_FILE);
outputKeyStore.store(out, nPassword);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
coverTokeyStore();
}
}
3 Keytool使用
- 查看jks内容:
keytool -list -v -keystore server.keystore -storepass 123456
- 生成jks证书:
keytool -genkey -alias cp.com.cn -keypass changeit -keyalg RSA -keysize 2048
-sigalg "SHA512withRSA" -validity 3650 -keystore server.keystore -keypass 123 -storepass 123
-dname "CN=cp.com.cn, OU=mssp, O=com.cn, L=Hangzhou, ST=Zhejiang, C=ZH"
- 导出证书:
keytool -export -alias cp.com.cn -keystore server.keystore -file server.crt -storepass 123
- 查看证书:
keytool -printcert -file server.crt
- 导入证书到jre:
keytool -import -file "server.crt" -keystore "C:\Program Files\Java\jre1.8.0_111\lib\security\cacerts" -alias cp.com.cn
- 查看jre内包含的证书:
keytool -list -keystore "C:\Program Files\Java\jre1.8.0_111\lib\security\cacerts" | findstr /i cp.com.cn
最后推荐一个SSL工具网站:https://www.chinassl.net/ssltools/convert-ssl.html
爱家人,爱生活,爱设计,爱编程,拥抱精彩人生!