การเชื่อมต่อ Https Android


101

ฉันกำลังโพสต์ https และได้รับข้อยกเว้นของข้อยกเว้น ssl ไม่ใช่ใบรับรองเซิร์ฟเวอร์ที่เชื่อถือได้ ถ้าฉันใช้ http ปกติมันก็ทำงานได้ดีอย่างสมบูรณ์ ฉันต้องยอมรับใบรับรองเซิร์ฟเวอร์หรือไม่?


ฉันขอตัวอย่างการใช้งานแบบเดียวกันได้
ไหม

เธรดนี้อาจช่วยได้ แต่ฉันไม่สามารถบอกได้ว่ามันจะทำงานได้หรือไม่ API ล่าสุด: groups.google.com/group/android-developers/browse_thread/thread/…
RzR

คำตอบ:


45

ฉันกำลังคาดเดา แต่ถ้าคุณต้องการให้มีการจับมือจริงเกิดขึ้นคุณต้องแจ้งให้ Android ทราบถึงใบรับรองของคุณ หากคุณต้องการยอมรับไม่ว่าจะเกิดอะไรขึ้นให้ใช้รหัสหลอกนี้เพื่อรับสิ่งที่คุณต้องการกับไคลเอนต์ Apache HTTP:

SchemeRegistry schemeRegistry = new SchemeRegistry ();

schemeRegistry.register (new Scheme ("http",
    PlainSocketFactory.getSocketFactory (), 80));
schemeRegistry.register (new Scheme ("https",
    new CustomSSLSocketFactory (), 443));

ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager (
    params, schemeRegistry);


return new DefaultHttpClient (cm, params);

CustomSSLSocketFactory:

public class CustomSSLSocketFactory extends org.apache.http.conn.ssl.SSLSocketFactory
{
private SSLSocketFactory FACTORY = HttpsURLConnection.getDefaultSSLSocketFactory ();

public CustomSSLSocketFactory ()
    {
    super(null);
    try
        {
        SSLContext context = SSLContext.getInstance ("TLS");
        TrustManager[] tm = new TrustManager[] { new FullX509TrustManager () };
        context.init (null, tm, new SecureRandom ());

        FACTORY = context.getSocketFactory ();
        }
    catch (Exception e)
        {
        e.printStackTrace();
        }
    }

public Socket createSocket() throws IOException
{
    return FACTORY.createSocket();
}

 // TODO: add other methods like createSocket() and getDefaultCipherSuites().
 // Hint: they all just make a call to member FACTORY 
}

FullX509TrustManager เป็นคลาสที่ใช้ javax.net.ssl.X509TrustManager ที่ยังไม่มีวิธีการจริงในการทำงานใด ๆ ได้รับตัวอย่างที่นี่

โชคดี!


เหตุใดจึงมีตัวแปร FACTORY ??
Codevalley

1
ส่งคืน FACTORY.createSocket (); กำลังมีปัญหา ซ็อกเก็ตที่สร้างขึ้นมีข้อยกเว้นของตัวชี้ null ในการดำเนินการ () นอกจากนี้ฉันสังเกตเห็นว่ามี 2 คลาส SocketFactory 1. org.apache.http.conn.ssl.SSLSocketFactory และ 2. javax.net.ssl.SSLSocketFactory
Codevalley

2
สวัสดีเนทดูเหมือนจะมีประโยชน์สำหรับสถานการณ์ของฉัน แต่ฉันมีปัญหากับการสร้าง CustomSSLSocketFactory ควรขยายชั้นเรียนอะไร หรือควรใช้อินเทอร์เฟซอะไร ฉันได้ทดลองกับ: javax.net.SocketFactory, javax.net.ssl.SSLSocketFactory, org.apache.http.conn.scheme.SocketFactory ซึ่งทั้งหมดบังคับใช้วิธีการอื่น ๆ ... โดยทั่วไปแล้วอะไร เนมสเปซของคลาสที่ใช้ในโค้ดของคุณคืออะไร? ขอบคุณ. :)
Cephron

2
ใช้งานไม่ได้สำหรับฉันทำให้ฉันมีข้อผิดพลาดใบรับรองเซิร์ฟเวอร์ไม่เชื่อถือเหมือนกัน
Omar Rehman

1
ฉันจะได้คลาสนี้ได้อย่างไรFullX509TrustManager
RajaReddy PolamReddy

89

นี่คือสิ่งที่ฉันกำลังทำ มันไม่ได้ตรวจสอบใบรับรองอีกต่อไป

