kendinden imzalı sertifikalarla HTTPS bağlantılarını kabul etme


154

HttpClientLib kullanarak HTTPS bağlantıları yapmaya çalışıyorum , ancak sorun şu ki, sertifika Android Güvenilir Sertifikalar kümesinde listelenen Verisign , GlobalSIgn , vb.Gibi tanınmış bir Sertifika Yetkilisi (CA) tarafından imzalanmadığı için , Ben almaya devam ediyorum javax.net.ssl.SSLException: Not trusted server certificate.

Tüm sertifikaları kabul ettiğiniz çözümler gördüm, ancak kullanıcıya sormak istersem ne olur?

Tarayıcınınkine benzer bir iletişim kutusu almak istiyorum ve kullanıcının devam edip etmemeye karar vermesini istiyorum. Tercihen tarayıcı ile aynı sertifika deposunu kullanmak istiyorum. Herhangi bir fikir?


Kabul edilen bu çözüm, me- stackoverflow.com/questions/2642777/…
Venkatesh

Yanıtlar:


171

Yapmanız gereken ilk şey doğrulama seviyesini ayarlamaktır. Bu seviyeler çok fazla değil:

  • ALLOW_ALL_HOSTNAME_VERIFIER
  • BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
  • STRICT_HOSTNAME_VERIFIER

SetHostnameVerifier () yöntemi yeni kitaplık apache için kullanılmamasına rağmen, Android SDK sürümünde normaldir. Ve böylece ALLOW_ALL_HOSTNAME_VERIFIERyöntem fabrikasında alıp ayarladık SSLSocketFactory.setHostnameVerifier().

Sonra, protokolü https için fabrikamızı ayarlamanız gerekir. Bunu yapmak için,SchemeRegistry.register() yöntemi .

Sonra bir DefaultHttpClientile oluşturmanız gerekir SingleClientConnManager. Ayrıca aşağıdaki kodda varsayılan olarak bayrağımızı da kullanacağınızı görebilirsiniz (ALLOW_ALL_HOSTNAME_VERIFIER ) yöntemimizi de yöntemleHttpsURLConnection.setDefaultHostnameVerifier()

Aşağıdaki kod benim için çalışıyor:

HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

DefaultHttpClient client = new DefaultHttpClient();

SchemeRegistry registry = new SchemeRegistry();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
registry.register(new Scheme("https", socketFactory, 443));
SingleClientConnManager mgr = new SingleClientConnManager(client.getParams(), registry);
DefaultHttpClient httpClient = new DefaultHttpClient(mgr, client.getParams());

// Set verifier     
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);

// Example send http request
final String url = "https://encrypted.google.com/";
HttpPost httpPost = new HttpPost(url);
HttpResponse response = httpClient.execute(httpPost);

6
Bu kodu maalesef çalıştıramıyorum, hala "Güvenilir değil sunucu sertifikası" alıyorum. Çalışması için ayarlamam gereken ekstra izinler var mı?
Juriy

1
Bu kod sadece tüm sertifikaları kabul etmiyor mu? Kabul etmek için bir pop-up'a ihtiyacım var.
Morten

3
Kullanıyorum org.apache.http.conn.ssl.SSLSocketFactoryneden kullanmak istiyorum javax.net.ssl.HttpsURLConnection??
Birisi

9
Bu kodun sertifika doğrulamayı tamamen devre dışı bırakmaktan daha iyi olduğunu açıklayabilir misiniz? Android'in ssl API'sini bilmiyorum, ancak bir bakışta bu aktif saldırganlara karşı tamamen güvensiz görünüyor.
CodesInChaos

3
SingleClientConnManager
Çiftlik

124

Android platformunun güvenilir olduğu düşünülmeyen Sertifika Yetkililerinden güvenli bir bağlantı elde etmek için aşağıdaki ana adımlar gereklidir.

