Java 如何使用okhttp响应获取服务器证书

Java 如何使用okhttp响应获取服务器证书,java,okhttp,Java,Okhttp,我想保存服务器证书,但找不到使用OkHttpClient获取该证书的方法。response.handshake为空: client.newCall(request.execute().handshake().peerCertificates()) 您有正确的代码。但您可能已禁用安全性或类似功能,因此您的请求没有干净的证书链 正确的安全代码 import okhttp3.internal.connection.RealCall import okhttp3.tls.HandshakeCertifi

我想保存服务器证书,但找不到使用
OkHttpClient
获取该证书的方法。response.handshake为空:

client.newCall(request.execute().handshake().peerCertificates())

您有正确的代码。但您可能已禁用安全性或类似功能,因此您的请求没有干净的证书链

正确的安全代码

import okhttp3.internal.connection.RealCall
import okhttp3.tls.HandshakeCertificates
import java.security.cert.X509Certificate
import javax.net.ssl.SSLSocket

fun main() {
  val handshakeCertificates = HandshakeCertificates.Builder()
    .addPlatformTrustedCertificates()
    .addInsecureHost("self-signed.badssl.com")
    .build()

  val client = OkHttpClient.Builder()
    .sslSocketFactory(handshakeCertificates.sslSocketFactory(), handshakeCertificates.trustManager)
    .eventListener(object : EventListener() {
      override fun connectionAcquired(call: Call, connection: Connection) {
        val socket = (call as RealCall).connection?.socket() as? SSLSocket

        println("connectionAcquired " + socket?.session?.peerCertificates?.size)
        socket?.session?.peerCertificates?.forEach {
          val x509 = it as X509Certificate
          println(x509.subjectDN)
        }
      }
    })
    .build()

  val response = client.newCall(Request.Builder().url("https://self-signed.badssl.com").build()).execute()
  println("response " + response.handshake?.peerCertificates?.size)
  response.handshake?.peerCertificates?.forEach {
    val x509 = it as X509Certificate
    println(x509.subjectDN)
  }
}

不安全代码

import okhttp3.internal.connection.RealCall
import okhttp3.tls.HandshakeCertificates
import java.security.cert.X509Certificate
import javax.net.ssl.SSLSocket

fun main() {
  val handshakeCertificates = HandshakeCertificates.Builder()
    .addPlatformTrustedCertificates()
    .addInsecureHost("self-signed.badssl.com")
    .build()

  val client = OkHttpClient.Builder()
    .sslSocketFactory(handshakeCertificates.sslSocketFactory(), handshakeCertificates.trustManager)
    .eventListener(object : EventListener() {
      override fun connectionAcquired(call: Call, connection: Connection) {
        val socket = (call as RealCall).connection?.socket() as? SSLSocket

        println("connectionAcquired " + socket?.session?.peerCertificates?.size)
        socket?.session?.peerCertificates?.forEach {
          val x509 = it as X509Certificate
          println(x509.subjectDN)
        }
      }
    })
    .build()

  val response = client.newCall(Request.Builder().url("https://self-signed.badssl.com").build()).execute()
  println("response " + response.handshake?.peerCertificates?.size)
  response.handshake?.peerCertificates?.forEach {
    val x509 = it as X509Certificate
    println(x509.subjectDN)
  }
}
输出

connectionAcquired 1
CN=*.badssl.com, O=BadSSL, L=San Francisco, ST=California, C=US
response 0

你有正确的代码。但您可能已禁用安全性或类似功能,因此您的请求没有干净的证书链

正确的安全代码

import okhttp3.internal.connection.RealCall
import okhttp3.tls.HandshakeCertificates
import java.security.cert.X509Certificate
import javax.net.ssl.SSLSocket

fun main() {
  val handshakeCertificates = HandshakeCertificates.Builder()
    .addPlatformTrustedCertificates()
    .addInsecureHost("self-signed.badssl.com")
    .build()

  val client = OkHttpClient.Builder()
    .sslSocketFactory(handshakeCertificates.sslSocketFactory(), handshakeCertificates.trustManager)
    .eventListener(object : EventListener() {
      override fun connectionAcquired(call: Call, connection: Connection) {
        val socket = (call as RealCall).connection?.socket() as? SSLSocket

        println("connectionAcquired " + socket?.session?.peerCertificates?.size)
        socket?.session?.peerCertificates?.forEach {
          val x509 = it as X509Certificate
          println(x509.subjectDN)
        }
      }
    })
    .build()

  val response = client.newCall(Request.Builder().url("https://self-signed.badssl.com").build()).execute()
  println("response " + response.handshake?.peerCertificates?.size)
  response.handshake?.peerCertificates?.forEach {
    val x509 = it as X509Certificate
    println(x509.subjectDN)
  }
}

不安全代码

import okhttp3.internal.connection.RealCall
import okhttp3.tls.HandshakeCertificates
import java.security.cert.X509Certificate
import javax.net.ssl.SSLSocket

