Ktor 多平台 - 在 kotlin 中用于 iOS 的 SSL 固定

Posted

技术标签:

【中文标题】Ktor 多平台 - 在 kotlin 中用于 iOS 的 SSL 固定【英文标题】:Ktor multiplatform - SSL pinning for iOS in kotlin 【发布时间】:2020-03-05 18:04:23 【问题描述】:

我正在使用以下代码在 Kotlin Multiplatform 中使用 Ktor 进行 SSL 固定。

这行代码我崩溃了

val remoteCertificateData : NSData = SecCertificateCopyData(certificate) as NSData 

这里是函数。

override fun URLSession(
            session: NSURLSession,
            didReceiveChallenge: NSURLAuthenticationChallenge,
            completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Unit
        ) 
            val serverTrust = didReceiveChallenge.protectionSpace.serverTrust

            val certificate = SecTrustGetCertificateAtIndex(serverTrust,0)

            var result: SecTrustResultType = 0u
            memScoped
                val nativeResult = alloc<SecTrustResultTypeVar>()
                nativeResult.value = result
                SecTrustEvaluate(serverTrust!!, nativeResult.ptr)
            

            val remoteCertificateData : NSData = SecCertificateCopyData(certificate) as NSData                                
            val bundle = NSBundle.bundleForClass(objc_getRequiredClass("iosClientEngine"))                

            val pathToCert = bundle.pathForResource("MyCertificate","cer")                

            val localCertificate : NSData = NSData.dataWithContentsOfFile(pathToCert!!)!!

            if (localCertificate == remoteCertificateData) 
                completionHandler(NSURLSessionAuthChallengeUseCredential,NSURLCredential.create(serverTrust))                    
             else 
                completionHandler(NSURLSessionAuthChallengeUseCredential, null)                    
            
        

【问题讨论】:

【参考方案1】:

经过这么多研究,我设法在 Kotlin Multiplatform for iOS 中转换 iOS 代码。

override fun URLSession(
    session: NSURLSession,
    didReceiveChallenge: NSURLAuthenticationChallenge,
    completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Unit
) 
    val serverTrust = didReceiveChallenge.protectionSpace.serverTrust
    var result: SecTrustResultType = 0u

    memScoped
        val nativeResult = alloc<SecTrustResultTypeVar>()
        nativeResult.value = result
        SecTrustEvaluate(serverTrust!!, nativeResult.ptr)
    

    val serverCertificate = SecTrustGetCertificateAtIndex(serverTrust,0)
    val serverCertificateData = SecCertificateCopyData(serverCertificate)
    val data = CFDataGetBytePtr(serverCertificateData)
    val size = CFDataGetLength(serverCertificateData)

    val cert1 = NSData.dataWithBytes(data,size.toULong())
    val pathToCert = NSBundle.mainBundle.pathForResource("Your Certificate","cer")

    val localCertificate : NSData = NSData.dataWithContentsOfFile(pathToCert!!)!!

    if (localCertificate == cert1) 
        completionHandler(NSURLSessionAuthChallengeUseCredential,NSURLCredential.create(serverTrust))
     else 
        completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, null)
    

【讨论】:

我正在尝试使用 ktor configureSession 配置会话委托并覆盖 URLSession 委托以进行证书验证,此 Urlsession 委托未调用。你试过使用 Ktor 1.3 您必须将此代码放在 Kotlin 代码中的 common 共享文件夹中。

以上是关于Ktor 多平台 - 在 kotlin 中用于 iOS 的 SSL 固定的主要内容,如果未能解决你的问题,请参考以下文章

从 ktor 提供 kotlin 多平台 javascript

在 Kotlin 多平台项目中使用 Ktor HttpClient 将文件作为二进制文件

Ktor 1.0 发布:Kotlin Web 框架;GoLand 2018.3 正式版发布!| 更新

是否可以使用 Ktor 和/或 Kotlin 多平台在 Rest API 和 Android 应用程序之间“共享”公开的数​​据?

Kodein + Ktor = 冻结 kotlin.collections.HashMap 的突变尝试 - 为啥?

Kotlin Ktor 客户端 mltiplatform gradle 配置