// always verify the host - dont check for certificate
final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
    public boolean verify(String hostname, SSLSession session) {
        return true;
    }
};

/**
 * Trust every server - dont check for any certificate
 */
private static void trustAllHosts() {
    // Create a trust manager that does not validate certificate chains
    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 {
        }
    } };

    // Install the all-trusting trust manager
    try {
        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection
                .setDefaultSSLSocketFactory(sc.getSocketFactory());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

และ

    HttpURLConnection http = null;

    if (url.getProtocol().toLowerCase().equals("https")) {
        trustAllHosts();
        HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
        https.setHostnameVerifier(DO_NOT_VERIFY);
        http = https;
    } else {
        http = (HttpURLConnection) url.openConnection();
    }

แบบนี้ดูดี! อย่างไรก็ตามฉันใช้ WebView และต้องเชื่อมต่อกับเซิร์ฟเวอร์ https เพื่อการทดสอบเท่านั้น (ไคลเอนต์ไม่สามารถจัดเตรียม FQDN ที่ตรงกันและไม่สามารถทดสอบกับ http ได้) มีวิธีใดในการแก้ไขปัญหานี้เมื่อใช้ WebView หรือไม่ ฉันเพิ่งวางรหัสนี้ในกิจกรรมที่ WebView อยู่และ "ใช้งานได้จริงหรือ" (สงสัยว่าไม่ใช่… ??)
Joe D'Andrea

ฉันกำลังพยายามใช้โซลูชันนั้นทีละขั้นตอนและฉันได้รับข้อยกเว้นดังกล่าว: 07-25 12: 35: 25.941: WARN / System.err (24383): java.lang.ClassCastException: org.apache.harmony.luni .internal.net.www.protocol.http.HttpURLConnectionImpl ในตำแหน่งที่ฉันพยายามเปิดการเชื่อมต่อ ... มีความคิดว่าทำไม ??
Robert

1
เฮ้ฉันก็ทำตามคำแนะนำโดยคุณ javax.net.ssl.SSLException: Received fatal alert: bad_record_macแต่ฉันได้รับข้อยกเว้นเป็น ฉันได้ลองแทนที่TLSด้วยSSLแต่ก็ไม่ได้ผล โปรดช่วยฉันด้วยขอบคุณ
devsri

40
แม้ว่าสิ่งนี้จะดีในระหว่างขั้นตอนการพัฒนา แต่คุณควรตระหนักว่าสิ่งนี้อนุญาตให้ใครก็ตามสามารถ MITM การเชื่อมต่อที่ปลอดภัยของคุณได้โดยการปลอมใบรับรอง SSL แบบสุ่มซึ่งทำให้การเชื่อมต่อของคุณไม่ปลอดภัยอีกต่อไป ลองดูคำถามนี้เพื่อดูว่าทำถูกวิธีที่นี่เพื่อดูวิธีรับใบรับรองและสุดท้ายนี้เพื่อเรียนรู้วิธีเพิ่มในที่เก็บคีย์
cimnine

2
คุณไม่ควรใช้คำแนะนำหรือโพสต์รหัสนี้ มันไม่ปลอดภัยอย่างสิ้นเชิง คุณควรแก้ปัญหาที่แท้จริง
Marquis of Lorne

33

ในขณะที่พยายามตอบคำถามนี้ฉันพบบทแนะนำที่ดีกว่า ด้วยวิธีนี้คุณไม่จำเป็นต้องประนีประนอมกับการตรวจสอบใบรับรอง

http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html

* ฉันไม่ได้เขียนสิ่งนี้ แต่ต้องขอบคุณ Bob Lee สำหรับงานนี้


4
นี่คือคำตอบที่สมบูรณ์แบบ ฉันได้โพสต์การอัปเดตที่แสดงวิธีจัดการกับ CA ที่ไม่อยู่ในรายการเนื่องจากฉันได้รับข้อผิดพลาด PeerCertificate ดูได้ที่นี่: blog.donnfelker.com/2011/06/13/…
Donn Felker

6

คุณยังสามารถดูบทความในบล็อกของฉันซึ่งคล้ายกับ crazybobs มาก

โซลูชันนี้ยังไม่กระทบต่อการตรวจสอบใบรับรองและอธิบายวิธีเพิ่มใบรับรองที่เชื่อถือได้ในที่เก็บคีย์ของคุณเอง

http://blog.antoine.li/index.php/2010/10/android-trusting-ssl-certificates/


4

http://madurangasblogs.blogspot.in/2013/08/avoiding-javaxnetsslsslpeerunverifiedex.html

Maduranga ได้รับความอนุเคราะห์

เมื่อพัฒนาแอปพลิเคชันที่ใช้ https เซิร์ฟเวอร์ทดสอบของคุณไม่มีใบรับรอง SSL ที่ถูกต้อง หรือบางครั้งเว็บไซต์ใช้ใบรับรองที่ลงนามด้วยตนเองหรือเว็บไซต์ใช้ใบรับรอง SSL ฟรี ดังนั้นหากคุณพยายามเชื่อมต่อกับเซิร์ฟเวอร์โดยใช้ Apache HttpClientคุณจะได้รับข้อยกเว้นที่บอกว่า "ไม่มีการตรวจสอบสิทธิ์แบบเพียร์" แม้ว่าจะไม่ใช่แนวทางปฏิบัติที่ดีในการเชื่อถือใบรับรองทั้งหมดในซอฟต์แวร์ที่ใช้งานจริง แต่คุณอาจต้องทำเช่นนั้นตามสถานการณ์ โซลูชันนี้แก้ไขข้อยกเว้นที่เกิดจาก "peer not authenticated"

แต่ก่อนที่เราจะไปที่โซลูชันฉันต้องเตือนคุณว่านี่ไม่ใช่ความคิดที่ดีสำหรับแอปพลิเคชันการผลิต สิ่งนี้จะละเมิดวัตถุประสงค์ของการใช้ใบรับรองความปลอดภัย ดังนั้นถ้าคุณไม่มีเหตุผลที่ดีหรือแน่ใจว่าจะไม่ก่อให้เกิดปัญหาใด ๆ อย่าใช้วิธีนี้

ปกติคุณสร้างแบบHttpClientนี้

HttpClient httpclient = new DefaultHttpClient();

แต่คุณต้องเปลี่ยนวิธีสร้าง HttpClient

org.apache.http.conn.ssl.SSLSocketFactoryแรกที่คุณต้องสร้างชั้นขยาย

import org.apache.http.conn.ssl.SSLSocketFactory;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class MySSLSocketFactory extends SSLSocketFactory {
         SSLContext sslContext = SSLContext.getInstance("TLS");

    public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
        super(truststore);

        TrustManager tm = new X509TrustManager() {
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

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

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

        sslContext.init(null, new TrustManager[] { tm }, null);
    }

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
        return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
    }

    @Override
    public Socket createSocket() throws IOException {
        return sslContext.getSocketFactory().createSocket();
    }
}