fun main() {
  val handshakeCertificates = HandshakeCertificates.Builder()
    .addPlatformTrustedCertificates()
    .addInsecureHost("self-signed.badssl.com")
    .build()

  val client = OkHttpClient.Builder()
    .sslSocketFactory(handshakeCertificates.sslSocketFactory(), handshakeCertificates.trustManager)
    .eventListener(object : EventListener() {
      override fun connectionAcquired(call: Call, connection: Connection) {
        val socket = (call as RealCall).connection?.socket() as? SSLSocket

        println("connectionAcquired " + socket?.session?.peerCertificates?.size)
        socket?.session?.peerCertificates?.forEach {
          val x509 = it as X509Certificate
          println(x509.subjectDN)
        }
      }
    })
    .build()

  val response = client.newCall(Request.Builder().url("https://self-signed.badssl.com").build()).execute()
  println("response " + response.handshake?.peerCertificates?.size)
  response.handshake?.peerCertificates?.forEach {
    val x509 = it as X509Certificate
    println(x509.subjectDN)
  }
}
输出

connectionAcquired 1
CN=*.badssl.com, O=BadSSL, L=San Francisco, ST=California, C=US
response 0

certifikit CLI可以以OkHttp友好格式为您下载它们

$certifikit cli git:(主)。/cft—主机badsl.com—不安全—输出tmp
中国:**badsl.com
引脚:sha256/F522E496C72FCCC623F1FFB9DA5A79CDEFE16340851F22D23D0CD2A58066F
SAN:*.badsl.com,badsl.com
密钥用法:数字签名、密钥加密
Ext键用法:serverAuth、clientAuth
权限信息访问:
ocsp:http://ocsp.digicert.com
凯恩斯:http://cacerts.digicert.com/DigiCertSHA2SecureServerCA.crt
有效期:2020-03-23T00:00:00Z..2022-05-17T12:00:00Z(1年)
CA:错
CN:DigiCert SHA2安全服务器CA
引脚:sha256/e6426f344330d0a8eb080bbb7976391d976fc824b5dc16c0d15246d5148ff75c
存储区域网络:
密钥用法:数字签名、KeyCertSign、CRLSign
权限信息访问:
ocsp:http://ocsp.digicert.com
有效期:2013-03-08T12:00:00Z..2023-03-08T12:00:00Z(2年)
CA:真实最大中间值:0
CN:DigiCert全局根CA(由本地受信任的根签名)
引脚:sha256/aff988906dde12955d9bebbf928fdcc31cce328d5b9384f21c8941ca26e20391
存储区域网络:
OU:www.digicert.com
密钥用法:数字签名、KeyCertSign、CRLSign
有效期:2006-11-10T00:00:00Z..2031-11-10T00:00:00Z(11年)
CA:是的
$certifikit cli git:(主)✗ ls tmp
aff988906dde12955d9bebbf928fdcc31cce328d5b9384f21c8941ca26e20391.pem F522E496C72FCCC623F1FFB9DA5A79CDEFE16340851F2D23D0CD2A58066F.pem
e6426f344330d0a8eb080bbb7976391d976fc824b5dc16c0d15246d5148ff75c.pem

certifikit CLI可以以OkHttp友好格式为您下载它们

$certifikit cli git:(主)。/cft—主机badsl.com—不安全—输出tmp
中国:**badsl.com
引脚:sha256/F522E496C72FCCC623F1FFB9DA5A79CDEFE16340851F22D23D0CD2A58066F
SAN:*.badsl.com,badsl.com
密钥用法:数字签名、密钥加密
Ext键用法:serverAuth、clientAuth
权限信息访问:
ocsp:http://ocsp.digicert.com
凯恩斯:http://cacerts.digicert.com/DigiCertSHA2SecureServerCA.crt
有效期:2020-03-23T00:00:00Z..2022-05-17T12:00:00Z(1年)
CA:错
CN:DigiCert SHA2安全服务器CA
引脚:sha256/e6426f344330d0a8eb080bbb7976391d976fc824b5dc16c0d15246d5148ff75c
存储区域网络:
密钥用法:数字签名、KeyCertSign、CRLSign
权限信息访问:
ocsp:http://ocsp.digicert.com
有效期:2013-03-08T12:00:00Z..2023-03-08T12:00:00Z(2年)
CA:真实最大中间值:0
CN:DigiCert全局根CA(由本地受信任的根签名)
引脚:sha256/aff988906dde12955d9bebbf928fdcc31cce328d5b9384f21c8941ca26e20391
存储区域网络:
OU:www.digicert.com
密钥用法:数字签名、KeyCertSign、CRLSign
有效期:2006-11-10T00:00:00Z..2031-11-10T00:00:00Z(11年)
CA:是的
$certifikit cli git:(主)✗ ls tmp
aff988906dde12955d9bebbf928fdcc31cce328d5b9384f21c8941ca26e20391.pem F522E496C72FCCC623F1FFB9DA5A79CDEFE16340851F2D23D0CD2A58066F.pem
e6426f344330d0a8eb080bbb7976391d976fc824b5dc16c0d15246d5148ff75c.pem

你的意思是“你在truststore中有一些自签名证书,你想查看它们的内容/列出它们吗?”我请求https网站,我想查看证书详细信息并将其保存到数据库你的意思是“你在truststore中有一些自签名证书,你想查看它们的内容/列出它们吗?”我请求一个https网站,我想查看证书详细信息并将其保存到数据库