读取X.509公钥在JCA中 , 使用X509EncodedKeySpec解析X.509公钥文件 , 如下:
public static void testX509PublicKeyFile() {byte[] derBytes = pemFileToDerBytes("cert/public_key_x509.key");X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(derBytes);RSAPublicKey rsaPublicKey = (RSAPublicKey)KeyFactory.getInstance("RSA").generatePublic(x509EncodedKeySpec);BigInteger e = rsaPublicKey.getPublicExponent();BigInteger n = rsaPublicKey.getModulus();System.out.printf(" e: %X \n n: %X \n", e, n);}
读取X.509证书读取X.509证书文件 , 可使用CertificateFactory类 , 如下:
public static void testX509CertFile() {byte[] derBytes = pemFileToDerBytes("cert/cert.crt");Collection<? extends Certificate> certificates = CertificateFactory.getInstance("X.509").generateCertificates(new ByteArrayInputStream(derBytes));for(Certificate certificate : certificates){X509Certificate x509Certificate = (X509Certificate)certificate;System.out.printf("SubjectDN: %s \n", x509Certificate.getSubjectDN());System.out.printf("IssuerDN: %s \n", x509Certificate.getIssuerDN());System.out.printf("SigAlgName: %s \n", x509Certificate.getSigAlgName());System.out.printf("Signature: %s \n", Hex.encodeHexString(x509Certificate.getSignature()));System.out.printf("PublicKey: %s \n", x509Certificate.getPublicKey());}}
读取PKCS12密钥库文件读取PKCS12规范的密钥库文件 , 可使用KeyStore类 , 如下:
public static void testPkcs12File() {KeyStore keyStore = KeyStore.getInstance("PKCS12");InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("cert/keystore.p12");char[] password = "123456".toCharArray();keyStore.load(is, password);//获取证书X509Certificate x509Certificate = (X509Certificate)keyStore.getCertificate("demo");System.out.println("X509Certificate: ");System.out.printf("SubjectDN: %s \n", x509Certificate.getSubjectDN());System.out.printf("IssuerDN: %s \n", x509Certificate.getIssuerDN());System.out.printf("SigAlgName: %s \n", x509Certificate.getSigAlgName());System.out.printf("Signature: %s \n", Hex.encodeHexString(x509Certificate.getSignature()));System.out.printf("PublicKey: %s \n", x509Certificate.getPublicKey());//获取私钥Key key = keyStore.getKey("demo", password);System.out.printf("PrivateKey: %s \n", key);}
如果要读取.jks
文件 , 只需要将KeyStore.getInstance("PKCS12")
中的PKCS12更换为JKS即可 , 其它部分保持不变 , 不过由于JKS是java专有格式 , 目前java也不推荐使用了 , 所以能不用的话 , 就尽量不要用了 。
常见问题证书信任问题证书的绝大多数应用场景是Https协议 , 但在访问https接口时 , 有时会由于证书信任问题导致https握手失败 , 主要有以下2点原因:
- 有些公司会自建CA , 使用自签证书 , 如早期的12306 , 而jdk只信任它预置的根证书 , 所以https握手时这种证书会认证失败 。
- 新成立的根CA机构证书 , 没预置在旧的jdk里面 , 导致这些CA机构签发的证书不被信任 。
# 将cert.crt导入jdk预置密钥库文件 , 密钥库文件密码默认是changeitsudo keytool -importcert -file cert.crt -alias demo -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit# 查看密钥库文件 , 检查是否导入成功keytool -list -v -alias demo -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit
2. 以编码的方式信任证书以jdk自带的https sdk为例 , 可在代码中手动将问题证书添加到信任列表中 , 如下:
经验总结扩展阅读
- [WPF] 抄抄超强的苹果官网滚动文字特效实现
- Java函数式编程:一、函数式接口,lambda表达式和方法引用
- 不妨试试更快更小更灵活Java开发框架Solon
- 11 微服务架构学习与思考:开源 API 网关02-以 Java 为基础的 API 网关详细介绍
- java 新特性之 Stream API
- java 入土--集合详解
- 4 Java I/O:AIO和NIO中的Selector
- 2023容易暴富的星座女实现质的飞跃
- 通过 Github Action 实现定时推送天气预报
- 3 Java I/O:NIO中的Buffer