Birçok kullanıcının istediği gibi, blog makalemdeki en önemli kısımları burada yansıttım :

  1. Gerekli tüm sertifikaları (kök ve ara CA'lar) alın
  2. Keytool ve BouncyCastle sağlayıcısı ile bir anahtar deposu oluşturun ve sertifikaları içe aktarın
  3. Anahtar deposunu android uygulamanıza yükleyin ve güvenli bağlantılar için kullanın ( standart yerine Apache HttpClient kullanmanızı öneririz java.net.ssl.HttpsURLConnection(anlaşılması daha kolay, daha fazla performans)

Sertifikaları al

Uç nokta sertifikasından Kök CA'ya kadar bir zincir oluşturan tüm sertifikaları edinmeniz gerekir. Bu, varsa (varsa) Ara CA sertifikaları ve ayrıca Kök CA sertifikası anlamına gelir. Uç nokta sertifikası almanıza gerek yoktur.

Anahtar deposunu oluşturma

BouncyCastle Sağlayıcısını indirin ve bilinen bir yerde saklayın. Ayrıca keytool komutunu da çağırabildiğinizden emin olun (genellikle JRE kurulumunuzun bin klasörü altında bulunur).

Şimdi elde edilen sertifikaları (uç nokta sertifikasını içe aktarmayın) BouncyCastle biçimli bir anahtar deposuna içe aktarın.

Test etmedim, ancak sertifikaları içe aktarma sırasının önemli olduğunu düşünüyorum. Bu, önce en alt ara CA sertifikasını sonra da Kök CA sertifikasına kadar alın.

Aşağıdaki komutla, mysecret parolasıyla yeni bir anahtar deposu (önceden yoksa) oluşturulur ve Ara CA sertifikası içe aktarılır. Ayrıca dosya sistemimde ve anahtar deposu biçiminde bulunabilecek BouncyCastle sağlayıcısını tanımladım. Zincirdeki her sertifika için bu komutu yürütün.

keytool -importcert -v -trustcacerts -file "path_to_cert/interm_ca.cer" -alias IntermediateCA -keystore "res/raw/mykeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret

Sertifikaların anahtar deposuna doğru şekilde aktarılıp aktarılmadığını doğrulayın:

keytool -list -keystore "res/raw/mykeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret

Tüm zinciri çıktılamalıdır:

RootCA, 22.10.2010, trustedCertEntry, Thumbprint (MD5): 24:77:D9:A8:91:D1:3B:FA:88:2D:C2:FF:F8:CD:33:93
IntermediateCA, 22.10.2010, trustedCertEntry, Thumbprint (MD5): 98:0F:C3:F8:39:F7:D8:05:07:02:0D:E3:14:5B:29:43

Artık anahtar deposunu android uygulamanızda ham kaynak olarak kopyalayabilirsiniz. res/raw/

Uygulamanızdaki anahtar deposunu kullanın

Her şeyden önce, anahtar depomuzu HTTPS bağlantıları için kullanan özel bir Apache HttpClient oluşturmanız gerekir:

import org.apache.http.*

public class MyHttpClient extends DefaultHttpClient {

    final Context context;

    public MyHttpClient(Context context) {
        this.context = context;
    }

    @Override
    protected ClientConnectionManager createClientConnectionManager() {
        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        // Register for port 443 our SSLSocketFactory with our keystore
        // to the ConnectionManager
        registry.register(new Scheme("https", newSslSocketFactory(), 443));
        return new SingleClientConnManager(getParams(), registry);
    }

    private SSLSocketFactory newSslSocketFactory() {
        try {
            // Get an instance of the Bouncy Castle KeyStore format
            KeyStore trusted = KeyStore.getInstance("BKS");
            // Get the raw resource, which contains the keystore with
            // your trusted certificates (root and any intermediate certs)
            InputStream in = context.getResources().openRawResource(R.raw.mykeystore);
            try {
                // Initialize the keystore with the provided trusted certificates
                // Also provide the password of the keystore
                trusted.load(in, "mysecret".toCharArray());
            } finally {
                in.close();
            }
            // Pass the keystore to the SSLSocketFactory. The factory is responsible
            // for the verification of the server certificate.
            SSLSocketFactory sf = new SSLSocketFactory(trusted);
            // Hostname verification from certificate
            // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506
            sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
            return sf;
        } catch (Exception e) {
            throw new AssertionError(e);
        }
    }
}

Özel HttpClient'imizi oluşturduk, şimdi güvenli bağlantılar için kullanabiliriz. Örneğin, bir REST kaynağına GET çağrısı yaptığımızda:

// Instantiate the custom HttpClient
DefaultHttpClient client = new MyHttpClient(getApplicationContext());
HttpGet get = new HttpGet("https://www.mydomain.ch/rest/contacts/23");
// Execute the GET call and obtain the response
HttpResponse getResponse = client.execute(get);
HttpEntity responseEntity = getResponse.getEntity();

Bu kadar ;)


8
Bu yalnızca başvurunuzu göndermeden önce sertifika almak için kullanışlıdır. Kullanıcıların kendi sertifikalarını kabul etmelerine gerçekten yardımcı olmaz. Başvurunuz
Bulanık

Herkese selam bazıları bana yukarıdaki uygulama için truststore ile anahtar deposu için doğrulama işlemi söyleyebilir ??? şimdiden teşekkürler ..
andriod_testing

Bu amele para cezası .. ama şimdi sunucuda sertifikayı yeniden okurken bir sorunla karşı karşıyayım. Sunucumdaki sertifikayı her güncellediğimde, istemci tarafı deposunun da güncellenmesi garip görünüyor. Daha iyi bir yol olmalı: |
bpn

Gr8 cevap, SingleClientConnManager
Çiftlik

Buna /res/raw/mykeystore.bksreferansı çözememe rağmen ekledim . bunu nasıl çözebilirim?
uniruddh

16

Aygıtta olmayan sunucuda özel / kendinden imzalı bir sertifikanız varsa, yüklemek ve Android'de istemci tarafında kullanmak için aşağıdaki sınıfı kullanabilirsiniz:

Sertifika *.crtdosyasını yerleştirin/res/raw ,R.raw.*

Bu sertifikayı kullanan bir soket fabrikasına sahip olacak olan HTTPClientveya HttpsURLConnectionbu sertifikayı alacak olan sınıfı kullanmak için aşağıdaki sınıfı kullanın :

package com.example.customssl;

import android.content.Context;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;

public class CustomCAHttpsProvider {

    /**
     * Creates a {@link org.apache.http.client.HttpClient} which is configured to work with a custom authority
     * certificate.
     *
     * @param context       Application Context
     * @param certRawResId  R.raw.id of certificate file (*.crt). Should be stored in /res/raw.
     * @param allowAllHosts If true then client will not check server against host names of certificate.
     * @return Http Client.
     * @throws Exception If there is an error initializing the client.
     */
    public static HttpClient getHttpClient(Context context, int certRawResId, boolean allowAllHosts) throws Exception {


        // build key store with ca certificate
        KeyStore keyStore = buildKeyStore(context, certRawResId);

        // init ssl socket factory with key store
        SSLSocketFactory sslSocketFactory = new SSLSocketFactory(keyStore);

        // skip hostname security check if specified
        if (allowAllHosts) {
            sslSocketFactory.setHostnameVerifier(new AllowAllHostnameVerifier());
        }

        // basic http params for client
        HttpParams params = new BasicHttpParams();

        // normal scheme registry with our ssl socket factory for "https"
        SchemeRegistry schemeRegistry = new SchemeRegistry();
        schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        schemeRegistry.register(new Scheme("https", sslSocketFactory, 443));

        // create connection manager
        ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);

        // create http client
        return new DefaultHttpClient(cm, params);
    }

    /**
     * Creates a {@link javax.net.ssl.HttpsURLConnection} which is configured to work with a custom authority
     * certificate.
     *
     * @param urlString     remote url string.
     * @param context       Application Context
     * @param certRawResId  R.raw.id of certificate file (*.crt). Should be stored in /res/raw.
     * @param allowAllHosts If true then client will not check server against host names of certificate.
     * @return Http url connection.
     * @throws Exception If there is an error initializing the connection.
     */
    public static HttpsURLConnection getHttpsUrlConnection(String urlString, Context context, int certRawResId,
                                                           boolean allowAllHosts) throws Exception {

        // build key store with ca certificate
        KeyStore keyStore = buildKeyStore(context, certRawResId);

        // Create a TrustManager that trusts the CAs in our KeyStore
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);

        // Create an SSLContext that uses our TrustManager
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);

        // Create a connection from url
        URL url = new URL(urlString);
        HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
        urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());

        // skip hostname security check if specified
        if (allowAllHosts) {
            urlConnection.setHostnameVerifier(new AllowAllHostnameVerifier());
        }

        return urlConnection;
    }

    private static KeyStore buildKeyStore(Context context, int certRawResId) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
        // init a default key store
        String keyStoreType = KeyStore.getDefaultType();
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);

        // read and add certificate authority
        Certificate cert = readCert(context, certRawResId);
        keyStore.setCertificateEntry("ca", cert);

        return keyStore;
    }

    private static Certificate readCert(Context context, int certResourceId) throws CertificateException, IOException {

        // read certificate resource
        InputStream caInput = context.getResources().openRawResource(certResourceId);

        Certificate ca;
        try {
            // generate a certificate
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            ca = cf.generateCertificate(caInput);
        } finally {
            caInput.close();
        }

        return ca;
    }

}

