SSL证书大致介绍

SSL证书格式一般常用的有:PEM、CER、JKS、PKCS12这几种,根据不同的服务器以及服务器的版本,我们需要用到不同的证书格式,就市面上主流的服务器来说,大概有以下格式:

  • DER .CER,文件是二进制格式,只保存证书,不保存私钥。
  • PEM,一般是文本格式,可保存证书,可保存私钥。
  • CRT,可以是二进制格式,可以是文本格式,与 .DER 格式相同,不保存私钥。
  • PFX .P12,二进制格式,同时包含证书和私钥,一般有密码保护。
  • JKS,二进制格式,同时包含证书和私钥,一般有密码保护。

DER

该格式是二进制文件内容,Java 和 Windows 服务器偏向于使用这种编码格式。

OpenSSL查看
openssl x509 -in certificate.der -inform der -text -noout
转换为PEM
openssl x509 -in cert.crt -inform der -outform pem -out cert.pem

PEM

Privacy Enhanced Mail,一般为文本格式,以 -----BEGIN... 开头,以 -----END... 结尾。中间的内容是 BASE64 编码。这种格式可以保存证书和私钥,有时我们也把PEM 格式的私钥的后缀改为 .key 以区别证书与私钥。具体你可以看文件的内容。

这种格式常用于Apache和Nginx服务器。

OpenSSL查看
openssl x509 -in certificate.pem -text -noout
转换为DER
openssl x509 -in cert.crt -outform der -out cert.der

CRT

Certificate 的简称,有可能是 PEM 编码格式,也有可能是 DER 编码格式。如何查看请参考前两种格式。

PFX

Predecessor of PKCS#12,这种格式是二进制格式,且证书和私钥存在一个 PFX 文件中。一般用于 Windows 上的 IIS 服务器。改格式的文件一般会有一个密码用于保证私钥的安全。

OpenSSL 查看:
openssl pkcs12 -in for-iis.pfx
转换为 PEM
openssl pkcs12 -in for-iis.pfx -out for-iis.pem -nodes

JKS

Java Key Storage,很容易知道这是 JAVA 的专属格式,利用 JAVA 的一个叫 keytool 的工具可以进行格式转换。一般用于 Tomcat 服务器。

你可以到这里进行格式转换:https://myssl.com/cert_convert.html

将PEM证书转换为JKS文件

要将PEM证书转换为JKS文件,可以按照以下步骤进行操作:

  1. 将PEM证书转换为DER格式。可以使用OpenSSL工具来完成此操作。例如,要将名为cert.pem的PEM证书转换为DER格式,可以运行以下命令:
openssl x509 -outform der -in cert.pem -out cert.der
  1. 将DER格式的证书导入到JKS文件中。可以使用Java的keytool工具来完成此操作。例如,要将名为cert.der的DER证书导入到名为keystore.jks的JKS文件中,可以运行以下命令:
keytool -import -alias myalias -file cert.der -keystore keystore.jks

在此命令中,myalias是证书的别名,可以根据需要进行更改。在执行此命令时,您将被要求输入JKS文件的密码。

完成上述步骤后,您将获得一个包含PEM证书的JKS文件。您可以使用Java的KeyStore类来加载该文件,并使用其中的证书进行加密和解密操作。

针对x509证书加密及解密的案例

以下是一个使用Java解密x509证书加密的示例代码,我们首先加载密钥库,然后获取证书和私钥。

import java.io.FileInputStream;
import java.security.Key;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;

import javax.crypto.Cipher;

public class X509Decryption {
    public static void main(String[] args) throws Exception {
        // 加载密钥库
        KeyStore ks = KeyStore.getInstance("JKS");
        FileInputStream fis = new FileInputStream("keystore.jks");
        ks.load(fis, "password".toCharArray());

        // 获取证书和私钥
        String alias = "myalias";
        Certificate cert = ks.getCertificate(alias);
        PrivateKey privateKey = (PrivateKey) ks.getKey(alias, "password".toCharArray());
    }
}

接下来,我们创建一个解密器,并使用私钥初始化它。最后,我们使用解密器解密加密后的数据。

import java.io.FileInputStream;
import java.security.Key;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;

import javax.crypto.Cipher;

public class X509Decryption {
    public static void main(String[] args) throws Exception {
        // 加载密钥库
        KeyStore ks = KeyStore.getInstance("JKS");
        FileInputStream fis = new FileInputStream("keystore.jks");
        ks.load(fis, "password".toCharArray());

        // 获取证书和私钥
        String alias = "myalias";
        Certificate cert = ks.getCertificate(alias);
        PrivateKey privateKey = (PrivateKey) ks.getKey(alias, "password".toCharArray());

        // 创建解密器
        Cipher cipher = Cipher.getInstance(cert.getPublicKey().getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        // 解密数据
        byte[] encryptedData = ...; // 加密后的数据
        byte[] decryptedData = cipher.doFinal(encryptedData);
        System.out.println(new String(decryptedData));
    }
}