4

我需要帮助获取适当的代码以获取服务器证书 - 有效和无效,由 CA 签名和自签名。任何链接和参考将不胜感激。

我有一个 UNIX 命令,它给了我想要的东西,但我想要使用 Java 的相同输出。UNIX 中的命令是这样的——

echo -n | openssl s_client -connect www.gmail.com:443 -showcerts | \
  sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /tmp/$SERVERNAME.cert

这将返回 gmail 上的证书(不知道加密)链。我希望我的程序提供完全相同的信息。打印整个证书链。

4

2 回答 2

5

这可以使用以下步骤来完成:

  • 初始化一个信任任何东西的SSLContextusing a TrustManager(这个用例是使用这种信任管理器的极少数原因之一)。仅当您怀疑远程证书不受信任时。
  • SSLSocketFactory从中得到一个。
  • SSLSocket使用您要连接的主机名从此工厂创建一个。如果您使用主机名(而不是InetAddress),这将在 Java 7 上启用 SNI,因此这相当于将其-servername用作命令的附加选项openssl
  • 开始握手(例如用startHandhsake()
  • SSLSession从此得到SSLSocket
  • 对于每Certificate一个getPeerCertificates()
    • 使用获取其编码值(as byte[]getEncoded()
    • 将其转换为 PEM,或者:
      • 使用 BouncyCastle 的PEMWriter.
      • 使用 Base 64 编码器(例如 Apache Commons),添加 BEGIN/END 分隔符并每隔 64 个字符用新行分割字符串。
于 2013-10-10T17:28:09.663 回答
0

我过去遇到过同样的挑战,并在我的库中提供了这个选项,你可以在这里看到:GitHub - SSLKickstart - Kickstart我认为在这里分享它可能对其他开发人员有帮助。

用法

Map<String, List<Certificate>> certificates = CertificateUtils.getCertificate(
            "https://github.com/", 
            "https://stackoverflow.com/", 
            "https://reddit.com/",
            "https://youtube.com/");
            
// or get the server certificates as pem format
Map<String, List<String>> certificatesAsPem = CertificateUtils.getCertificateAsPem(
            "https://github.com/", 
            "https://stackoverflow.com/", 
            "https://reddit.com/",
            "https://youtube.com/");

使用 maven 安装库

<dependency>
    <groupId>io.github.hakky54</groupId>
    <artifactId>sslcontext-kickstart</artifactId>
    <version>6.7.0</version>
</dependency>
于 2021-07-06T22:04:42.967 回答