Anahtar noktaları:

  1. Certificate nesneler .crt dosyalardan .
  2. Bir varsayılan KeyStoreoluşturulur.
  3. keyStore.setCertificateEntry("ca", cert)"ca" takma adı altında anahtar deposuna sertifika ekliyor. Daha fazla sertifika (ara CA vb.) Eklemek için kodu değiştirirsiniz.
  4. Temel amaç, SSLSocketFactorydaha sonra HTTPClientveya tarafından kullanılabilecek bir tane oluşturmaktır HttpsURLConnection.
  5. SSLSocketFactory daha fazla yapılandırılabilir, örneğin ana bilgisayar adı doğrulamasını atlamak vb.

Daha fazla bilgi için: http://developer.android.com/training/articles/security-ssl.html


Nereden .crtdosya alabilirim ? Sunucudan indirme?
zionpi

@zionpi Sertifika dosyası, bağlandığınız TLS etkin sunucu tarafından kullanılan dosya ile aynı olacaktır.
SD

Teşekkürler! Bu çok kolaydı!
kapil thadani

@SD .crt yerine .P12 dosyasını nasıl kullanabilirim?
Rakesh R Nair

Soğuk bir benzer şüphe var lütfen stackoverflow.com/questions/57389622/… yardım
StezPet

8