จากนั้นสร้างวิธีการเช่นนี้

public HttpClient getNewHttpClient() {
     try {
         KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
         trustStore.load(null, null);

         SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
         sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

         HttpParams params = new BasicHttpParams();
         HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
         HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

         SchemeRegistry registry = new SchemeRegistry();
         registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
         registry.register(new Scheme("https", sf, 443));

         ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

         return new DefaultHttpClient(ccm, params);
     } catch (Exception e) {
         return new DefaultHttpClient();
     }
}

จากนั้นคุณสามารถสร้างไฟล์HttpClient.

HttpClient httpclient = getNewHttpClient();

หากคุณพยายามส่งคำขอโพสต์ไปยังหน้าล็อกอินส่วนที่เหลือของรหัสจะเป็นเช่นนี้

private URI url = new URI("url of the action of the form");
HttpPost httppost =  new HttpPost(url);
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();  
nameValuePairs.add(new BasicNameValuePair("username", "user"));  
nameValuePairs.add(new BasicNameValuePair("password", "password"));
try {
    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
    HttpResponse response = httpclient.execute(httppost);
    HttpEntity entity = response.getEntity();
    InputStream is = entity.getContent();
} catch (UnsupportedEncodingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (ClientProtocolException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

คุณได้รับหน้า html ไปยัง InputStream จากนั้นคุณสามารถทำอะไรก็ได้ที่คุณต้องการด้วยหน้า html ที่ส่งคืน

แต่ที่นี่คุณจะต้องเผชิญกับปัญหา หากคุณต้องการจัดการเซสชันโดยใช้คุกกี้คุณจะไม่สามารถทำได้ด้วยวิธีนี้ หากคุณต้องการรับคุกกี้คุณจะต้องทำผ่านเบราว์เซอร์ จากนั้นคุณเท่านั้นที่จะได้รับคุกกี้



2

สิ่งเหล่านี้ไม่ได้ผลสำหรับฉัน (ถูกทำให้รุนแรงขึ้นโดยบั๊ก Thawteเช่นกัน) ในที่สุดฉันก็ได้รับการแก้ไขด้วยการยอมรับ SSL ที่ลงชื่อด้วยตนเองบน Androidและการจัดการ SSL แบบกำหนดเองก็หยุดทำงานบน Android 2.2 FroYo


2

คำตอบใด ๆ นี้ไม่ได้ผลสำหรับฉันดังนั้นนี่คือรหัสที่เชื่อถือใบรับรองใด ๆ

import java.io.IOException;

    import java.net.Socket;
    import java.security.KeyManagementException;
    import java.security.KeyStoreException;
    import java.security.NoSuchAlgorithmException;
    import java.security.UnrecoverableKeyException;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;

    import javax.net.ssl.SSLContext;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;

    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpPost;
    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.SSLSocketFactory;
    import org.apache.http.conn.ssl.X509HostnameVerifier;
    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.HttpConnectionParams;
import org.apache.http.params.HttpParams;

    public class HttpsClientBuilder {
        public static DefaultHttpClient getBelieverHttpsClient() {

            DefaultHttpClient client = null;

            SchemeRegistry Current_Scheme = new SchemeRegistry();
            Current_Scheme.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
            try {
                Current_Scheme.register(new Scheme("https", new Naive_SSLSocketFactory(), 8443));
            } catch (KeyManagementException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (UnrecoverableKeyException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoSuchAlgorithmException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (KeyStoreException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            HttpParams Current_Params = new BasicHttpParams();
            int timeoutConnection = 8000;
            HttpConnectionParams.setConnectionTimeout(Current_Params, timeoutConnection);
            int timeoutSocket = 10000;
            HttpConnectionParams.setSoTimeout(Current_Params, timeoutSocket);
            ThreadSafeClientConnManager Current_Manager = new ThreadSafeClientConnManager(Current_Params, Current_Scheme);
            client = new DefaultHttpClient(Current_Manager, Current_Params);
            //HttpPost httpPost = new HttpPost(url);
            //client.execute(httpPost);

         return client;
         }

    public static class Naive_SSLSocketFactory extends SSLSocketFactory
    {
        protected SSLContext Cur_SSL_Context = SSLContext.getInstance("TLS");

        public Naive_SSLSocketFactory ()
                throws NoSuchAlgorithmException, KeyManagementException,
                KeyStoreException, UnrecoverableKeyException
        {
            super(null, null, null, null, null, (X509HostnameVerifier)null);
            Cur_SSL_Context.init(null, new TrustManager[] { new X509_Trust_Manager() }, null);
        }

        @Override
        public Socket createSocket(Socket socket, String host, int port,
                boolean autoClose) throws IOException
        {
            return Cur_SSL_Context.getSocketFactory().createSocket(socket, host, port, autoClose);
        }

        @Override
        public Socket createSocket() throws IOException
        {
            return Cur_SSL_Context.getSocketFactory().createSocket();
        }
    }

    private static class X509_Trust_Manager implements X509TrustManager
    {

        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            // TODO Auto-generated method stub

        }

        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            // TODO Auto-generated method stub

        }

        public X509Certificate[] getAcceptedIssuers() {
            // TODO Auto-generated method stub
            return null;
        }

    };
}

รหัสนี้ใช้งานได้ดีกับรูปแบบ URL - localhost: 8443 / webProject / YourService
Speise

ตัวสร้าง SSLSocketFactory (null, null, null, null, null, X509HostnameVerifier) ​​ไม่ได้กำหนด
Michal

1

ฉันไม่รู้เกี่ยวกับข้อกำหนดเฉพาะของ Android สำหรับใบรับรอง ssl แต่มันสมเหตุสมผลแล้วที่ Android จะไม่ยอมรับใบรับรอง ssl ที่ลงนามด้วยตนเองจากค้างคาว ฉันพบโพสต์นี้จากฟอรัม Android ซึ่งดูเหมือนว่าจะแก้ไขปัญหาเดียวกัน: http://androidforums.com/android-applications/950-imap-self-signed-ssl-certificates.html


อย่างที่ฉันบอกว่าฉันไม่รู้ข้อมูลจำเพาะของ Android แต่ฉันเป็นวันที่คุณต้องบอกแพลตฟอร์มว่าใบรับรอง ssl ของเซิร์ฟเวอร์ที่คุณเชื่อมต่อคืออะไร นั่นคือถ้าคุณใช้ใบรับรองที่ลงนามด้วยตนเองซึ่งแพลตฟอร์มไม่รู้จัก คลาส SslCertificate น่าจะเป็นประโยชน์: developer.android.com/reference/android/net/http/… ฉันจะเจาะลึกเรื่องนี้ในภายหลังเมื่อฉันมีเวลามากขึ้น
Matti Lyra

1

นี่เป็นปัญหาที่ทราบแล้วของ Android 2.x ฉันกำลังดิ้นรนกับปัญหานี้เป็นเวลาหนึ่งสัปดาห์จนกระทั่งฉันเจอคำถามต่อไปนี้ซึ่งไม่เพียง แต่ให้ภูมิหลังที่ดีของปัญหา แต่ยังให้วิธีแก้ปัญหาที่ใช้งานได้และมีประสิทธิภาพโดยปราศจากช่องโหว่ด้านความปลอดภัยใด ๆ

ข้อผิดพลาด 'ไม่มีใบรับรองเพียร์' ใน Android 2.3 แต่ไม่มีใน 4


0

ด้วยเหตุผลบางประการวิธีแก้ปัญหาที่กล่าวถึงสำหรับ httpClient ข้างต้นไม่ได้ผลสำหรับฉัน ในตอนท้ายฉันสามารถทำให้มันทำงานได้โดยการแทนที่เมธอดอย่างถูกต้องเมื่อใช้คลาส SSLSocketFactory ที่กำหนดเอง

@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) 
                              throws IOException, UnknownHostException 
    {
    return sslFactory.createSocket(socket, host, port, autoClose);
}

@Override
public Socket createSocket() throws IOException {
    return sslFactory.createSocket();
}

นี่คือวิธีการทำงานที่สมบูรณ์แบบสำหรับฉัน คุณสามารถดูคลาสแบบกำหนดเองแบบเต็มและการใช้งานในเธรดต่อไปนี้: http://blog.syedgakbar.com/2012/07/21/android-https-and-not-trusted-server-certificate-error/


0

ฉันสร้างชั้นเรียนนี้และพบ

package com.example.fakessl;

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;

import android.util.Log;

public class CertificadoAceptar {
    private static TrustManager[] trustManagers;

    public static class _FakeX509TrustManager implements
            javax.net.ssl.X509TrustManager {
        private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[] {};

        public void checkClientTrusted(X509Certificate[] arg0, String arg1)
                throws CertificateException {
        }

        public void checkServerTrusted(X509Certificate[] arg0, String arg1)
                throws CertificateException {
        }

        public boolean isClientTrusted(X509Certificate[] chain) {
            return (true);
        }

        public boolean isServerTrusted(X509Certificate[] chain) {
            return (true);
        }

        public X509Certificate[] getAcceptedIssuers() {
            return (_AcceptedIssuers);
        }
    }

    public static void allowAllSSL() {

        javax.net.ssl.HttpsURLConnection
                .setDefaultHostnameVerifier(new HostnameVerifier() {
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });

        javax.net.ssl.SSLContext context = null;

        if (trustManagers == null) {
            trustManagers = new javax.net.ssl.TrustManager[] { new _FakeX509TrustManager() };
        }

        try {
            context = javax.net.ssl.SSLContext.getInstance("TLS");
            context.init(null, trustManagers, new SecureRandom());
        } catch (NoSuchAlgorithmException e) {
            Log.e("allowAllSSL", e.toString());
        } catch (KeyManagementException e) {
            Log.e("allowAllSSL", e.toString());
        }
        javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(context
                .getSocketFactory());
    }
}

ในคุณเขียนโค้ดสีขาวนี้

CertificadoAceptar ca = new CertificadoAceptar();
ca.allowAllSSL();
HttpsTransportSE Transport = new HttpsTransportSE("iphost or host name", 8080, "/WS/wsexample.asmx?WSDL", 30000);

0

แหล่งที่มาที่ช่วยให้ฉันทำงานกับใบรับรองที่ลงนามด้วยตนเองบนเซิร์ฟเวอร์ AWS Apache ของฉันและเชื่อมต่อกับ HttpsURLConnection จากอุปกรณ์ Android:

SSL บนอินสแตนซ์ aws - บทช่วยสอนของ amazon เกี่ยวกับ ssl
Android Security ด้วย HTTPS และ SSL - การสร้างผู้จัดการความเชื่อถือของคุณเองบนไคลเอนต์เพื่อยอมรับ ใบรับรองของคุณการ
สร้างใบรับรองที่ลงนามด้วยตนเอง - สคริปต์ง่าย ๆ สำหรับการสร้างใบรับรองของคุณ

จากนั้นฉันทำสิ่งต่อไปนี้:

  1. ตรวจสอบให้แน่ใจว่าเซิร์ฟเวอร์รองรับ https (sudo yum install -y mod24_ssl)
  2. ใส่สคริปต์นี้ในไฟล์create_my_certs.sh:
#!/bin/bash
FQDN=$1

# make directories to work from
mkdir -p server/ client/ all/

# Create your very own Root Certificate Authority
openssl genrsa \
  -out all/my-private-root-ca.privkey.pem \
  2048

# Self-sign your Root Certificate Authority
# Since this is private, the details can be as bogus as you like
openssl req \
  -x509 \
  -new \
  -nodes \
  -key all/my-private-root-ca.privkey.pem \
  -days 1024 \
  -out all/my-private-root-ca.cert.pem \
  -subj "/C=US/ST=Utah/L=Provo/O=ACME Signing Authority Inc/CN=example.com"

# Create a Device Certificate for each domain,
# such as example.com, *.example.com, awesome.example.com
# NOTE: You MUST match CN to the domain name or ip address you want to use
openssl genrsa \
  -out all/privkey.pem \
  2048

# Create a request from your Device, which your Root CA will sign
openssl req -new \
  -key all/privkey.pem \
  -out all/csr.pem \
  -subj "/C=US/ST=Utah/L=Provo/O=ACME Tech Inc/CN=${FQDN}"

# Sign the request from Device with your Root CA
openssl x509 \
  -req -in all/csr.pem \
  -CA all/my-private-root-ca.cert.pem \
  -CAkey all/my-private-root-ca.privkey.pem \
  -CAcreateserial \
  -out all/cert.pem \
  -days 500

# Put things in their proper place
rsync -a all/{privkey,cert}.pem server/
cat all/cert.pem > server/fullchain.pem         # we have no intermediates in this case
rsync -a all/my-private-root-ca.cert.pem server/
rsync -a all/my-private-root-ca.cert.pem client/
  1. วิ่ง bash create_my_certs.sh yourdomain.com
  2. วางใบรับรองในตำแหน่งที่เหมาะสมบนเซิร์ฟเวอร์ (คุณสามารถค้นหาการกำหนดค่าได้ใน /etc/httpd/conf.d/ssl.conf) ควรตั้งค่าทั้งหมดเหล่านี้:
    SSLCertificateFile
    SSLCertificateKeyFile
    SSLCertificateChainFile
    SSLCACertificateFile

  3. รีสตาร์ท httpd โดยใช้sudo service httpd restartและตรวจสอบให้แน่ใจว่า httpd เริ่มต้นแล้ว: การ
    หยุด httpd: [ตกลง] การ
    เริ่ม httpd: [ตกลง]

  4. คัดลอกmy-private-root-ca.certไปยังโฟลเดอร์สินทรัพย์โครงการ Android ของคุณ

  5. สร้างผู้จัดการความน่าเชื่อถือของคุณ:

    SSLContext SSLContext;

    CertificateFactory cf = CertificateFactory.getInstance ("X.509"); InputStream caInput = context.getAssets () เปิด ("my-private-root-ca.cert.pem"); ใบรับรอง CA; ลองใช้ {ca = cf.generateCertificate (caInput); } ในที่สุด {caInput.close (); }

      // 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 = SSLContext.getInstance("TLS");
      SSSLContext.init(null, tmf.getTrustManagers(), null);
  6. และทำการเชื่อมต่อโดยใช้ HttpsURLConnection:

    การเชื่อมต่อ HttpsURLConnection = (HttpsURLConnection) url.openConnection (); connection.setSSLSocketFactory (SSLContext.getSocketFactory ());

  7. ลองเชื่อมต่อ https ของคุณ


0

คุณอาจลองทำสิ่งนี้ได้ สิ่งนี้ช่วยฉันได้

    SslContextFactory sec = new SslContextFactory();
    sec.setValidateCerts(false);
    sec.setTrustAll(true);

    org.eclipse.jetty.websocket.client.WebSocketClient client = new WebSocketClient(sec);

-1

เพียงใช้วิธีนี้เป็น HTTPClient ของคุณ:

public static  HttpClient getNewHttpClient() {
    try {
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        trustStore.load(null, null);

        SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
        sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        registry.register(new Scheme("https", sf, 443));

        ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

        return new DefaultHttpClient(ccm, params);
    } catch (Exception e) {
        return new DefaultHttpClient();
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.