Безопасное подключение к Artik 055 с модулем Samsung с помощью Android - PullRequest
0 голосов
/ 14 мая 2019

Я работаю над приложением Android, которое должно взаимодействовать с модулем Artik 055s и процессором Samsung.

Artik создает собственную точку доступа, и к WiFi можно подключить только одно устройство.время.С этого момента мы должны использовать простые HTTPS-запросы и ответы, используя Retrofit.

Пытаясь вызвать его, я получаю

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: доверенная привязка для пути сертификации не найдена.

При чтении документации по Android это может быть вызвано несколькими причинами.Насколько я понял от разработчиков Artik, в процессоре есть встроенный сертификат от Samsung.Поэтому мне было интересно, был ли самозаверяющий сертификат, возможно.Затем разработчики Artik взяли сертификат, отправленный с помощью WireShark, и отправили мне, чтобы я мог включить его в приложение, а затем использовать его для проверки рукопожатия.

Затем я попытался реализовать этот код с помощью https://developer.android.com/training/articles/security-ssl#SelfSigned

val instrumentDataSource: IInstrumentDataSource
        by lazy {
            val retrofit = Retrofit.Builder()
                    .addConverterFactory(GsonConverterFactory.create())
                    .baseUrl(BuildConfig.BASE_URL)
                    .client(getUnsafeOkHttpClient())
                    .build()

            retrofit.create(IInstrumentDataSource::class.java)
        }

private fun getUnsafeOkHttpClient(): OkHttpClient {
    try {
        // Install the all-trusting trust manager
        val sslContext = getSSLContextFromCertificate()
        // Create an ssl socket factory with our all-trusting manager
        val sslSocketFactory = sslContext.socketFactory

        val okHttpClient = OkHttpClient()
        return okHttpClient.newBuilder()
                .sslSocketFactory(sslSocketFactory)
                .hostnameVerifier { hostname, session -> true }
                .build()

    } catch (e: Exception) {
        throw RuntimeException(e)
    }
}

private fun getSSLContextFromCertificate(): SSLContext {
    val cf: CertificateFactory = CertificateFactory.getInstance("X.509")
    // From https://www.washington.edu/itconnect/security/ca/load-der.crt
    val caInput: InputStream = HealthApplication.appContext.resources.openRawResource(R.raw.cert_name)
    val ca: X509Certificate = caInput.use {
        cf.generateCertificate(it) as X509Certificate
    }
    System.out.println("ca=" + ca.subjectDN)

    // Create a KeyStore containing our trusted CAs
    val keyStoreType = KeyStore.getDefaultType()
    val keyStore = KeyStore.getInstance(keyStoreType).apply {
        load(null, null)
        setCertificateEntry("ca", ca)
    }

    // Create a TrustManager that trusts the CAs inputStream our KeyStore
    val tmfAlgorithm: String = TrustManagerFactory.getDefaultAlgorithm()
    val tmf: TrustManagerFactory = TrustManagerFactory.getInstance(tmfAlgorithm).apply {
        init(keyStore)
    }

    // Create an SSLContext that uses our TrustManager
    return SSLContext.getInstance("TLS").apply {
        init(null, tmf.trustManagers, null)
    }
}

Но я все равно получаю ту же ошибку, что и раньше ..

Все«хорошо», если я попробую этот пример, который всплывает в Интернете (что Android даже упоминает по ссылке, которую я только что опубликовал), где вы полностью отключаете все проверки, как это:

private fun getUnsafeOkHttpClient(): OkHttpClient {

    try {
        // Create a trust manager that does not validate certificate chains
        val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
            override fun getAcceptedIssuers(): Array<X509Certificate> {
                return arrayOf()
            }

            @Throws(CertificateException::class)
            override fun checkClientTrusted(
                    chain: Array<X509Certificate>,
                    authType: String) {
            }

            @Throws(CertificateException::class)
            override fun checkServerTrusted(
                    chain: Array<X509Certificate>,
                    authType: String) {
            }
        })

        // Install the all-trusting trust manager
        val sslContext = SSLContext.getInstance("TLS")
        sslContext.init(null, trustAllCerts,
                java.security.SecureRandom())
        // Create an ssl socket factory with our all-trusting manager
        val sslSocketFactory = sslContext
                .socketFactory

        val okHttpClient = OkHttpClient()
        return okHttpClient.newBuilder()
                .sslSocketFactory(sslSocketFactory)
                .hostnameVerifier { hostname, session -> true }
                .build()

    } catch (e: Exception) {
        throw RuntimeException(e)
    }
}

Кто-нибудь получил что-нибудь хорошееидеи продолжить?Я знаю, что последняя проверка небезопасна для производства, но достаточно ли вышеупомянутого, если я его заработаю, достаточно безопасно?

...