Https kullanarak Android Uygulamamı RESTful hizmetime bağlamaya çalıştığımda hayal kırıklığına uğradım. Ayrıca, sertifika kontrolünü tamamen devre dışı bırakmayı öneren tüm cevaplar hakkında biraz rahatsız oldum. Bunu yaparsanız, https'nin amacı nedir?

Bir süre konuyla ilgili bir şey yaptıktan sonra, sonunda harici kavanozlara ihtiyaç duyulmayan bu çözümü sadece Android API'larını buldum . Temmuz 2014'te yayınlayan Andrew Smith'e teşekkürler

 /**
 * Set up a connection to myservice.domain using HTTPS. An entire function
 * is needed to do this because myservice.domain has a self-signed certificate.
 * 
 * The caller of the function would do something like:
 * HttpsURLConnection urlConnection = setUpHttpsConnection("https://littlesvr.ca");
 * InputStream in = urlConnection.getInputStream();
 * And read from that "in" as usual in Java
 * 
 * Based on code from:
 * https://developer.android.com/training/articles/security-ssl.html#SelfSigned
 */
public static HttpsURLConnection setUpHttpsConnection(String urlString)
{
    try
    {
        // Load CAs from an InputStream
        // (could be from a resource or ByteArrayInputStream or ...)
        CertificateFactory cf = CertificateFactory.getInstance("X.509");

        // My CRT file that I put in the assets folder
        // I got this file by following these steps:
        // * Go to https://littlesvr.ca using Firefox
        // * Click the padlock/More/Security/View Certificate/Details/Export
        // * Saved the file as littlesvr.crt (type X.509 Certificate (PEM))
        // The MainActivity.context is declared as:
        // public static Context context;
        // And initialized in MainActivity.onCreate() as:
        // MainActivity.context = getApplicationContext();
        InputStream caInput = new BufferedInputStream(MainActivity.context.getAssets().open("littlesvr.crt"));
        Certificate ca = cf.generateCertificate(caInput);
        System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());

        // Create a KeyStore containing our trusted CAs
        String keyStoreType = KeyStore.getDefaultType();
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", ca);

        // Create a TrustManager that trusts the CAs in our KeyStore
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);

        // Create an SSLContext that uses our TrustManager
        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, tmf.getTrustManagers(), null);

        // Tell the URLConnection to use a SocketFactory from our SSLContext
        URL url = new URL(urlString);
        HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection();
        urlConnection.setSSLSocketFactory(context.getSocketFactory());

        return urlConnection;
    }
    catch (Exception ex)
    {
        Log.e(TAG, "Failed to establish SSL connection to server: " + ex.toString());
        return null;
    }
}

