一、SSL证书解析两种方式
1,JDK自带的java.security解析证书
2,需要引入BouncyCastle依赖,即BC包
但是需要注意的是,JDK自带的解析工具类不能解析国密证书,但是BC包是支持国密算法的。当遇到下面的错误时,就表示JDK自带解析工具不能解析证书,需替换为BC包来解析
java.security.cert.CertificateParsingException: java.io.IOException: Unknown named curve: 1.2.156.10197.1.301
二、引入BC包依赖,实现证书解析逻辑
1,引入BC包依赖
<!-- bc库解析证书信息 -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.64</version>
</dependency>
2,读取SSL证书
InputStream fileIn = null;
try {
fileIn = new FileInputStream("F:\\baidu.cer"); // 将本地证书读入文件流
// 引入BC库
Security.addProvider(new BouncyCastleProvider());
CertificateFactory cf = CertificateFactory.getInstance("X.509","BC");
Certificate cert = cf.generateCertificate(fileIn); // 将文件流的证书转化为证书类
X509Certificate x509Cert = (X509Certificate)cert;
} catch (Exception e) {
logger.error("证书转换及解析异常:",e.getMessage());
} finally {
try {
if (fileIn != null) {
fileIn.close();
}
} catch (IOException e) {
logger.error("关闭证书文件输入流异常:",e.getMessage());
}
}
3,解析SSL证书基本信息
// 解析证书基本信息
private static void parseCertInfo(X509Certificate x509Cert) {
// 证书公钥信息,转为base64字符串
PublicKey publicKey = x509Cert.getPublicKey();
String base64PublicKey = new String(Base64.encodeBase64Chunked(publicKey.getEncoded()));
logger.info("证书版本号 ",x509Cert.getVersion());
logger.info("证书序列号 ",x509Cert.getSerialNumber().toString());
logger.info("证书使用者信息 ",x509Cert.getSubjectDN());
logger.info("证书颁发者信息 ",x509Cert.getIssuerDN());
logger.info("证书有效期-开始时间 ",x509Cert.getNotBefore());
logger.info("证书有效期-结束时间 ",x509Cert.getNotAfter());
logger.info("证书签名算法 ",x509Cert.getSigAlgName());
logger.info("证书加密算法 ",publicKey.getAlgorithm());// 加密算法
logger.info("证书公钥信息",base64PublicKey);// Base64,包含公钥算法和公钥值
}
// 获取域名列表
private static void getDnsList(X509Certificate x509Cert) {
try {
if (x509Cert.getSubjectAlternativeNames() != null) {
Iterator<List<?>> iterator = x509Cert.getSubjectAlternativeNames().iterator();
while (iterator.hasNext()) {
List<?> item = iterator.next();
String domain = (String) item.get(item.size()-1);
logger.info("证书的DNS域名列表为 : " + domain);
}
}
} catch (CertificateParsingException e) {
logger.error("解析证书的域名列表报错:",e.getMessage());
}
}