Android SSL Bağlantısı için Güven Çapası bulunamadı


185

Godaddy 256bit SSL sertifikası çalıştıran bir IIS6 kutusuna bağlanmaya çalışıyorum ve hatayı alıyorum:

java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

Buna neyin sebep olabileceğini belirlemeye çalışıyordum, ama şu anda boşluklar çiziyorum.

Nasıl bağlandığım:

HttpsURLConnection conn;              
conn = (HttpsURLConnection) (new URL(mURL)).openConnection();
conn.setConnectTimeout(20000);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.connect();
String tempString = toString(conn.getInputStream()); 

Yanıtlar:


78

@Chrispix'in çözümü tehlikelidir! Tüm sertifikalara güvenmek, herkesin orta saldırıda bir adam yapmasına izin verir! Sadece istemciye HERHANGİ bir sertifika gönderin ve kabul edecek!

Sertifikalarınızı bu yayında açıklandığı gibi özel bir güven yöneticisine ekleyin: HTTPS üzerinden HttpClient kullanarak tüm sertifikalara güvenme

Özel bir sertifika ile güvenli bir bağlantı kurmak biraz daha karmaşık olsa da, orta saldırıda insan tehlikesi olmadan size istenen SSL şifreleme güvenliğini getirecektir!


1
Bu, kendi oluşturduğu bir sertifika ile çalışmak için uygundur, ancak kök CA'lara geçerli bir zinciri olan biri için (OP'ler gibi), kötü yapılandırılmış bir sunucu için sadece bir çözümdür - cevabımı görün.
Stevie

4
@Stevie HER sertifikayı kabul etmek, yalnızca SSL bağlantısının test etmek istediğiniz bölüm olmadığı bir konsept kanıtı testi için bir seçenektir. Aksi takdirde, bağlantı güvenli olmadığı için her sertifikayı kabul ediyorsanız SSL kullanmanız gerekmez!
Matthias B

1
Ah, üzgünüm, sanırım bir yanlış anlama var - hiç kimsenin her sertifikayı kabul etmemesi gerektiğine tamamen katılıyorum! :) Yorumum, IMHO'nun önerilen bir çözüm yerine son çare çözümü olması gereken 2. paragrafınız (özel bir güven yöneticisi kullanma önerisi) ile ilgiliydi.
Stevie

2
Çığlık at! .. Daha fazla soruna yol açmamak için geçici çözüm olarak yapıştırdığım 'çözümü' kaldırdım, çünkü insanlar bunu 'geçici bir çalışma' olarak görmediler.
Chrispix

7
@Chrispix, kısmi düzeltmeyi kaldırmamalıydınız, sadece test amaçlı iyi
Hugo Allexis Cardona

224

Kabul cevap aksine sen değil özel bir güven yöneticiye ihtiyacım, sunucu yapılandırmasını düzeltmek gerekir!

Yanlış yüklenmiş bir dynadot / alphassl sertifikası ile bir Apache sunucusuna bağlanırken aynı sorunu vurdum. Atmak HttpsUrlConnection (Java / Android) kullanarak bağlanma -

javax.net.ssl.SSLHandshakeException: 
  java.security.cert.CertPathValidatorException: 
    Trust anchor for certification path not found.

Asıl sorun sunucu yanlış yapılandırmasıdır - http://www.digicert.com/help/ ile test edin veya benzeri ve hatta size çözümü söyleyecektir:

"Sertifika güvenilir bir yetkili tarafından imzalanmadı (Mozilla'nın kök deposuna karşı denetleme). Sertifikayı güvenilir bir yetkiliden satın aldıysanız, büyük olasılıkla yalnızca bir veya daha fazla Ara sertifika yüklemeniz gerekir . Bunu yapmak için sertifika sağlayıcınıza başvurun. sunucu platformu. "

Sertifikayı openssl ile de kontrol edebilirsiniz:

openssl s_client -debug -connect www.thedomaintocheck.com:443

Muhtemelen göreceksiniz:

Verify return code: 21 (unable to verify the first certificate)

ve çıktıda daha önce:

depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=27:certificate not trusted
verify return:1
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=21:unable to verify the first certificate`

Sertifika zinciri yalnızca 1 öğe içerecektir (sertifikanız):

Certificate chain
 0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com
  i:/O=AlphaSSL/CN=AlphaSSL CA - G2

... ancak bir zincirdeki imza yetkililerini Android'in güvendiği bir zincire (Verisign, GlobalSign, vb.) geri göndermelidir:

Certificate chain
 0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com
   i:/O=AlphaSSL/CN=AlphaSSL CA - G2
 1 s:/O=AlphaSSL/CN=AlphaSSL CA - G2
   i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
 2 s:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
   i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA

Sunucunuzu yapılandırmaya ilişkin talimatlar (ve ara sertifikalar) genellikle sertifikanızı veren yetkili tarafından sağlanır, örneğin: http://www.alphassl.com/support/install-root-certificate.html

Sertifika düzenleyicim tarafından sağlanan ara sertifikaları yükledikten sonra artık HttpsUrlConnection kullanarak bağlanırken hiçbir hatam yok.


3
OP'nin bağlandığı sunucuların SSL yapılandırmasına erişimi varsa, bu bir çözüm olabilir. Ancak, bağlandığı hizmeti barındıran kişi değilse, sorunu kendi tarafında düzeltmek zorundadır, yani özel bir güven yöneticisi uygulamaktır.
Matthias B

9
Çözümünüz çalışıyor, soru yok, ancak bunun temel neden için bir çözüm yerine bir çözüm olduğunu kabul etmiyor musunuz? 3 istemciden (Android, iOS, Windows Mobile) bir sunucuya bağlanmak zorunda kalırsam, o zaman tüm 3'te geçici çözümü uygulamak zorundayım, oysa sunucuyu bir kez düzeltebilirim ve hepsi "sadece çalışır".
Stevie

2
Teşekkürler Stevie, sunucumu 3 ay boyunca yanlış yapılandırdım ve sadece şimdi bunu tespit ettim! Şimdi benim android uygulaması% 100 çalışıyor
jpros

2
@Stevie Aynı etki alanını paylaşan farklı API'lara birçok çağrı yapıyorum, ancak bunlardan yalnızca biri başarısız oluyor (javax.net.ssl.SSLHandshakeException) ... böyle bir şeyin neden olacağı hakkında herhangi bir fikir? ve bu arada, SSL Sertifikasına güvenilmiyor. Bu yüzden, tüm çağrıların aynı istisna dışında başarısız olması gerektiğini düşündüm.
adil bir oyuncu

1
@dvaey sunucunun sahibi kimseyle temasa geçin ve yapılandırmasının bozulduğunu ve https'lerinin düzgün çalışmadığını söyleyin - onlara bunu kanıtlamak için bu bağlantıyı verin digicert.com/help ... Ben takdir ve hızlı olacağını hayal ediyorum çözmek. Aksi takdirde, diğer yanıtlardaki geçici çözüm adımlarından birini uygulamanız gerekir, ancak sertifikanızın süresi dolduğunda ve özel güven deponuz artık yeni ile eşleşmediğinde ya güvenlik kabul etmemeniz (sertifikaları yoksay) veya uygulamalarınızı yeniden konuşlandırmanız gerekir. Sertifika.
Stevie

17

Çalışma zamanında belirli bir sertifikaya güvenebilirsiniz.
Sadece sunucudan indirin, varlıkları koyun ve ssl-utils-android kullanarak böyle yükleyin :

OkHttpClient client = new OkHttpClient();
SSLContext sslContext = SslUtils.getSslContextForCertificateFile(context, "BPClass2RootCA-sha2.cer");
client.setSslSocketFactory(sslContext.getSocketFactory());

Yukarıdaki örnekte kullandım, OkHttpClientancak SSLContextJava'daki herhangi bir istemciyle kullanılabilir.

Herhangi bir sorunuz varsa sormaktan çekinmeyin. Bu küçük kütüphanenin yazarıyım.


.pfx ne olacak?
Choletski

2
Herhangi bir kullanıcı apk aldıktan sonra bir uygulamanın varlıklar klasörüne erişebildiğinden bu güvenli değil mi?
Patrice Andala

1
@PatriceAndala, Kök CA'lar herkese açıktır, bu yüzden sorun değil
BekaBot

17

En son Android dokümanlarına göre güncelleme (Mart 2017):

Bu tür bir hatayı aldığınızda:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
        at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:374)
        at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:209)
        at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:478)
        at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:433)
        at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
        at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
        at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282)
        at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
        at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)

sorun aşağıdakilerden biri olabilir:

  1. Sunucu sertifikasını veren CA bilinmiyordu
  2. Sunucu sertifikası bir CA tarafından imzalanmadı, ancak otomatik olarak imzalandı
  3. Sunucu yapılandırmasında ara CA eksik

Çözüm, HttpsURLConnectionbelirli bir CA kümesine güvenmeyi öğretmektir . Nasıl? Lütfen https://developer.android.com/training/articles/security-ssl.html#CommonProblems adresini kontrol edin

Kullandığınız Diğerleri AsyncHTTPClientgelen com.loopj.android:android-async-httpkütüphane, kontrol ediniz HTTPS kullanmak için Kurulum AsyncHttpClient .


5
Bir okhttp istemcisi kullanılıyorsa ne olur?
TheLearner

Okhttp için, pls @ mklimek'in cevabını kontrol edin.
user1506104

14

Retrofit kullanıyorsanız, OkHttpClient'inizi özelleştirmeniz gerekir.

retrofit = new Retrofit.Builder()
                        .baseUrl(ApplicationData.FINAL_URL)
                        .client(getUnsafeOkHttpClient().build())
                        .addConverterFactory(GsonConverterFactory.create())
                        .build();

Tam kod aşağıdaki gibidir.

    public class RestAdapter {

    private static Retrofit retrofit = null;
    private static ApiInterface apiInterface;

    public static OkHttpClient.Builder getUnsafeOkHttpClient() {
        try {
            // Create a trust manager that does not validate certificate chains
            final 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 java.security.cert.X509Certificate[]{};
                        }
                    }
            };

            // Install the all-trusting trust manager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

            // Create an ssl socket factory with our all-trusting manager
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
            return builder;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static ApiInterface getApiClient() {
        if (apiInterface == null) {

            try {
                retrofit = new Retrofit.Builder()
                        .baseUrl(ApplicationData.FINAL_URL)
                        .client(getUnsafeOkHttpClient().build())
                        .addConverterFactory(GsonConverterFactory.create())
                        .build();

            } catch (Exception e) {

                e.printStackTrace();
            }


            apiInterface = retrofit.create(ApiInterface.class);
        }
        return apiInterface;
    }

}

1
Kod kullanmaya çalışıyorum ama aşağıdaki hatayı tekrar alıyorum .. "javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Sertifika yolu için güven bağlantısı bulunamadı." u - bu yardımcı olabilir
Vishwa Pratap

Bu radikal bir güvensizlik. Kullanmayın.
Lorne Markiz

Teşekkürler! Yöntemi Kotlin'de yeniden yazdı getUnsafeOkHttpClient(): stackoverflow.com/a/60507560/2914140 .
CoolMind

11

Çok eski gönderiyi yanıtlıyor. Ama belki bazı acemi yardımcı olacaktır ve yukarıdakilerden biri işe yaramazsa.

Açıklama: Kimse açıklama saçmalamak istemez; daha ziyade çözüm. Ancak bir astarda, yerel makinenizden makinenize güvenmeyen bir uzak makineye bir servise erişmeye çalışıyorsunuz. Uzak sunucudan güven kazanmanız isteniyor.

Çözüm: Aşağıdaki çözüm, aşağıdaki koşulların karşılandığını varsayar

  1. Yerel makinenizden uzak bir API'ye erişmeye çalışıyorum.
  2. Android uygulaması için geliştiriyorsunuz
  3. Uzak sunucunuz proxy filtrelemesi altında (tarayıcı ayarınızda, genellikle bir hazırlama veya geliştirme sunucusu olan uzak API hizmetine erişmek için proxy kullanıyorsunuz)
  4. Gerçek cihazda test yapıyorsunuz

Adımlar:

Uygulamanızı kaydetmek için bir .keystore uzantı dosyasına ihtiyacınız var. .Keystore dosyasının nasıl oluşturulacağını bilmiyorsanız; sonra aşağıdaki ile birlikte takip .keystore dosyası oluşturun bölümünde veya başka bir sonraki bölüm atlamak İşaret APK dosyasını

.Keystore dosyası oluştur

Android Studio'yu açın. Üst menü Oluştur> İmzalı APK Oluştur'u tıklayın. Bir sonraki pencerede Yeni oluştur ... düğmesini tıklayın. Yeni pencerede, lütfen tüm alanlara veri girin. Tavsiye ettiğim iki Parola alanının aynı parolaya sahip olması gerektiğini unutmayın; farklı şifre kullanmayın; ve ayrıca en üst alandaki kaydetme yolunu hatırlayın Anahtar saklama yolu: . Tüm alanı girdikten sonra Tamam düğmesine tıklayın.

Apk Dosyasını İmzala

Şimdi yeni oluşturduğunuz .keystore dosyasıyla imzalı bir uygulama oluşturmanız gerekir. Bu adımları takip et

  1. Oluştur> Projeyi Temizle, temizliği bitirene kadar bekleyin
  2. Yapı> imzalı oluşturmak APK
  3. Tıklayın Choose existing... düğmesi
  4. Create .keystore dosyasında az önce oluşturduğumuz .keystore dosyasını seçin bölümünde
  5. .Keystore dosyası oluştur bölümünde oluştururken oluşturduğunuz şifreyi girin . Key store passwordVe için aynı şifreyi kullanKey password alanları . Ayrıca takma adı da girin
  6. İleri düğmesine tıklayın
  7. Bir sonraki ekranda; bu, build.gradledosyalardaki ayarlarınıza bağlı olarak farklı olabilir , seçmeniz Build TypesveFlavors .
  8. İçin Build Typesseçim releaseaçılır menüden
  9. İçin Flavorsancak o olacak daki ayarlarına bağlıdır build.gradledosyası. stagingBu alandan seçim yapın . Aşağıdaki ayarları build.gradlekullandım, benimkiyle aynı kullanabilirsiniz, ancak applicationIdpaket adınızı değiştirdiğinizden emin olun .

    productFlavors {
        staging {
            applicationId "com.yourapplication.package"
            manifestPlaceholders = [icon: "@drawable/ic_launcher"]
            buildConfigField "boolean", "CATALYST_DEBUG", "true"
            buildConfigField "boolean", "ALLOW_INVALID_CERTIFICATE", "true"
        }
        production {
            buildConfigField "boolean", "CATALYST_DEBUG", "false"
            buildConfigField "boolean", "ALLOW_INVALID_CERTIFICATE", "false"
        }
    }
  10. Alttaki iki Signature Versionsonay kutusunu ve düğmesini Finishtıklayın.

Neredeyse:

Tüm çalışkanlar yapıldı, şimdi gerçeğin hareketi. Proxy ile yedeklenen Staging sunucusuna erişmek için, gerçek test Android cihazlarınızda bazı ayarlamalar yapmanız gerekir.

Android Cihazda Proxy Ayarı:

  1. Android telefonun içindeki Ayar'ı ve ardından kablosuz bağlantıyı tıklayın
  2. Bağlı wifi'ye uzun basın ve seçin Modify network
  3. Alanı Advanced optionsgöremiyorsanız tıklayınProxy Hostname
  4. Gelen Proxy Hostnamekonak IP girin veya isim Bağlanmak istediğiniz. Tipik bir hazırlama sunucusu şu şekilde adlandırılır:stg.api.mygoodcompany.com
  5. Bağlantı noktası için örneğin dört haneli bağlantı noktası numarasını girin 9502
  6. SaveDüğmeye bas

Son Bir Durak:

İmzalı APK dosyasını Sign APK File bölümünde oluşturduğumuzu unutmayın. Şimdi bu APK dosyasını yükleme zamanı.

  1. Bir terminal açın ve imzalı apk dosya klasörüne dönüştürün
  2. Android cihazınızı makinenize bağlayın
  3. Daha önce yüklenmiş herhangi bir apk dosyasını Android cihazdan kaldırın
  4. Çalıştırmak adb install name of the apk file
  5. Herhangi bir nedenle yukarıdaki komut ile geri dönerse adb command not found. Tam yolu şu şekilde girin:C:\Users\shah\AppData\Local\Android\sdk\platform-tools\adb.exe install name of the apk file

Umarım sorun çözülmüş olabilir. Değilse lütfen bana bir yorum bırakın.

Salam!


4

Aldığım hata mesajı benzerdi ama nedeni kendinden imzalı sertifikanın süresinin dolmuş olmasıydı. Openssl istemcisi denendiğinde, sertifika iletişim kutusunu firefox'tan kontrol ederken gözden kaçırılan nedeni bana verdi.

Bu nedenle, genel olarak sertifika anahtar deposunda ve "VALID" konumundaysa, bu hata giderilir.


1
Sertifikanın süresi dolmuşsa, bir dizi standarda göre geçerli değildir. Bir özel TrustManagerkullanmak ve farklı bir ölçüt kümesi kullanmak uygun. Ama kutudan çıkar çıkmaz, bununla çalışmak zorundasın.
jww

4

Android istemcisinden Kurento sunucusuna bağlanırken aynı sorunu yaşadım. Kurento sunucusu jks sertifikaları kullanmak, bu yüzden ona pem dönüştürmek zorunda kaldı. Dönüşüm için girdi olarak cert.pem dosyasını kullandım ve bu tür hatalara yol açtı. Ama kullanımı ise fullchain.pem yerine cert.pem - tüm sorun yok.


3

Bir alanı test etmek için https://www.ssllabs.com/ssltest/ adresini kullanın .

Kotlin'de Şihab Uddin'in çözümü .

import java.security.SecureRandom
import java.security.cert.X509Certificate
import javax.net.ssl.*
import javax.security.cert.CertificateException

companion object {

    private val gson: Gson
    private val retrofit: Retrofit

    init {

        val okHttpClient = getUnsafeOkHttpClient() // OkHttpClient().newBuilder()
            .build()

        gson = GsonBuilder().setLenient().create()

        retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(okHttpClient)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build()
    }

    private fun getUnsafeOkHttpClient(): OkHttpClient.Builder =
        try {
            // Create a trust manager that does not validate certificate chains
            val trustAllCerts: Array<TrustManager> = arrayOf(
                object : X509TrustManager {
                    @Throws(CertificateException::class)
                    override fun checkClientTrusted(chain: Array<X509Certificate?>?,
                                                    authType: String?) = Unit

                    @Throws(CertificateException::class)
                    override fun checkServerTrusted(chain: Array<X509Certificate?>?,
                                                    authType: String?) = Unit

                    override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
                }
            )
            // Install the all-trusting trust manager
            val sslContext: SSLContext = SSLContext.getInstance("SSL")
            sslContext.init(null, trustAllCerts, SecureRandom())
            // Create an ssl socket factory with our all-trusting manager
            val sslSocketFactory: SSLSocketFactory = sslContext.socketFactory
            val builder = OkHttpClient.Builder()
            builder.sslSocketFactory(sslSocketFactory,
                trustAllCerts[0] as X509TrustManager)
            builder.hostnameVerifier { _, _ -> true }
            builder
        } catch (e: Exception) {
            throw RuntimeException(e)
        }
}

2

Ben buldum aynı sorun vardı ara sertifika eksik sağlanan sertifika .crt dosya oldu. Bu yüzden sunucu yöneticimdeki tüm .crt dosyalarını sordum, sonra ters sırada birleştirdik.

Ör. 1. Root.crt 2. Inter.crt 3. myCrt.crt

Windows'da i kopyaladım Inter.crt + Root.crt newCertificate.crt

(Burada myCrt.crt yoksayıldı)

Sonra inputstream üzerinden koda newCertificate.crt dosyasını sağladı. İş bitti.


Aynı sorunu yaşadık. Ara sertifika eksik
Nidhin Chandran

1

Güven bağlantısı hatası birçok nedenden dolayı olabilir. Benim için https://example.com/bunun yerine erişmeye çalışıyordum https://www.example.com/.

Dolayısıyla, kendi Güven Yöneticinizi oluşturmaya başlamadan önce URL'lerinizi tekrar kontrol etmek isteyebilirsiniz (benim yaptığım gibi).


0

Gingerbread telefonlarında her zaman bu hatayı alıyorum: Trust Anchor not found for Android SSL Connectionsertifikama güvenecek şekilde ayarlasam bile.

İşte kullandığım kod (Scala dilinde):

object Security {
    private def createCtxSsl(ctx: Context) = {
        val cer = {
            val is = ctx.getAssets.open("mycertificate.crt")
            try
                CertificateFactory.getInstance("X.509").generateCertificate(is)
            finally
                is.close()
        }
        val key = KeyStore.getInstance(KeyStore.getDefaultType)
        key.load(null, null)
        key.setCertificateEntry("ca", cer)

        val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm)
    tmf.init(key)

        val c = SSLContext.getInstance("TLS")
        c.init(null, tmf.getTrustManagers, null)
        c
    }

    def prepare(url: HttpURLConnection)(implicit ctx: Context) {
        url match {
            case https: HttpsURLConnection 
                val cSsl = ctxSsl match {
                    case None 
                        val res = createCtxSsl(ctx)
                        ctxSsl = Some(res)
                        res
                    case Some(c)  c
                }
                https.setSSLSocketFactory(cSsl.getSocketFactory)
            case _ 
        }
    }

    def noSecurity(url: HttpURLConnection) {
        url match {
            case https: HttpsURLConnection 
                https.setHostnameVerifier(new HostnameVerifier {
                    override def verify(hostname: String, session: SSLSession) = true
                })
            case _ 
        }
    }
}

ve işte bağlantı kodu:

def connect(securize: HttpURLConnection  Unit) {
    val conn = url.openConnection().asInstanceOf[HttpURLConnection]
    securize(conn)
    conn.connect();
    ....
}

try {
    connect(Security.prepare)
} catch {
    case ex: SSLHandshakeException /*if ex.getMessage != null && ex.getMessage.contains("Trust anchor for certification path not found")*/ 
        connect(Security.noSecurity)
}

Temel olarak, özel sertifikama güvenmeyi ayarlıyorum. Bu başarısız olursa, güvenliği devre dışı bırakırım. Bu en iyi seçenek değil, ama eski ve buggy telefonları ile bildiğim tek seçim.

Bu örnek kod, kolayca Java'ya çevrilebilir.


Birisi ihtiyaç duyarsa android 2.3.x için çözüm, stackoverflow.com/a/46465722/7125370
Newbie009

0

Benim durumumda bu, Android 8.0 güncellemesinden sonra gerçekleşiyordu. Kendinden imzalı Android sertifikası güvene ayarlandı, imza algoritması SHA1withRSA kullanıyordu. Yeni bir sertifikaya geçerek, SHA256 imza algoritması kullanarak RSA sorunu düzeltti.


0

Tüm sertifikalara güvenmeniz gerekmediğini biliyorum, ancak benim durumumda, kendinden imzalı sertifikalarımız olan bazı hata ayıklama ortamlarında sorun yaşadım ve kirli bir çözüme ihtiyacım vardı.

Yapmam gereken tek şey, sslContext

mySSLContext.init(null, trustAllCerts, null); 

bu trustAllCertsşekilde oluşturuldu:

private final TrustManager[] trustAllCerts= new TrustManager[] { new X509TrustManager() {
    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
        return new java.security.cert.X509Certificate[]{};
    }

    public void checkClientTrusted(X509Certificate[] chain,
                                   String authType) throws CertificateException {
    }

    public void checkServerTrusted(X509Certificate[] chain,
                                   String authType) throws CertificateException {
    }
} };

Umarım bu işe yarar.


Bunu bulmak istedim! Teşekkürler
Aralık'ta 18:18

Hata alıyorum Hostname '192.168.0.16' was not verified. Webapi'imi yerel olarak hata ayıklayıcı (IIS Express) aracılığıyla test ediyorum. Bunu nasıl düzeltebileceğine dair bir fikrin var mı? Teşekkürler :)
Sam

1
Bu kökten güvensiz. Kullanmayın.
Lorne Marquis

0

Benzer bir sorun yaşadım ve tüm kaynaklara güvenme stratejisini tamamen dışladım.

Kotlin'de uygulanan bir uygulamaya uygulanan çözümümü burada paylaşıyorum

Öncelikle sertifika ve geçerliliği hakkında bilgi almak için aşağıdaki web sitesini kullanmanızı tavsiye ederim

Bir şekilde görünmüyorsa 'Kabul İhraççılar' de Android varsayılan güven deposunda , biz bu sertifikayı almak ve özel bir güven deposu oluşturmak için uygulama içine içermelidir

Benim durumumda ideal çözüm , özel ve Android varsayılan güven deposunu birleştiren üst düzey bir Güven Yöneticisi oluşturmaktı

Burada, Retrofit ile kullandığı OkHttpClient'i yapılandırmak için kullanılan üst düzey kodu ortaya koyar.

override fun onBuildHttpClient(httpClientBuild: OkHttpClient.Builder) {

        val trustManagerWrapper = createX509TrustManagerWrapper(
            arrayOf(
                getCustomX509TrustManager(),
                getDefaultX509TrustManager()
            )
        )

        printX509TrustManagerAcceptedIssuers(trustManagerWrapper)

        val sslSocketFactory = createSocketFactory(trustManagerWrapper)
        httpClientBuild.sslSocketFactory(sslSocketFactory, trustManagerWrapper)

    }

Bu şekilde, kendinden imzalı bir sertifika ile sunucuyla ve güvenilir bir sertifika kuruluşu tarafından verilen bir sertifika ile diğer sunucularla iletişim kurabilirim

İşte bu, umarım birine yardımcı olabilir.


0

Bunun çok eski bir makale olduğunu biliyorum, ancak güven çapa sorunlarımı çözmeye çalışırken bu makaleye rastladım. Nasıl düzelttiğimi ilan ettim. Kök CA'nızı önceden yüklediyseniz manifest'e bir yapılandırma eklemeniz gerekir.

https://stackoverflow.com/a/60102517/114265


yalnızca API 24+ için
BekaBot

@BekaBot - bu muhtemelen doğrudur, ancak 23 ve altındaki belgelere göre varsayılan olarak kullanıcı sertifikalarına güvenir Varsayılan olarak, tüm uygulamalardan güvenli bağlantılar (TLS ve HTTPS gibi protokolleri kullanarak) önceden yüklenmiş sistem CA'larına ve Android 6.0'ı hedefleyen uygulamalara güvenir (API düzey 23) ve daha düşük sürümleri de varsayılan olarak kullanıcı tarafından eklenen CA deposuna güvenir
GR Envoy

-1
**Set proper alias name**
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509","BC");
            X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(derInputStream);
            String alias = cert.getSubjectX500Principal().getName();
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null);
trustStore.setCertificateEntry(alias, cert);

-2

Aynı problemle de karşılaştım. Ben sadece http için hhtps kaldırmak, gibi

final public static String ROOT_URL = "https://example.com"; için final public static String ROOT_URL = "http://example.com";

Sonunda, bu sorunu çözdüm.


Elbette bu sadece SSL güvenliğini denklemden kaldırmaktır, bu muhtemelen bir üretim ortamı için kötü bir fikirdir.
Dragonthoughts

Bu, SSL güvenliğini kaldıran bir çözüm değildir.
omega1
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.