我们在我的一个Android应用中使用websockets。使用第三方库“ https://github.com/TakahikoKawasaki/nv-websocket-client”。
现在,我们想为websocket启用ssl固定。 我们应该怎么做?
谢谢
答案 0 :(得分:0)
We can enable ssl pinning for web sockets using sslContext.
This is my working code.
----------
val sslContext = SSLContext.getInstance("TLS")
sslContext.init(null, arrayOf(CustomTrustManager(null)), SecureRandom())
mSocketFactory.sslContext = sslContext
val ws = mSocketFactory.createSocket(presentEndpoint)
class CustomTrustManager(keyStore: KeyStore?) : X509TrustManager {
private val tag = CustomTrustManager::class.java.canonicalName
init {
val factory: TrustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
factory.init(keyStore)
val trustmanagers: Array<TrustManager> = factory.trustManagers
if (trustmanagers.isEmpty()) {
throw NoSuchAlgorithmException("no trust manager found")
}
}
override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {
}
override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {
for (certificate in chain!!) {
if (isValidPin(certificate)) {
return
}
}
throw CertificateException("No valid pins found in chain!")
}
override fun getAcceptedIssuers(): Array<X509Certificate>? {
return null
}
private fun isValidPin(certificate: X509Certificate): Boolean {
return try {
val md = MessageDigest.getInstance("SHA-256")
val publicKey = certificate.publicKey.encoded
md.update(publicKey, 0, publicKey.size)
val pin = Base64.encodeToString(md.digest(), Base64.NO_WRAP)
val validPins = Collections.singleton(Constants.PK)
if (validPins.contains("sha256/$pin")) {
return true
}
false
} catch (ex: NoSuchAlgorithmException) {
throw CertificateException(ex)
}
}
}