2013-10-10 36 views
2

我希望得到适当的代码片段以获得服务器证书的帮助 - 有效和无效,由CA签名并自签名。任何链接和参考将高度赞赏。JAVA:提取服务器证书

我有一个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上的证书(不知道加密)链。我希望我的java程序能够提供完全相同的信息。打印整个证书链。

+0

通过“完全相同的信息”,你的意思是一个Java应用程序实际上应该在shell中执行相同的命令并显示输出? – eis

+0

否。不要从java运行Unix命令。但是,要以与Unix命令相同的编码获取证书。 –

回答

2

这可以通过以下步骤来完成:

  • 使用TrustManager该信任什么(这个用例是使用了这样的信任管理器,以极少数的原因之一)初始化的SSLContext。只有在您怀疑远程证书不可信时才会这样做。
  • 从它得到一个SSLSocketFactory
  • 使用要连接的主机名从此工厂创建SSLSocket。如果您使用主机名(而不是InetAddress),则这将启用Java 7上的SNI,因此这相当于将-servername用作openssl命令的附加选项。
  • (与startHandhsake()例如)启动握手
  • 从这个SSLSocket获取SSLSession
  • 对于每个CertificategetPeerCertificates()
    • 使用getEncoded()
    • 转换成PEM获取其编码值(如byte[]),或者:
      • 使用BouncyCastle的的PEMWriter
      • 使用Base 64编码器(例如Apache Commons),添加BEGIN/END分隔符并每64个字符用一个新行分割字符串。
+0

谢谢。将执行相同的并返回。 –

+0

使用下面的代码。 Base64字符串与我使用Unix命令收到的输出几乎相同。当我在两者之间做了差异时,我注意到只有两个字符不匹配。原始字符串'+'中的字符在我的java输出中显示为' - '。 '/'为'_'。除了这两个,其他的都是完美的。在此粘贴代码: for(int i = 0; i

+0

不要使用'... URLSafeString',只需使用普通的base 64编码器即可。 – Bruno

相关问题