Benim mockup App için güzel çalıştı.


Hangisini java veya javax içe aktarmalıyım?
Siddharth

İthal ettimimport java.security.cert.X509Certificate;
Gonzalo Fernández

Bunun için teşekkürler. Gerçekten işe
yarar

6

En iyi cevap benim için işe yaramadı. Bazı araştırmalardan sonra "Android Developer" hakkında gerekli bilgileri buldum: https://developer.android.com/training/articles/security-ssl.html#SelfSigned

Boş bir X509TrustManager uygulaması oluşturmak hile yaptı:

private static class MyTrustManager implements X509TrustManager
{

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

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

    @Override
    public X509Certificate[] getAcceptedIssuers()
    {
        return null;
    }

}

...

HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
try
{
    // Create an SSLContext that uses our TrustManager
    SSLContext context = SSLContext.getInstance("TLS");
    TrustManager[] tmlist = {new MyTrustManager()};
    context.init(null, tmlist, null);
    conn.setSSLSocketFactory(context.getSocketFactory());
}
catch (NoSuchAlgorithmException e)
{
    throw new IOException(e);
} catch (KeyManagementException e)
{
    throw new IOException(e);
}
conn.setRequestMethod("GET");
int rcode = conn.getResponseCode();

Bu boş TustManager uygulamasının sadece bir örnek olduğunu ve üretken bir ortamda kullanmanın ciddi bir güvenlik tehdidine neden olacağını lütfen unutmayın!


1
sadece fyi - idk o zaman böyle olsaydı, ama şimdi bu yaklaşımı şiddetle tavsiye etmiyorlar (nota bakınız)
Saik Caskey

6

Google , HTTP / HTTPS bağlantıları için Android Volley kullanılmasını önerir , çünküHttpClient kullanımdan kaldırılmıştır. Yani, doğru seçimi biliyorsunuz :).

Ve ayrıca, ASLA NUKE SSL Sertifikaları (ASLA !!!).

SSL Sertifikalarını nuke etmek, güvenliği destekleyen SSL amacına tamamen aykırıdır . Gelen tüm SSL sertifikalarını bombalamayı planlıyorsanız SSL kullanmanın bir anlamı yoktur. Daha iyi bir çözüm, SSL kullanmamak veya daha iyi bir çözüm, özel birTrustManager HTTP + / HTTPS bağlantıları için Android Volley kullanarak App + cihazınızda .

