Https详解
1:具体流程:
1)客户端和服务端通信,通信过程会被黑客窃取,需要加密,需要用到加密密钥SessionKey
2)双方在交换SessionKey的过程中,也会出现SessionKey被窃取的风险
3)服务端产生公私钥对,将公钥PubKey发给客户端,客户端用PubKey加密SessionKey,发给服务端,服务端用PriKey解密,得到SessionKey
4)但是前面一步有风险,客户端得到的公钥也可能不是服务端发过来的,服务端在发送公钥的过程中,被黑客拦截,黑客换成自己的公钥发送给客户端,所以服务端的公钥需要更高一级的CA机构来保证
5)CA机构有自己的公私钥对,CA的私钥对服务端的公钥(不止公钥,还包括版本号、服务器地址等其他信息)进行hash计算,得到hashResult,然后用CA的私钥对该hashResult进行加密,得到数字签名,然后将内容ContentS和数字签名合成一本数字证书,发送给客户端
6)客户端内置CA机构的证书(可以得到CA的公钥),收到服务端发过来的证书之后,用CA的公钥解密数字签名,得到hashResult1,然后对证书内的ContentS进行hash计算得到hashResult2,两者对比,相等的话,就说明得到的服务端的公钥是没问题的。
2:单向认证过程:
1).客户端向服务器请求HTTPS连接
2).服务器确认并返回证书(证书含有服务端公钥)
3).客户端验证服务器发来的证书
4).确认成功,生成随机密钥A,用公钥进行加密后发给服务器
5).服务器用私钥解密出随机密钥A,并发出确认,握手完成
3:Android系统会内置合法ca机构的根证书,只要服务器证书是由这些机构或者是其中间机构签发的那么系统会自动做安全校验,我们不需要做任何事情,直接请求https就可以。
但是如果服务器证书是自签名的,就需要我们对请求逻辑做一定的改造,不然你发起的所有请求都会失败,因为系统在做ssl证书校验时会认为这是一个非法请求直接阻断掉
4:自定义证书的验证:将服务端提供的.crt证书load进去,https通信的时候,只有服务端提供的公钥才会通过,其他比如黑客的冒充的公钥会拒绝。
绕过所有SSL意思是,所有服务器发送过来的公钥都接收,不会进行验证,存在风险,有可能公钥是黑客发过来的。
单向认证代码:
InputStream inputStream = assetManager.open(certificateFile); Certificate certificate = certificateFactory.generateCertificate(inputStream); //Keystore KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); keystore.load(null, certificatePassword.toCharArray()); keystore.setCertificateEntry("ca", certificate);
//TrustManager String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(tmfAlgorithm); trustManagerFactory.init(keystore);
//sslContext sslContext.init(null, trustManagerFactory.getTrustManagers(), null); inputStream.close(); return sslContext.getSocketFactory();
- 服务端的证书被解析后存储在一个密钥库(keystore)中。
- 密钥库被用来初始化一个信任管理器工厂(TrustManagerFactory)。
- 信任管理器工厂的配置中包括了从密钥库中加载的证书。
- 最后,信任管理器工厂被用来初始化SSL上下文(SSLContext),确保与服务器建立的安全连接可以验证服务器的证书,并进行安全的通信。
KeyStore, TrustManagerFactory, 和 SSLContext 是在Java中用于配置和管理SSL/TLS通信的关键组件,它们的作用如下:
-
KeyStore (密钥库):
KeyStore是用于存储密钥和证书的安全容器。它可以包含私钥、公钥、数字证书以及其他安全材料。- 具体作用:用于存储自己的证书和私钥,也可以用来存储受信任的根证书或中间证书,以供验证远程服务器的证书。
-
TrustManagerFactory (信任管理器工厂):
TrustManagerFactory是用于管理信任管理器的工厂类。信任管理器用于验证远程服务器的证书是否受信任。- 具体作用:加载信任材料(通常是根证书和中间证书),验证服务器证书的有效性,确保与远程服务器的通信是安全的。
-
SSLContext:
SSLContext是用于配置和管理安全套接字(SSL/TLS)通信的上下文对象。它包括SSL/TLS协议参数、密钥管理和信任管理的配置。- 具体作用:初始化SSL/TLS协议的配置,包括加密算法、协议版本、信任管理器等。一旦
SSLContext被初始化,它可以用来创建安全套接字工厂,以确保通信数据的机密性和安全性。
通常,这些组件在安全通信中一起使用。密钥库用于存储本地证书和私钥,信任管理器工厂用于验证远程服务器的证书,而SSLContext用于配置和管理通信的安全参数。这些组件的组合确保了通信的安全性,包括加密、认证和完整性验证。
双向认证代码:java:
AssetManager assetManager = NymphSdkService.getInstance().getContext().getAssets(); CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); SSLContext sslContext = SSLContext.getInstance(protocol); Timber.i("--->certificate file:%s", certificateFile); if (mutualAuthEnabled) { InputStream clientCertIn = assetManager.open(certificateFile); InputStream clientPrivateKeyIn = assetManager.open(privateKeyFile); InputStream caFileIn = assetManager.open(caFile);
Certificate certificate = certificateFactory.generateCertificate(caFileIn);
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
trustStore.setCertificateEntry("ca", certificate);
//TrustManagerFactory
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
final X509TrustManager origTrustmanager = (X509TrustManager) trustManagers[0];
TrustManager[] wrappedTrustManagers = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
origTrustmanager.checkClientTrusted(x509Certificates, s);
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return origTrustmanager.getAcceptedIssuers();
}
}
};
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
KeyManagerFactory.getDefaultAlgorithm());
// 服务器端需要验证的客户端证书,其实就是客户端的keystore
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
Certificate clientCert = certificateFactory.generateCertificate(clientCertIn);
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] data = new byte[4096];
int count = -1;
while ((count = clientPrivateKeyIn.read(data, 0, 4096)) != -1)
outStream.write(data, 0, count);
String key = new String(outStream.toByteArray(), "ISO-8859-1");
StringBuilder pkcs8Lines = new StringBuilder();
BufferedReader rdr = new BufferedReader(new StringReader(key));
String line;
while ((line = rdr.readLine()) != null) {
pkcs8Lines.append(line);
}
String pkcs8Pem = pkcs8Lines.toString();
pkcs8Pem = pkcs8Pem.replace("-----BEGIN PRIVATE KEY-----", "");
pkcs8Pem = pkcs8Pem.replace("-----END PRIVATE KEY-----", "");
pkcs8Pem = pkcs8Pem.replaceAll("\\s+", "");
byte[] encoderByte = Base64.decode(pkcs8Pem, Base64.DEFAULT);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoderByte);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privateKey = kf.generatePrivate(keySpec);
keyStore.setKeyEntry("client", privateKey, null, new Certificate[]{clientCert});
keyManagerFactory.init(keyStore, null);
sslContext.init(keyManagerFactory.getKeyManagers(), wrappedTrustManagers, null);
clientCertIn.close();
clientPrivateKeyIn.close();
caFileIn.close();
return sslContext.getSocketFactory();
TrustStore存储受信任的根证书和中间证书,用于验证服务器证书的有效性。TrustStore中的证书被用于创建TrustManager实例。TrustManagerFactory用于创建TrustManager数组,其中的TrustManager实例使用TrustStore中的根证书和中间证书来验证服务器证书。KeyStore存储客户端证书和私钥,通常在双向认证情况下使用。KeyStore存储在KeyManagerFactory中,用于创建客户端密钥管理器。SSLContext用于配置和管理SSL/TLS通信的上下文,包括信任管理器、密钥管理器等参数。
trustmanager:
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { @Override public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { //该方法在服务端使用,用来校验客户端的安全性 } @Override public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { //该方法在客户端使用,用来校验服务端的安全性 } @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } }};
certificateFile、privateKeyFile 和 caFile 分别代表了不同的文件,其作用如下:
-
certificateFile:这是客户端的证书文件,包含客户端的公钥和身份信息。这个文件通常包含客户端的公钥证书,用于在双向认证中证明客户端的身份。 -
privateKeyFile:这是客户端的私钥文件,用于与客户端证书一起形成完整的密钥对。私钥是机密的,用于对消息进行数字签名,以证明消息的真实性。 -
caFile:这是证书颁发机构 (CA) 的根证书文件,也称为根证书。CA 根证书用于验证服务器证书,以确保它们由受信任的 CA 签发。这样可以确保客户端与服务器建立的连接是安全的。
ByteArrayOutputStream outStream = new ByteArrayOutputStream(); byte[] data = new byte[4096]; int count = -1; while ((count = clientPrivateKeyIn.read(data, 0, 4096)) != -1) outStream.write(data, 0, count); String key = new String(outStream.toByteArray(), "ISO-8859-1"); StringBuilder pkcs8Lines = new StringBuilder(); BufferedReader rdr = new BufferedReader(new StringReader(key)); String line; while ((line = rdr.readLine()) != null) { pkcs8Lines.append(line); } String pkcs8Pem = pkcs8Lines.toString(); pkcs8Pem = pkcs8Pem.replace("-----BEGIN PRIVATE KEY-----", ""); pkcs8Pem = pkcs8Pem.replace("-----END PRIVATE KEY-----", ""); pkcs8Pem = pkcs8Pem.replaceAll("\\s+", ""); byte[] encoderByte = Base64.decode(pkcs8Pem, Base64.DEFAULT); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoderByte); KeyFactory kf = KeyFactory.getInstance("RSA"); PrivateKey privateKey = kf.generatePrivate(keySpec); keyStore.setKeyEntry("client", privateKey, null, new Certificate[]{clientCert}); keyManagerFactory.init(keyStore, null);
上述代码段的主要目的是将从私钥文件中读取的私钥数据转换为 PKCS#8 格式,并将它存储在 KeyStore 中。这是为了确保私钥符合标准的私钥格式,并能够在 SSL/TLS 连接中使用。
具体流程如下:
- 读取私钥文件中的私钥数据。
- 将私钥数据转换为 PKCS#8 格式,包括去除起始和结束标志以及空白字符。
- 将处理后的 PKCS#8 格式私钥数据转换为字节数组。
- 使用
PKCS8EncodedKeySpec创建一个用于生成私钥的规范。 - 生成私钥对象。
- 将生成的私钥对象与客户端证书一起存储在
KeyStore中,以供后续在 SSL/TLS 连接中使用。
这个过程确保了私钥的正确格式和可用性,以便在客户端与服务器之间建立安全的 SSL/TLS 连接时使用。私钥格式的正确性对于双向认证非常重要,因为它影响了客户端的身份验证。
3)trustManager的kotlin:
所以代码里面的步骤是:xxx.crt->certificate->trustManager->sslContext->sslFactory
trustManager负责网站证书的认证,所以要绕过证书检查,重写的就是trustManager
private val trustManager: TrustManager = object : X509TrustManager { @Throws(CertificateException::class) override fun checkClientTrusted( chain: Array<java.security.cert.X509Certificate>, authType: String ) { } @Throws(CertificateException::class) override fun checkServerTrusted( chain: Array<java.security.cert.X509Certificate>, authType: String ) { } override fun getAcceptedIssuers(): Array<X509Certificate?> { return arrayOfNulls(0) } }
certificateFile和privateKeyFile:
通常情况下,certificateFile 和 privateKeyFile 是在事先的证书和私钥生成过程中创建的。生成这些文件通常需要使用工具(如 OpenSSL)或编程方式来生成。下面是一个示例,展示如何使用 OpenSSL 生成客户端的证书和私钥文件:
-
生成客户端私钥文件:
bash
-
openssl genpkey -algorithm RSA -out client-private-key.pem -
生成客户端证书签发请求 (CSR) 文件:
bash -
openssl req -new -key client-private-key.pem -out client-csr.pem -
使用证书颁发机构 (CA) 签发客户端证书文件:
bash
-
openssl x509 -req -in client-csr.pem -CA ca-certificate.pem -CAkey ca-private-key.pem -out client-certificate.pem -days 365
在这个示例中, client-private-key.pem 是客户端私钥文件,client-certificate.pem 是客户端证书文件。这两个文件可以被用作客户端的证书和私钥,然后在代码中被加载和处理,如之前提供的代码示例所示。
4)trustore,对于自定义证书,就是把服务器提供的证书,设置到trustStore里面,后续交易,trustStore会用该证书验证服务器的证书是否有效。
keystore,用于存储服务器的身份证书该服务器将在连接上向客户端显示该证书,而客户端上的信任存储设置必须包含此证书才能使连接正常工作。
private fun getRetrofit(): Retrofit {
val httpLoggingInterceptor = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
val httpClient = OkHttpClient.Builder()
.hostnameVerifier { _, _ -> true }
//.sslSocketFactory(createIgnoreVerifySSL("TLS"), trustManager as X509TrustManager)
.sslSocketFactory(
sSLSocketFactory,
trustManagers?.get(0) as X509TrustManager
)
.addInterceptor(httpLoggingInterceptor)
.build()
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(baseUrl)
.client(httpClient)
.build()
}
private val trustManagers: Array<TrustManager>?
private get() = try {
val certificateFactory = CertificateFactory.getInstance("X.509")
Timber.i("--->使用的证书:$certificateFile")
val inputStream = ReaderApplication.context?.assets?.open(certificateFile)
val certificate = certificateFactory.generateCertificate(inputStream)
val keystore =
KeyStore.getInstance(KeyStore.getDefaultType())
keystore.load(null, certificatePassword.toCharArray())
keystore.setCertificateEntry("ca", certificate)
inputStream?.close()
requireNotNull(keystore) { "Keystore may not be null" }
Timber.d("Initializing trust manager")
val trustManagerFactory =
TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm()
)
trustManagerFactory.init(keystore)
trustManagerFactory.trustManagers
} catch (e: Exception) {
e.printStackTrace()
null
}
private val sSLSocketFactory: SSLSocketFactory?
private get() = try {
val sslContext = SSLContext.getInstance("TLSv1.2")
sslContext.init(null, trustManagers, null)
sslContext.socketFactory
} catch (e: Exception) {
e.printStackTrace()
null
}
5:
X.509 证书文件的不同后缀PEM DER CRT CER其实对应两种编码方案
- Base64编码
- ASN1.1 DER编码
PEM文件的后缀可以是:.crt, .pem, .cer, and .key
- 1 PEM( “Privacy Enhanced Mail”)是最常用的X.509 证书文件后缀
PEM 文件是一个文本文件,采用了Base64 ASCII 编码;所以打开文件口看到(e.g. -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----).
一个PEM文件可以包含公钥证书/私钥/或者能形成证书链的多个证书 -
其实证书或者私钥,都是先根据规范给ASN.1描述,然后进行DER编码,生成二进制文件(DER),然后对二进制文件再Base64编码,即可以生成ASCII码文件(PEM)。
所以DER到PEM转换,其实就是Base64编码,反之,则是Base64解码
6:Openssl:
1)下载地址:
http://slproweb.com/products/Win32OpenSSL.html
2)进入Openssl的bin目录下,Shift+右键,打开:Windows PowerShell
3)./openssl version查看openssl指令是否可行
4)将.crt(base64)文件转为明文指令:
./openssl x509 in xx.crt -text -noout
crt文件:
-----BEGIN CERTIFICATE-----
MIIHLDCCBhSgAwIBAgIQRvQBEbgWZHm89U/+ykfPIzANBgkqhkiG9w0BAQsFADCB
ujELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsT
H1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAy
MDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEuMCwG
A1UEAxMlRW50cnVzdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEwxSzAeFw0y
MDEyMjIyMzE4MjVaFw0yMjAxMjEyMzE4MjRaMHUxCzAJBgNVBAYTAlVTMRMwEQYD
VQQIEwpDYWxpZm9ybmlhMRQwEgYDVQQHEwtGb3N0ZXIgQ2l0eTEgMB4GA1UEChMX
Q3liZXJzb3VyY2UgQ29ycG9yYXRpb24xGTAXBgNVBAMTEHBucnN0YWdlLmljMy5j
b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCJJ95Uf3J/S3xW2CvL
hu3J34VmfJT946bS8hKQtgP7cchPBlPiXp3eDIQ7RSAg95SwCuynnwvfWO4ewPZq
/gbgRS9Hh7Kp4NPTwp0irC3qcJYQogAOfV2eBpYOMNj/BdFJuRozMp0yfMrMLcOi
V6nZiQOBIAKXcQh/NCPqzi4xuBejq+Jna2RTGDizjcUkg2dPmjd8/3s5fq94Gc8I
116ep9yc6Fy4CrPrHOSoC3hCzgHFhS0Ey5NXRAOjl6tLA+xskNjU/bjtH1y6kJX6
JJD5iGR66DShNEQrAaXdQX6Gd75ZrXgHGGdLHPzseqPQGUnBHdh2esITIxSgV/dR
+4odAgMBAAGjggNwMIIDbDAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBSIDOwbWeLo
l7EtAoutD6/2ucoYNzAfBgNVHSMEGDAWgBSConB03bxTP8971PfNf6dgxgpMvzBo
BggrBgEFBQcBAQRcMFowIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLmVudHJ1c3Qu
bmV0MDMGCCsGAQUFBzAChidodHRwOi8vYWlhLmVudHJ1c3QubmV0L2wxay1jaGFp
bjI1Ni5jZXIwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5lbnRydXN0Lm5l
dC9sZXZlbDFrLmNybDB/BgNVHREEeDB2ghBwbnJzdGFnZS5pYzMuY29tghhhcGlz
dGFnZS5jeWJlcnNvdXJjZS5jb22CGGNna3N0YWdlLmN5YmVyc291cmNlLmNvbYIa
Ki5hcGlzdGFnZS5jeWJlcnNvdXJjZS5jb22CEioucG5yc3RhZ2UuaWMzLmNvbTAO
BgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMEwG
A1UdIARFMEMwNwYKYIZIAYb6bAoBBTApMCcGCCsGAQUFBwIBFhtodHRwczovL3d3
dy5lbnRydXN0Lm5ldC9ycGEwCAYGZ4EMAQICMIIBfQYKKwYBBAHWeQIEAgSCAW0E
ggFpAWcAdgBRo7D1/QF5nFZtuDd4jwykeswbJ8v3nohCmg3+1IsF5QAAAXaMvyVr
AAAEAwBHMEUCIQC4RzUXXKFppZZamAOcc2h6aQh4Eprpjw6xjBmvxede4QIgDx+S
FURsDV9Ecbi1iBTZAiYG0rVXoC5o5cCZifdHYXgAdQBWFAaaL9fC7NP14b1Esj7H
Rna5vJkRXMDvlJhV1onQ3QAAAXaMvyVwAAAEAwBGMEQCIEeEXJMIBrNmWu89m+L0
wAXLnkBoATM/6xnXajO3ICOGAiAoJ31gBNu/H9IRbN75jVAcA9Bw5yiVwXJ3V3RM
HGYMwAB2AEalVet1+pEgMLWiiWn0830RLEF0vv1JuIWr8vxw/m1HAAABdoy/J6sA
AAQDAEcwRQIgFK+TtHrx04KABHFDm0By0q5IYznA3eliNHgCVmrG5IACIQCKWU2p
JWZ4hkJJellHcMBDcKZpbgCiX7lUQRNtS1Zs6jANBgkqhkiG9w0BAQsFAAOCAQEA
dBSKeFSwSESs0x1u5GBTLYiE5m7ROLPCI7wciX1VqcrjBe3zz/NhcIKjAkFQX4/v
gi59DB6zN7C5aJ4WFuQqBNwoatsipRpP8bbSaEUp1uOT5MjqdcZwonbIt9+VU8xE
WyKBMpO2gSOWRSPJuf2Fbaebq3mV8MbSBki03W+WuwvapbeP12H3peMilOuXjoHw
Bejzh4n9jkaIsUvPz/O9Of3MG1oLpCaynicezbMpDTd+j6EO+p7fAVE3gSmp5pOH
+CkpLiGE9rmpuTbcv8wDurmNsZIMTEEs9+/1T97DCQ1+C6QVwCjciLZb+2O8+Ot2
ZXdPzB4NAIPkDaGMUloU8A==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFDjCCA/agAwIBAgIMDulMwwAAAABR03eFMA0GCSqGSIb3DQEBCwUAMIG+MQsw
CQYDVQQGEwJVUzEWMBQGA1UEChMNRW50cnVzdCwgSW5jLjEoMCYGA1UECxMfU2Vl
IHd3dy5lbnRydXN0Lm5ldC9sZWdhbC10ZXJtczE5MDcGA1UECxMwKGMpIDIwMDkg
RW50cnVzdCwgSW5jLiAtIGZvciBhdXRob3JpemVkIHVzZSBvbmx5MTIwMAYDVQQD
EylFbnRydXN0IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjAeFw0x
NTEwMDUxOTEzNTZaFw0zMDEyMDUxOTQzNTZaMIG6MQswCQYDVQQGEwJVUzEWMBQG
A1UEChMNRW50cnVzdCwgSW5jLjEoMCYGA1UECxMfU2VlIHd3dy5lbnRydXN0Lm5l
dC9sZWdhbC10ZXJtczE5MDcGA1UECxMwKGMpIDIwMTIgRW50cnVzdCwgSW5jLiAt
IGZvciBhdXRob3JpemVkIHVzZSBvbmx5MS4wLAYDVQQDEyVFbnRydXN0IENlcnRp
ZmljYXRpb24gQXV0aG9yaXR5IC0gTDFLMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEA2j+W0E25L0Tn2zlem1DuXKVh2kFnUwmqAJqOV38pa9vH4SEkqjrQ
jUcj0u1yFvCRIdJdt7hLqIOPt5EyaM/OJZMssn2XyP7BtBe6CZ4DkJN7fEmDImiK
m95HwzGYei59QAvS7z7Tsoyqj0ip/wDoKVgG97aTWpRzJiatWA7lQrjV6nN5ZGhT
JbiEz5R6rgZFDKNrTdDGvuoYpDbwkrK6HIiPOlJ/915tgxyd8B/lw9bdpXiSPbBt
LOrJz5RBGXFEaLpHPATpXbo+8DX3Fbae8i4VHj9HyMg4p3NFXU2wO7GOFyk36t0F
ASK7lDYqjVs1/lMZLwhGwSqzGmIdTivZGwIDAQABo4IBDDCCAQgwDgYDVR0PAQH/
BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwMwYIKwYBBQUHAQEEJzAlMCMGCCsG
AQUFBzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5ldDAwBgNVHR8EKTAnMCWgI6Ah
hh9odHRwOi8vY3JsLmVudHJ1c3QubmV0L2cyY2EuY3JsMDsGA1UdIAQ0MDIwMAYE
VR0gADAoMCYGCCsGAQUFBwIBFhpodHRwOi8vd3d3LmVudHJ1c3QubmV0L3JwYTAd
BgNVHQ4EFgQUgqJwdN28Uz/Pe9T3zX+nYMYKTL8wHwYDVR0jBBgwFoAUanImetAe
733nO2lR1GyNn5ASZqswDQYJKoZIhvcNAQELBQADggEBADnVjpiDYcgsY9NwHRkw
y/YJrMxp1cncN0HyMg/vdMNY9ngnCTQIlZIv19+4o/0OgemknNM/TWgrFTEKFcxS
BJPok1DD2bHi4Wi3Ogl08TRYCj93mEC45mj/XeTIRsXsgdfJghhcg85x2Ly/rJkC
k9uUmITSnKa1/ly78EqvIazCP0kkZ9Yujs+szGQVGHLlbHfTUqi53Y2sAEo1GdRv
c6N172tkw+CNgxKhiucOhk3YtCAbvmqljEtoZuMrx1gL+1YQ1JH7HdMxWBCMRON1
exCdtTix9qrKgWRs6PLigVWXUX/hwidQosk8WwBD9lu51aX8/wdQQGcHsFXwt35u
Lcw=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIE/zCCA+egAwIBAgIEUdNARDANBgkqhkiG9w0BAQsFADCBsDELMAkGA1UEBhMC
VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl
cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE0MDkyMjE3MTQ1N1oXDTI0MDkyMzAx
MzE1M1owgb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgw
JgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQL
EzAoYykgMjAwOSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9u
bHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
eSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuoS2ctueDGvi
mekwAad26jK4lUEaydphTlhyz/72gnm/c2EGCqUn2LNf00VOHHLWTjLycooP94MZ
0GqAgABFHrDH55q/ElcnHKNoLwqHvWprDl5l8xx31dSFjXAhtLMy54ui1YY5ArG4
0kfO5MlJxDun3vtUfVe+8OhuwnmyOgtV4lCYFjITXC94VsHClLPyWuQnmp8k18bs
0JslguPMwsRFxYyXegZrKhGfqQpuSDtv29QRGUL3jwe/9VNfnD70FyzmaaxOMkxi
d+q36OW7NLwZi66cUee3frVTsTMi5W3PcDwa+uKbZ7aD9I2lr2JMTeBYrGQ0EgP4
to2UYySkcQIDAQABo4IBDzCCAQswDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQI
MAYBAf8CAQEwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8vb2Nz
cC5lbnRydXN0Lm5ldDAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3JsLmVudHJ1
c3QubmV0L3Jvb3RjYTEuY3JsMDsGA1UdIAQ0MDIwMAYEVR0gADAoMCYGCCsGAQUF
BwIBFhpodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NQUzAdBgNVHQ4EFgQUanImetAe
733nO2lR1GyNn5ASZqswHwYDVR0jBBgwFoAUaJDkZ6SmU4DHhmak8fdLQ/uEvW0w
DQYJKoZIhvcNAQELBQADggEBAGkzg/woem99751V68U+ep11s8zDODbZNKIoaBjq
HmnTvefQd9q4AINOSs9v0fHBIj905PeYSZ6btp7h25h3LVY0sag82f3Azce/BQPU
AsXx5cbaCKUTx2IjEdFhMB1ghEXveajGJpOkt800uGnFE/aRs8lFc3a2kvZ2Clvh
A0e36SlMkTIjN0qcNdh4/R0f5IOJJICtt/nP5F2l1HHEhVtwH9s/HAHrGkUmMRTM
Zb9n3srMM2XlQZHXN75BGpad5oqXnafOrE6aPb0BoGrZTyIAi0TVaWJ7LuvMuueS
fWlnPfy4fN5Bh9Bp6roKGHoalUOzeXEodm2h+1dK7E3IDhA=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC
VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl
cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw
NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw
NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy
ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV
BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ
KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo
Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4
4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9
KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI
rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi
94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB
sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi
gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo
kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE
vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t
O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua
AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP
9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/
eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m
0vdXcDazv/wor3ElhVsT/h5/WrQ8
-----END CERTIFICATE-----
生成明文:

Certificate:
Data:
Version: 3 (0x2)
Serial Number:
46:f4:01:11:b8:16:64:79:bc:f5:4f:fe:ca:47:cf:23
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, O = "Entrust, Inc.", OU = See www.entrust.net/legal-terms, OU = "(c) 2012 Entrust, Inc. - for authorized use only", CN = Entrust Certification Authority - L1K
Validity
Not Before: Dec 22 23:18:25 2020 GMT
Not After : Jan 21 23:18:24 2022 GMT
Subject: C = US, ST = California, L = Foster City, O = Cybersource Corporation, CN = pnrstage.ic3.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:89:27:de:54:7f:72:7f:4b:7c:56:d8:2b:cb:86:
ed:c9:df:85:66:7c:94:fd:e3:a6:d2:f2:12:90:b6:
03:fb:71:c8:4f:06:53:e2:5e:9d:de:0c:84:3b:45:
20:20:f7:94:b0:0a:ec:a7:9f:0b:df:58:ee:1e:c0:
f6:6a:fe:06:e0:45:2f:47:87:b2:a9:e0:d3:d3:c2:
9d:22:ac:2d:ea:70:96:10:a2:00:0e:7d:5d:9e:06:
96:0e:30:d8:ff:05:d1:49:b9:1a:33:32:9d:32:7c:
ca:cc:2d:c3:a2:57:a9:d9:89:03:81:20:02:97:71:
08:7f:34:23:ea:ce:2e:31:b8:17:a3:ab:e2:67:6b:
64:53:18:38:b3:8d:c5:24:83:67:4f:9a:37:7c:ff:
7b:39:7e:af:78:19:cf:08:d7:5e:9e:a7:dc:9c:e8:
5c:b8:0a:b3:eb:1c:e4:a8:0b:78:42:ce:01:c5:85:
2d:04:cb:93:57:44:03:a3:97:ab:4b:03:ec:6c:90:
d8:d4:fd:b8:ed:1f:5c:ba:90:95:fa:24:90:f9:88:
64:7a:e8:34:a1:34:44:2b:01:a5:dd:41:7e:86:77:
be:59:ad:78:07:18:67:4b:1c:fc:ec:7a:a3:d0:19:
49:c1:1d:d8:76:7a:c2:13:23:14:a0:57:f7:51:fb:
8a:1d
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Key Identifier:
88:0C:EC:1B:59:E2:E8:97:B1:2D:02:8B:AD:0F:AF:F6:B9:CA:18:37
X509v3 Authority Key Identifier:
82:A2:70:74:DD:BC:53:3F:CF:7B:D4:F7:CD:7F:A7:60:C6:0A:4C:BF
Authority Information Access:
OCSP - URI:http://ocsp.entrust.net
CA Issuers - URI:http://aia.entrust.net/l1k-chain256.cer
X509v3 CRL Distribution Points:
Full Name:
URI:http://crl.entrust.net/level1k.crl
X509v3 Subject Alternative Name:
DNS:pnrstage.ic3.com, DNS:apistage.cybersource.com, DNS:cgkstage.cybersource.com, DNS:*.apistage.cybersource.com, DNS:*.pnrstage.ic3.com
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Certificate Policies:
Policy: 2.16.840.1.114028.10.1.5
CPS: https://www.entrust.net/rpa
Policy: 2.23.140.1.2.2
CT Precertificate SCTs:
Signed Certificate Timestamp:
Version : v1 (0x0)
Log ID : 51:A3:B0:F5:FD:01:79:9C:56:6D:B8:37:78:8F:0C:A4:
7A:CC:1B:27:CB:F7:9E:88:42:9A:0D:FE:D4:8B:05:E5
Timestamp : Dec 22 23:18:25.899 2020 GMT
Extensions: none
Signature : ecdsa-with-SHA256
30:45:02:21:00:B8:47:35:17:5C:A1:69:A5:96:5A:98:
03:9C:73:68:7A:69:08:78:12:9A:E9:8F:0E:B1:8C:19:
AF:C5:E7:5E:E1:02:20:0F:1F:92:15:44:6C:0D:5F:44:
71:B8:B5:88:14:D9:02:26:06:D2:B5:57:A0:2E:68:E5:
C0:99:89:F7:47:61:78
Signed Certificate Timestamp:
Version : v1 (0x0)
Log ID : 56:14:06:9A:2F:D7:C2:EC:D3:F5:E1:BD:44:B2:3E:C7:
46:76:B9:BC:99:11:5C:C0:EF:94:98:55:D6:89:D0:DD
Timestamp : Dec 22 23:18:25.904 2020 GMT
Extensions: none
Signature : ecdsa-with-SHA256
30:44:02:20:47:84:5C:93:08:06:B3:66:5A:EF:3D:9B:
E2:F4:C0:05:CB:9E:40:68:01:33:3F:EB:19:D7:6A:33:
B7:20:23:86:02:20:28:27:7D:60:04:DB:BF:1F:D2:11:
6C:DE:F9:8D:50:1C:03:D0:70:E7:28:95:C1:72:77:57:
74:4C:1C:66:0C:C0
Signed Certificate Timestamp:
Version : v1 (0x0)
Log ID : 46:A5:55:EB:75:FA:91:20:30:B5:A2:89:69:F4:F3:7D:
11:2C:41:74:BE:FD:49:B8:85:AB:F2:FC:70:FE:6D:47
Timestamp : Dec 22 23:18:26.475 2020 GMT
Extensions: none
Signature : ecdsa-with-SHA256
30:45:02:20:14:AF:93:B4:7A:F1:D3:82:80:04:71:43:
9B:40:72:D2:AE:48:63:39:C0:DD:E9:62:34:78:02:56:
6A:C6:E4:80:02:21:00:8A:59:4D:A9:25:66:78:86:42:
49:7A:59:47:70:C0:43:70:A6:69:6E:00:A2:5F:B9:54:
41:13:6D:4B:56:6C:EA
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
74:14:8a:78:54:b0:48:44:ac:d3:1d:6e:e4:60:53:2d:88:84:
e6:6e:d1:38:b3:c2:23:bc:1c:89:7d:55:a9:ca:e3:05:ed:f3:
cf:f3:61:70:82:a3:02:41:50:5f:8f:ef:82:2e:7d:0c:1e:b3:
37:b0:b9:68:9e:16:16:e4:2a:04:dc:28:6a:db:22:a5:1a:4f:
f1:b6:d2:68:45:29:d6:e3:93:e4:c8:ea:75:c6:70:a2:76:c8:
b7:df:95:53:cc:44:5b:22:81:32:93:b6:81:23:96:45:23:c9:
b9:fd:85:6d:a7:9b:ab:79:95:f0:c6:d2:06:48:b4:dd:6f:96:
bb:0b:da:a5:b7:8f:d7:61:f7:a5:e3:22:94:eb:97:8e:81:f0:
05:e8:f3:87:89:fd:8e:46:88:b1:4b:cf:cf:f3:bd:39:fd:cc:
1b:5a:0b:a4:26:b2:9e:27:1e:cd:b3:29:0d:37:7e:8f:a1:0e:
fa:9e:df:01:51:37:81:29:a9:e6:93:87:f8:29:29:2e:21:84:
f6:b9:a9:b9:36:dc:bf:cc:03:ba:b9:8d:b1:92:0c:4c:41:2c:
f7:ef:f5:4f:de:c3:09:0d:7e:0b:a4:15:c0:28:dc:88:b6:5b:
fb:63:bc:f8:eb:76:65:77:4f:cc:1e:0d:00:83:e4:0d:a1:8c:
52:5a:14:f0
参考:
https://zhuanlan.zhihu.com/p/105052428
双向认证:
https://blog.csdn.net/qq_37079898/article/details/132411367
https://codeleading.com/article/37864606405/
trustManager:

浙公网安备 33010602011771号