|
|
@ -1,6 +1,5 @@ |
|
|
|
package io.legado.app.help.http |
|
|
|
package io.legado.app.help.http |
|
|
|
|
|
|
|
|
|
|
|
import javax.net.ssl.* |
|
|
|
|
|
|
|
import java.io.IOException |
|
|
|
import java.io.IOException |
|
|
|
import java.io.InputStream |
|
|
|
import java.io.InputStream |
|
|
|
import java.security.KeyManagementException |
|
|
|
import java.security.KeyManagementException |
|
|
@ -9,10 +8,11 @@ import java.security.NoSuchAlgorithmException |
|
|
|
import java.security.cert.CertificateException |
|
|
|
import java.security.cert.CertificateException |
|
|
|
import java.security.cert.CertificateFactory |
|
|
|
import java.security.cert.CertificateFactory |
|
|
|
import java.security.cert.X509Certificate |
|
|
|
import java.security.cert.X509Certificate |
|
|
|
|
|
|
|
import javax.net.ssl.* |
|
|
|
|
|
|
|
|
|
|
|
object SSLHelper { |
|
|
|
object SSLHelper { |
|
|
|
|
|
|
|
|
|
|
|
val sslSocketFactory: SSLParams |
|
|
|
val sslSocketFactory: SSLParams? |
|
|
|
get() = getSslSocketFactoryBase(null, null, null) |
|
|
|
get() = getSslSocketFactoryBase(null, null, null) |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -41,15 +41,15 @@ object SSLHelper { |
|
|
|
val unsafeHostnameVerifier: HostnameVerifier = HostnameVerifier { _, _ -> true } |
|
|
|
val unsafeHostnameVerifier: HostnameVerifier = HostnameVerifier { _, _ -> true } |
|
|
|
|
|
|
|
|
|
|
|
class SSLParams { |
|
|
|
class SSLParams { |
|
|
|
var sSLSocketFactory: SSLSocketFactory? = null |
|
|
|
lateinit var sSLSocketFactory: SSLSocketFactory |
|
|
|
var trustManager: X509TrustManager? = null |
|
|
|
lateinit var trustManager: X509TrustManager |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* https单向认证 |
|
|
|
* https单向认证 |
|
|
|
* 可以额外配置信任服务端的证书策略,否则默认是按CA证书去验证的,若不是CA可信任的证书,则无法通过验证 |
|
|
|
* 可以额外配置信任服务端的证书策略,否则默认是按CA证书去验证的,若不是CA可信任的证书,则无法通过验证 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun getSslSocketFactory(trustManager: X509TrustManager): SSLParams { |
|
|
|
fun getSslSocketFactory(trustManager: X509TrustManager): SSLParams? { |
|
|
|
return getSslSocketFactoryBase(trustManager, null, null) |
|
|
|
return getSslSocketFactoryBase(trustManager, null, null) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -57,7 +57,7 @@ object SSLHelper { |
|
|
|
* https单向认证 |
|
|
|
* https单向认证 |
|
|
|
* 用含有服务端公钥的证书校验服务端证书 |
|
|
|
* 用含有服务端公钥的证书校验服务端证书 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun getSslSocketFactory(vararg certificates: InputStream): SSLParams { |
|
|
|
fun getSslSocketFactory(vararg certificates: InputStream): SSLParams? { |
|
|
|
return getSslSocketFactoryBase(null, null, null, *certificates) |
|
|
|
return getSslSocketFactoryBase(null, null, null, *certificates) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -66,7 +66,7 @@ object SSLHelper { |
|
|
|
* bksFile 和 password -> 客户端使用bks证书校验服务端证书 |
|
|
|
* bksFile 和 password -> 客户端使用bks证书校验服务端证书 |
|
|
|
* certificates -> 用含有服务端公钥的证书校验服务端证书 |
|
|
|
* certificates -> 用含有服务端公钥的证书校验服务端证书 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun getSslSocketFactory(bksFile: InputStream, password: String, vararg certificates: InputStream): SSLParams { |
|
|
|
fun getSslSocketFactory(bksFile: InputStream, password: String, vararg certificates: InputStream): SSLParams? { |
|
|
|
return getSslSocketFactoryBase(null, bksFile, password, *certificates) |
|
|
|
return getSslSocketFactoryBase(null, bksFile, password, *certificates) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -75,7 +75,7 @@ object SSLHelper { |
|
|
|
* bksFile 和 password -> 客户端使用bks证书校验服务端证书 |
|
|
|
* bksFile 和 password -> 客户端使用bks证书校验服务端证书 |
|
|
|
* X509TrustManager -> 如果需要自己校验,那么可以自己实现相关校验,如果不需要自己校验,那么传null即可 |
|
|
|
* X509TrustManager -> 如果需要自己校验,那么可以自己实现相关校验,如果不需要自己校验,那么传null即可 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun getSslSocketFactory(bksFile: InputStream, password: String, trustManager: X509TrustManager): SSLParams { |
|
|
|
fun getSslSocketFactory(bksFile: InputStream, password: String, trustManager: X509TrustManager): SSLParams? { |
|
|
|
return getSslSocketFactoryBase(trustManager, bksFile, password) |
|
|
|
return getSslSocketFactoryBase(trustManager, bksFile, password) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -84,35 +84,27 @@ object SSLHelper { |
|
|
|
bksFile: InputStream?, |
|
|
|
bksFile: InputStream?, |
|
|
|
password: String?, |
|
|
|
password: String?, |
|
|
|
vararg certificates: InputStream |
|
|
|
vararg certificates: InputStream |
|
|
|
): SSLParams { |
|
|
|
): SSLParams? { |
|
|
|
val sslParams = SSLParams() |
|
|
|
val sslParams = SSLParams() |
|
|
|
try { |
|
|
|
try { |
|
|
|
val keyManagers = prepareKeyManager(bksFile, password) |
|
|
|
val keyManagers = prepareKeyManager(bksFile, password) |
|
|
|
val trustManagers = prepareTrustManager(*certificates) |
|
|
|
val trustManagers = prepareTrustManager(*certificates) |
|
|
|
val manager: X509TrustManager? |
|
|
|
val manager: X509TrustManager = trustManager ?: chooseTrustManager(trustManagers) |
|
|
|
manager = //优先使用用户自定义的TrustManager |
|
|
|
|
|
|
|
trustManager ?: if (trustManagers != null) { |
|
|
|
|
|
|
|
//然后使用默认的TrustManager |
|
|
|
|
|
|
|
chooseTrustManager(trustManagers) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
//否则使用不安全的TrustManager |
|
|
|
|
|
|
|
unsafeTrustManager |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// 创建TLS类型的SSLContext对象, that uses our TrustManager |
|
|
|
// 创建TLS类型的SSLContext对象, that uses our TrustManager |
|
|
|
val sslContext = SSLContext.getInstance("TLS") |
|
|
|
val sslContext = SSLContext.getInstance("TLS") |
|
|
|
// 用上面得到的trustManagers初始化SSLContext,这样sslContext就会信任keyStore中的证书 |
|
|
|
// 用上面得到的trustManagers初始化SSLContext,这样sslContext就会信任keyStore中的证书 |
|
|
|
// 第一个参数是授权的密钥管理器,用来授权验证,比如授权自签名的证书验证。第二个是被授权的证书管理器,用来验证服务器端的证书 |
|
|
|
// 第一个参数是授权的密钥管理器,用来授权验证,比如授权自签名的证书验证。第二个是被授权的证书管理器,用来验证服务器端的证书 |
|
|
|
sslContext.init(keyManagers, manager?.let { arrayOf<TrustManager>(it) }, null) |
|
|
|
sslContext.init(keyManagers, arrayOf<TrustManager>(manager), null) |
|
|
|
// 通过sslContext获取SSLSocketFactory对象 |
|
|
|
// 通过sslContext获取SSLSocketFactory对象 |
|
|
|
sslParams.sSLSocketFactory = sslContext.socketFactory |
|
|
|
sslParams.sSLSocketFactory = sslContext.socketFactory |
|
|
|
sslParams.trustManager = manager |
|
|
|
sslParams.trustManager = manager |
|
|
|
return sslParams |
|
|
|
return sslParams |
|
|
|
} catch (e: NoSuchAlgorithmException) { |
|
|
|
} catch (e: NoSuchAlgorithmException) { |
|
|
|
throw AssertionError(e) |
|
|
|
e.printStackTrace() |
|
|
|
} catch (e: KeyManagementException) { |
|
|
|
} catch (e: KeyManagementException) { |
|
|
|
throw AssertionError(e) |
|
|
|
e.printStackTrace() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return null |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private fun prepareKeyManager(bksFile: InputStream?, password: String?): Array<KeyManager>? { |
|
|
|
private fun prepareKeyManager(bksFile: InputStream?, password: String?): Array<KeyManager>? { |
|
|
@ -126,50 +118,40 @@ object SSLHelper { |
|
|
|
} catch (e: Exception) { |
|
|
|
} catch (e: Exception) { |
|
|
|
e.printStackTrace() |
|
|
|
e.printStackTrace() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return null |
|
|
|
return null |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private fun prepareTrustManager(vararg certificates: InputStream): Array<TrustManager>? { |
|
|
|
private fun prepareTrustManager(vararg certificates: InputStream): Array<TrustManager> { |
|
|
|
if (certificates.isEmpty()) return null |
|
|
|
val certificateFactory = CertificateFactory.getInstance("X.509") |
|
|
|
try { |
|
|
|
// 创建一个默认类型的KeyStore,存储我们信任的证书 |
|
|
|
val certificateFactory = CertificateFactory.getInstance("X.509") |
|
|
|
val keyStore = KeyStore.getInstance(KeyStore.getDefaultType()) |
|
|
|
// 创建一个默认类型的KeyStore,存储我们信任的证书 |
|
|
|
keyStore.load(null) |
|
|
|
val keyStore = KeyStore.getInstance(KeyStore.getDefaultType()) |
|
|
|
for ((index, certStream) in certificates.withIndex()) { |
|
|
|
keyStore.load(null) |
|
|
|
val certificateAlias = Integer.toString(index) |
|
|
|
var index = 0 |
|
|
|
// 证书工厂根据证书文件的流生成证书 cert |
|
|
|
for (certStream in certificates) { |
|
|
|
val cert = certificateFactory.generateCertificate(certStream) |
|
|
|
val certificateAlias = Integer.toString(index++) |
|
|
|
// 将 cert 作为可信证书放入到keyStore中 |
|
|
|
// 证书工厂根据证书文件的流生成证书 cert |
|
|
|
keyStore.setCertificateEntry(certificateAlias, cert) |
|
|
|
val cert = certificateFactory.generateCertificate(certStream) |
|
|
|
try { |
|
|
|
// 将 cert 作为可信证书放入到keyStore中 |
|
|
|
certStream.close() |
|
|
|
keyStore.setCertificateEntry(certificateAlias, cert) |
|
|
|
} catch (e: IOException) { |
|
|
|
try { |
|
|
|
e.printStackTrace() |
|
|
|
certStream?.close() |
|
|
|
|
|
|
|
} catch (e: IOException) { |
|
|
|
|
|
|
|
e.printStackTrace() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
//我们创建一个默认类型的TrustManagerFactory |
|
|
|
|
|
|
|
val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()) |
|
|
|
|
|
|
|
//用我们之前的keyStore实例初始化TrustManagerFactory,这样tmf就会信任keyStore中的证书 |
|
|
|
|
|
|
|
tmf.init(keyStore) |
|
|
|
|
|
|
|
//通过tmf获取TrustManager数组,TrustManager也会信任keyStore中的证书 |
|
|
|
|
|
|
|
return tmf.trustManagers |
|
|
|
|
|
|
|
} catch (e: Exception) { |
|
|
|
|
|
|
|
e.printStackTrace() |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//我们创建一个默认类型的TrustManagerFactory |
|
|
|
return null |
|
|
|
val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()) |
|
|
|
|
|
|
|
//用我们之前的keyStore实例初始化TrustManagerFactory,这样tmf就会信任keyStore中的证书 |
|
|
|
|
|
|
|
tmf.init(keyStore) |
|
|
|
|
|
|
|
//通过tmf获取TrustManager数组,TrustManager也会信任keyStore中的证书 |
|
|
|
|
|
|
|
return tmf.trustManagers |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private fun chooseTrustManager(trustManagers: Array<TrustManager>): X509TrustManager? { |
|
|
|
private fun chooseTrustManager(trustManagers: Array<TrustManager>): X509TrustManager { |
|
|
|
for (trustManager in trustManagers) { |
|
|
|
for (trustManager in trustManagers) { |
|
|
|
if (trustManager is X509TrustManager) { |
|
|
|
if (trustManager is X509TrustManager) { |
|
|
|
return trustManager |
|
|
|
return trustManager |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return null |
|
|
|
throw NullPointerException() |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|