İşte temel bir LoginApp ile, HTTPS bağlantıları gerçekleştirerek, sunucu tarafında Kendinden İmzalı Sertifika kullanarak, Uygulamada kabul ettiğim bir Gist .

Ayrıca , Sunucunuzda kurulum yapmak ve Uygulamanızdaki sertifikayı kullanmak için Kendinden İmzalı SSL Sertifikaları oluşturmak için yardımcı olabilecek başka bir Gist . Çok önemli: Yukarıdaki komut dosyası tarafından oluşturulan .crt dosyasını Android projenizdeki "raw" dizinine kopyalamanız gerekir.


Merhaba Ivan, SSL sertifikalarıyla hiç çalışmadım. Biraz ayrıntılı düşünür müsünüz? .Crt dosyasını nasıl edinebilirim?
Temmuz

Merhaba Jively! Anlıyorum. Evet tabi ki. Ama önce, yukarıda bahsettiğim ikinci Gist'e bir göz atmak ister misiniz? Bu Gist üzerine iki dosya koydum: biri komut dosyası tarafından kullanılan dosya ve diğeri, dosyayı okumak ve daha sonra SSL Sertifikası ( .crt). Her şeyi anlayabiliyorsan bana haber ver. Saygılarımızla :).
ivanleoncz

Hmm evet bu 2 özlüğe baktım, ama onları nasıl kullanacağımı gerçekten anlayamıyorum?
jlively

4

Bu sorunu önlemek için KeyStore'unuza nasıl ek sertifikalar ekleyebilirsiniz: HTTPS üzerinden HttpClient kullanarak tüm sertifikalara güvenme

İstediğiniz kullanıcıyı sormaz, ancak kullanıcının "Güvenilir olmayan sunucu sertifikası" hatasıyla karşılaşma olasılığını azaltır.


Sadece test amacıyla, Play Store'da bu hile ile bir uygulama yayınlayamazsınız çünkü reddedilecek
ariel

3

SSL sertifikası oluşturmanın en kolay yolu

Firefox'u açın (Sanırım Chrome ile de mümkün, ancak FF ile benim için daha kolay)

Kendinden imzalı bir SSL sertifikası ile geliştirme sitenizi ziyaret edin.

Sertifikayı tıklayın (site adının yanında)

"Daha fazla bilgi" yi tıklayın

"Sertifikayı görüntüle" yi tıklayın

"Ayrıntılar" ı tıklayın

"Dışa aktar ..." ı tıklayın

Zincirle (PEM) "X.509 Sertifikası" nı seçin, kaydedilecek klasörü ve adı seçin ve "Kaydet" i tıklayın

Komut satırına, pem dosyasını indirdiğiniz dizine gidin ve "openssl x509 -inform PEM -outform DM -in .pem -out .crt" komutunu çalıştırın.

.Crt dosyasını Android cihazınızdaki / sdcard klasörünün köküne kopyalayın Android cihazınızın içinde Ayarlar> Güvenlik> Depodan yükle.

Sertifikayı algılamalı ve cihaza eklemenize izin vermelidir Geliştirme sitenize göz atın.

İlk kez güvenlik istisnasını onaylamanızı istemelidir. Bu kadar.

Sertifika, Android'inizde yüklü herhangi bir tarayıcıyla çalışmalıdır (Tarayıcı, Chrome, Opera, Dolphin ...)

Statik dosyalarınızı farklı bir alan adından sunuyorsanız (hepimiz sayfa hızı sürtükleriyiz), bu alan adı için sertifikayı da eklemeniz gerektiğini unutmayın.


2

Android'de belirli bir sertifikaya güvenmek için küçük kütüphane ssl-utils-android yazdım .

Varlıklar dizininden dosya adını vererek herhangi bir sertifikayı kolayca yükleyebilirsiniz.

Kullanımı:

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

1

Bu düzeltmelerin hiçbiri SDK 16, Sürüm 4.1.2'yi hedefleyen geliştirme platformum için işe yaramadı, bu yüzden bir çözüm buldum.

Uygulamam, verileri " http://www.example.com/page.php?data=somedata " kullanarak sunucuda depolar

Son zamanlarda page.php " https://www.secure-example.com/page.php " adresine taşındı ve "javax.net.ssl.SSLException: Güvenilir sunucu sertifikası" almaya devam ediyorum.

Tüm sertifikaları tek bir sayfa için kabul etmek yerine, bu kılavuzdan başlayarak " http://www.example.com/page.php " adresinde yayınlanan kendi page.php sorunumu çözdüm.

<?php

caronte ("https://www.secure-example.com/page.php");

function caronte($url) {
    // build curl request
    $ch = curl_init();
    foreach ($_POST as $a => $b) {
        $post[htmlentities($a)]=htmlentities($b);
    }
    curl_setopt($ch, CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS,http_build_query($post));

    // receive server response ...
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $server_output = curl_exec ($ch);
    curl_close ($ch);

    echo $server_output;
}

?>

1

19 Ocak 2020 Kendinden İmzalı Sertifika SORUN DÜZELTME:

Kendinden imzalı herhangi bir sertifika için video, resim, web servisini aramak veya güvenli olmayan herhangi bir URL'ye bağlanmak için herhangi bir işlem yapmadan önce bu yöntemi çağırmanız yeterlidir, sertifika sorunuyla ilgili sorununuzu çözecektir:

KOTLIN KODU

  private fun disableSSLCertificateChecking() {
        val hostnameVerifier = object: HostnameVerifier {
            override fun verify(s:String, sslSession: SSLSession):Boolean {
                return true
            }
        }
        val trustAllCerts = arrayOf<TrustManager>(object: X509TrustManager {
            override fun getAcceptedIssuers(): Array<X509Certificate> {
                TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
            }

            //val acceptedIssuers:Array<X509Certificate> = null
            @Throws(CertificateException::class)
            override fun checkClientTrusted(arg0:Array<X509Certificate>, arg1:String) {// Not implemented
            }
            @Throws(CertificateException::class)
            override fun checkServerTrusted(arg0:Array<X509Certificate>, arg1:String) {// Not implemented
            }
        })
        try
        {
            val sc = SSLContext.getInstance("TLS")
            sc.init(null, trustAllCerts, java.security.SecureRandom())
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory())
            HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier)
        }
        catch (e: KeyManagementException) {
            e.printStackTrace()
        }
        catch (e: NoSuchAlgorithmException) {
            e.printStackTrace()
        }
    }

0

Belki bu yardımcı olacaktır ... kendinden imzalı sertifikalar kullanan java istemcileri üzerinde çalışır (sertifikanın kontrolü yoktur). Dikkatli olun ve sadece geliştirme vakaları için kullanın çünkü bu hiç güvenli değildir!

Apache HttpClient 4.0'da SSL sertifikası hataları nasıl yoksayılır

Umarım sadece HttpClient kütüphanesini ekleyerek Android'de çalışır ... iyi şanslar !!


1
Hayır, Android varyantında mevcut olmayan kullanımdan kaldırılmış yöntemlere dayandığından android üzerinde çalışmaz :-(
kellyfj

0

Bu sorun, A, ndroid 2.x'te SNI (Sunucu Adı Tanımlama) desteği eksikliğinden kaynaklanmaktadır. Aşağıdaki sorunun karşısına çıkana kadar bir hafta boyunca bu sorunla mücadele ediyordum, bu da sorunun iyi bir arka planını vermekle kalmıyor, aynı zamanda herhangi bir güvenlik boşluğundan yoksun çalışan ve etkili bir çözüm sunuyor.

Android 2.3'te 'eş sertifikası yok' hatası ancak 4'te DEĞİL

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.