كيفية التعامل مع شهادات SSL غير صالحة مع Apache httpclient؟ [مكرر

StackOverflow https://stackoverflow.com/questions/1828775

  •  11-09-2019
  •  | 
  •  

سؤال

أعلم، هناك العديد من الأسئلة المختلفة والحد من الإجابات حول هذه المشكلة ... لكنني لا أستطيع أن أفهم ...

لدي: Ubuntu-9.10-Desktop-AMD64 + NETBEANS6.7.1 مثبتة "كما هو" من خارج. اعادة عد. أحتاج الاتصال ببعض الموقع عبر HTTPS. لهذا يمكنني استخدام Apache HttpClient.

من البرنامج التعليمي قرأت:

"بمجرد تثبيت jsse بشكل صحيح، يجب أن يكون التواصل الآمن HTTP عبر SSL
بسيطة مثل اتصال HTTP عادي. "وبعض المثال:

HttpClient httpclient = new HttpClient();
GetMethod httpget = new GetMethod("https://www.verisign.com/"); 
try { 
  httpclient.executeMethod(httpget);
  System.out.println(httpget.getStatusLine());
} finally {
  httpget.releaseConnection();
}

الآن، أكتب هذا:

HttpClient client = new HttpClient();

HttpMethod get = new GetMethod("https://mms.nw.ru");
//get.setDoAuthentication(true);

try {
    int status = client.executeMethod(get);
    System.out.println(status);

    BufferedInputStream is = new BufferedInputStream(get.getResponseBodyAsStream());
    int r=0;byte[] buf = new byte[10];
    while((r = is.read(buf)) > 0) {
        System.out.write(buf,0,r);
    }

} catch(Exception ex) {
    ex.printStackTrace();
}

نتيجة لذلك لدي مجموعة من الأخطاء:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
        at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1627)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:204)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:198)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:994)
        at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:142)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:533)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:471)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:904)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1132)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:643)
        at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:78)
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
        at org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(HttpConnection.java:828)
        at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2116)
        at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
        at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
        at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
        at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
        at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
        at simpleapachehttp.Main.main(Main.java:41)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:302)
        at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:205)
        at sun.security.validator.Validator.validate(Validator.java:235)
        at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:147)
        at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:230)
        at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:270)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:973)
        ... 17 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:191)
        at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:255)
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:297)
        ... 23 more

ماذا علي أن أفعل لإنشاء اتصال أبسط SSL؟ (ربما بدون keymanager ومدير الثقة وما إلى ذلك.)

هل كانت مفيدة؟

المحلول

https://mms.nw.ru. يستخدم شهادة توقيع ذاتي والتي من الواضح أنها لا تحتوي على مجموعة افتراضية من مديري الثقة.

ستحتاج إلى أحد الإجراءات التالية:

  • تكوين SSLContext مع TrustManager يقبل أي سيرت (انظر أدناه)

  • تكوين SSLContext مع متجر ثقة مناسب يتضمن سيرتك

  • أضف Cert إلى هذا الموقع إلى متجر Java Trust Start الافتراضي.

فيما يلي برنامج نموذج يخلق سياق SSL (معظمه لا قيمة له) يقبل أي سيرت:

import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class SSLTest {

    public static void main(String [] args) throws Exception {
        // configure the SSLContext with a TrustManager
        SSLContext ctx = SSLContext.getInstance("TLS");
        ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());
        SSLContext.setDefault(ctx);

        URL url = new URL("https://mms.nw.ru");
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
        conn.setHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        });
        System.out.println(conn.getResponseCode());
        conn.disconnect();
    }

    private static class DefaultTrustManager implements X509TrustManager {

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

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

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

نصائح أخرى

https://mms.nw.ru. من المرجح أن يستخدم الشهادة التي لم تصدرها سلطة مصلحة. وبالتالي، تحتاج إلى إضافة الشهادة إلى متجر Java Key الموثوق به كما هو موضح في غير قادر على العثور على مسار شهادة صالحة إلى الهدف المطلوب:

عند العمل على عميل يعمل مع خادم SSL يدعم يعمل في بروتوكول HTTPS، يمكنك الحصول على خطأ "غير قادر على العثور على مسار شهادات صالح إلى الهدف المطلوب" إذا لم تصدر شهادة الخادم عن طريق مرجع الشهادة، ولكن تم توقيع نفسك أو إصدارها من قبل CMS خاص.

لا الذعر. كل ما عليك فعله هو إضافة شهادة الخادم إلى متجر Java Key الموثوق به إذا كتب عميلك في Java. قد تتساءل كيف يمكنك الوصول إلى الجهاز حيث تم تثبيت الخادم. هناك برنامج بسيط يمكن أن يساعدك. يرجى تحميل برنامج جافا و اهرب

% java InstallCert _web_site_hostname_

افتتح هذا البرنامج اتصالا بالمضيف المحدد وبدأ مصافحة SSL. طباعة أثر المكدس الاستثناء للخطأ الذي حدث ويظهر لك الشهادات المستخدمة من قبل الخادم. الآن يطالبك بإضافة الشهادة إلى Keystore الموثوق بها.

إذا قمت بتغيير رأيك، فأدخل "س". إذا كنت ترغب حقا في إضافة الشهادة، فأدخل أرقام "1" أو أرقام أخرى لإضافة شهادات أخرى، حتى شهادة CA، لكنك عادة لا تريد أن تفعل ذلك. بمجرد اختيارك، سيعرض البرنامج الشهادة الكاملة ثم أضفته إلى مفتاح Keystore Java المسمى "JSSECACERTS" في الدليل الحالي.

لاستخدامها في البرنامج الخاص بك، إما تكوين JSSE لاستخدامه كحل ثقة أو نسخه في دليل $ Java_home / JRE / Lib / Securmance. إذا كنت تريد أن تتعرف جميع تطبيقات Java على الشهادة على أنها موثوق بها وليس فقط JSSE، فيمكنك أيضا الكتابة فوق ملف Cacerts في هذا الدليل.

بعد كل ذلك، سيتمكن JSSE من إكمال مصافحة مع المضيف، والذي يمكنك التحقق من خلال تشغيل البرنامج مرة أخرى.

للحصول على مزيد من التفاصيل، يمكنك التحقق من بلوق ليلاند لا مزيد من "غير قادر على إيجاد مسار شهادة صالحة إلى الهدف المطلوب"

بالإضافة إلى إجابة Pascal TEMIVENT الصحيحة، هناك طريقة أخرى هي حفظ الشهادة من Firefox (عرض الشهادة -> التفاصيل -> تصدير) أو openssl s_client واستيرادها إلى متجر الثقة.

يجب عليك فقط القيام بذلك فقط إذا كان لديك طريقة للتحقق من هذه الشهادة. فشل ذلك، افعلها في المرة الأولى التي تتصل فيها، وسوف تعطيك على الأقل خطأ إذا تغيرت الشهادة بشكل غير متوقع على الاتصالات اللاحقة.

لاستيرادها في متجر ثقة، استخدم:

keytool -importcert -keystore truststore.jks -file servercert.pem

بشكل افتراضي، يجب أن يكون مخزن الثقة الافتراضي lib/security/cacerts وكلمة المرور الخاصة بها يجب أن تكون changeit, ، يرى دليل مرجعي JSSE للتفاصيل.

إذا كنت لا ترغب في السماح بذلك الشهادة على مستوى العالم، ولكن فقط لهذه الاتصالات، فمن الممكن إنشاء SSLContext لذلك:

TrustManagerFactory tmf = TrustManagerFactory
    .getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore ks = KeyStore.getInstance("JKS");
FileInputStream fis = new FileInputStream("/.../truststore.jks");
ks.load(fis, null);
// or ks.load(fis, "thepassword".toCharArray());
fis.close();

tmf.init(ks);

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);

ثم، تحتاج إلى إعداده ل Apache HTTP Client 3.x عن طريق تطبيق واحد إذا كان عليه SecureProtocolSocketFactory لاستخدام هذا SSLContext. وبعد (هناك أمثلة هنا).

Apache HTTP Client 4.x (بصرف النظر عن النسخة الأولى) لديه دعم مباشر لمرور SSLContext.

طريقة Apache httpclient 4.5:

org.apache.http.ssl.SSLContextBuilder sslContextBuilder = SSLContextBuilder.create();
sslContextBuilder.loadTrustMaterial(new org.apache.http.conn.ssl.TrustSelfSignedStrategy());
SSLContext sslContext = sslContextBuilder.build();
org.apache.http.conn.ssl.SSLConnectionSocketFactory sslSocketFactory =
        new SSLConnectionSocketFactory(sslContext, new org.apache.http.conn.ssl.DefaultHostnameVerifier());

HttpClientBuilder httpClientBuilder = HttpClients.custom().setSSLSocketFactory(sslSocketFactory);
httpClient = httpClientBuilder.build();

ملاحظة: org.apache.http.conn.ssl.SSLContextBuilder يكون إهمال و org.apache.http.ssl.SSLContextBuilder هو الجديد (إشعار conn مفقود من اسم حزمة الأخير).

من http://hc.apache.org/httpclient-3.x/sslguide.html.:

Protocol.registerProtocol("https", 
new Protocol("https", new MySSLSocketFactory(), 443));
HttpClient httpclient = new HttpClient();
GetMethod httpget = new GetMethod("https://www.whatever.com/");
try {
  httpclient.executeMethod(httpget);
      System.out.println(httpget.getStatusLine());
} finally {
      httpget.releaseConnection();
}

حيث يمكن العثور على مثال mysslsacletory هنا. وبعد يشير إلى أ TrustManager, ، والتي يمكنك تعديلها لتثقيف كل شيء (على الرغم يجب أن تنظر في هذا!

ل Apache httpclient 4.5+ و Java8:

SSLContext sslContext = SSLContexts.custom()
        .loadTrustMaterial((chain, authType) -> true).build();

SSLConnectionSocketFactory sslConnectionSocketFactory =
        new SSLConnectionSocketFactory(sslContext, new String[]
        {"SSLv2Hello", "SSLv3", "TLSv1","TLSv1.1", "TLSv1.2" }, null,
        NoopHostnameVerifier.INSTANCE);
CloseableHttpClient client = HttpClients.custom()
        .setSSLSocketFactory(sslConnectionSocketFactory)
        .build();

ولكن إذا استخدم HttpClient الخاص بك اتصالا للبحث عن اتصال، على سبيل المثال، مثل هذا:

 PoolingHttpClientConnectionManager connectionManager = new 
         PoolingHttpClientConnectionManager();

 CloseableHttpClient client = HttpClients.custom()
            .setConnectionManager(connectionManager)
            .build();

ال HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory) ليس له أي تأثير, ، لم يتم حل المشكلة.

نظرا لأن استخدام HTTPClient استخدام الاتصال المحدد من أجل البحث عن اتصال والاتصال المحدد لم يكن تسجيلنا لحل هذا، يجب أن تسجل SSLCONTACTICTORTORTORTORTORATORMATORMATORY في الاتصال. يجب أن يكون الرمز الصحيح مثل هذا:

PoolingHttpClientConnectionManager connectionManager = new 
    PoolingHttpClientConnectionManager(RegistryBuilder.
                <ConnectionSocketFactory>create()
      .register("http",PlainConnectionSocketFactory.getSocketFactory())
      .register("https", sslConnectionSocketFactory).build());

CloseableHttpClient client = HttpClients.custom()
            .setConnectionManager(connectionManager)
            .build();

بمجرد أن يكون لديك متجر جافا سيرت (باستخدام رائعة InstallCert Class تم إنشاؤه أعلاه)، يمكنك الحصول على Java لاستخدامه عن طريق تمرير "Javax.ssl.TrustStStore" Param في بدء تشغيل Java.

السابق:

java -Djavax.net.ssl.trustStore=/path/to/jssecacerts MyClassName

مشكلة أخرى قد تواجهها مع اختبار موقعة ذاتيا

java.io.ioException: اسم المضيف HTTPS خطأ: يجب أن يكون ...

يحدث هذا الخطأ عند محاولة الوصول إلى عنوان URL HTTPS. ربما تكون قد قمت بالفعل بتثبيت شهادة الخادم إلى Keystore JRE الخاص بك. ولكن هذا الخطأ يعني أن اسم شهادة الخادم لا يتطابق مع اسم المجال الفعلي للخادم المذكور في عنوان URL. يحدث هذا عادة عند استخدام شهادة صادرة غير المرجعية.

يوضح هذا المثال كيفية كتابة DefaulThostMOstfostifioMverifierferifierferferifierferferifierferifier الذي يتجاهل اسم خادم الشهادات:

http://www.java-samples.com/showtutorial.php؟tutoryid=211.

تريد لصق الجواب هنا:

في Apache httpclient 4.5.5

كيفية التعامل مع شهادة SSL غير صالحة مع عميل Apache 4.5.5؟

HttpClient httpClient = HttpClients
            .custom()
            .setSSLContext(new SSLContextBuilder().loadTrustMaterial(null, TrustAllStrategy.INSTANCE).build())
            .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
            .build();

للحصول على وسيلة لإضافة مضيفات بسهولة تثق في وقت التشغيل دون إلقاء جميع الشيكات، جرب الكود هنا: http://code.google.com/p/self-signed-cert-trust-manager/.

aseysslprotocolsAckletory كان يعطيني مشاكل لذلك انتهى بي الأمر في تنفيذ بروتوكولاتي الخاصة.

أولا تحتاج إلى تسجيله:

Protocol.registerProtocol("https", new Protocol("https", new TrustAllSSLSocketFactory(), 443));

HttpClient client = new HttpClient();
...

ثم قم بتنفيذ ProtocultSactory:

class TrustAllSSLSocketFactory implements ProtocolSocketFactory {

    public static final TrustManager[] TRUST_ALL_CERTS = new TrustManager[]{
        new X509TrustManager() {
            public void checkClientTrusted(final X509Certificate[] certs, final String authType) {

            }

            public void checkServerTrusted(final X509Certificate[] certs, final String authType) {

            }

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

    private TrustManager[] getTrustManager() {
        return TRUST_ALL_CERTS;
    }

    public Socket createSocket(final String host, final int port, final InetAddress clientHost,
                               final int clientPort) throws IOException {
        return getSocketFactory().createSocket(host, port, clientHost, clientPort);
    }

    @Override
    public Socket createSocket(final String host, final int port, final InetAddress localAddress,
                               final int localPort, final HttpConnectionParams params) throws IOException {
        return createSocket(host, port);
    }

    public Socket createSocket(final String host, final int port) throws IOException {
        return getSocketFactory().createSocket(host, port);
    }

    private SocketFactory getSocketFactory() throws UnknownHostException {
        TrustManager[] trustAllCerts = getTrustManager();

        try {
            SSLContext context = SSLContext.getInstance("SSL");
            context.init(null, trustAllCerts, new SecureRandom());

            final SSLSocketFactory socketFactory = context.getSocketFactory();
            HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory);
            return socketFactory;
        } catch (NoSuchAlgorithmException | KeyManagementException exception) {
            throw new UnknownHostException(exception.getMessage());
        }
    }
}

ملاحظة: هذا مع HTTPClient 3.1 و Java 8

هذه حلقة الوصل يشرح الشرط الذي لديك خطوة بخطوة. إذا كنت لا تشعر بالقلق حقا من الشهادة التي يمكنك متابعة العملية في الرابط أدناه.

ملاحظة قد ترغب في التحقق من ضعف ما تفعله منذ ذلك الحين، هذه عملية غير آمنة.

باستخدام InstallCert لتوليد jssecacerts ملف و do.-Djavax.net.ssl.trustStore=/path/to/jssecacerts عملت كبيرة.

أنا أستخدم httpclient 3.1.x، وهذا يعمل بالنسبة لي

        try {
        SSLContext sslContext = SSLContext.getInstance("TLS");
        TrustManager trustManager = new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
        sslContext.init(null, new TrustManager[]{trustManager}, null);
        SslContextSecureProtocolSocketFactory socketFactory = new SslContextSecureProtocolSocketFactory(sslContext,false);
        Protocol.registerProtocol("https", new Protocol("https", (ProtocolSocketFactory) socketFactory, 443));//同样会影响到HttpUtils
    } catch (Throwable e) {
        e.printStackTrace();

}

public class SslContextSecureProtocolSocketFactory implements      SecureProtocolSocketFactory {

private SSLContext sslContext;
private boolean verifyHostname;

public SslContextSecureProtocolSocketFactory(SSLContext sslContext, boolean verifyHostname) {
    this.verifyHostname = true;
    this.sslContext = sslContext;
    this.verifyHostname = verifyHostname;
}

public SslContextSecureProtocolSocketFactory(SSLContext sslContext) {
    this(sslContext, true);
}

public SslContextSecureProtocolSocketFactory(boolean verifyHostname) {
    this((SSLContext)null, verifyHostname);
}

public SslContextSecureProtocolSocketFactory() {
    this((SSLContext)null, true);
}

public synchronized void setHostnameVerification(boolean verifyHostname) {
    this.verifyHostname = verifyHostname;
}

public synchronized boolean getHostnameVerification() {
    return this.verifyHostname;
}

public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException, UnknownHostException {
    SSLSocketFactory sf = this.getSslSocketFactory();
    SSLSocket sslSocket = (SSLSocket)sf.createSocket(host, port, clientHost, clientPort);
    this.verifyHostname(sslSocket);
    return sslSocket;
}

public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
    if(params == null) {
        throw new IllegalArgumentException("Parameters may not be null");
    } else {
        int timeout = params.getConnectionTimeout();
        Socket socket = null;
        SSLSocketFactory socketfactory = this.getSslSocketFactory();
        if(timeout == 0) {
            socket = socketfactory.createSocket(host, port, localAddress, localPort);
        } else {
            socket = socketfactory.createSocket();
            InetSocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
            InetSocketAddress remoteaddr = new InetSocketAddress(host, port);
            socket.bind(localaddr);
            socket.connect(remoteaddr, timeout);
        }

        this.verifyHostname((SSLSocket)socket);
        return socket;
    }
}

public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
    SSLSocketFactory sf = this.getSslSocketFactory();
    SSLSocket sslSocket = (SSLSocket)sf.createSocket(host, port);
    this.verifyHostname(sslSocket);
    return sslSocket;
}

public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
    SSLSocketFactory sf = this.getSslSocketFactory();
    SSLSocket sslSocket = (SSLSocket)sf.createSocket(socket, host, port, autoClose);
    this.verifyHostname(sslSocket);
    return sslSocket;
}

private void verifyHostname(SSLSocket socket) throws SSLPeerUnverifiedException, UnknownHostException {
    synchronized(this) {
        if(!this.verifyHostname) {
            return;
        }
    }

    SSLSession session = socket.getSession();
    String hostname = session.getPeerHost();

    try {
        InetAddress.getByName(hostname);
    } catch (UnknownHostException var10) {
        throw new UnknownHostException("Could not resolve SSL sessions server hostname: " + hostname);
    }

    X509Certificate[] certs = (X509Certificate[])((X509Certificate[])session.getPeerCertificates());
    if(certs != null && certs.length != 0) {
        X500Principal subjectDN = certs[0].getSubjectX500Principal();
        List cns = this.getCNs(subjectDN);
        boolean foundHostName = false;
        Iterator i$ = cns.iterator();
        AntPathMatcher matcher  = new AntPathMatcher();
        while(i$.hasNext()) {
            String cn = (String)i$.next();
            if(matcher.match(cn.toLowerCase(),hostname.toLowerCase())) {
                foundHostName = true;
                break;
            }
        }

        if(!foundHostName) {
            throw new SSLPeerUnverifiedException("HTTPS hostname invalid: expected \'" + hostname + "\', received \'" + cns + "\'");
        }
    } else {
        throw new SSLPeerUnverifiedException("No server certificates found!");
    }
}

private List<String> getCNs(X500Principal subjectDN) {
    ArrayList cns = new ArrayList();
    StringTokenizer st = new StringTokenizer(subjectDN.getName(), ",");

    while(st.hasMoreTokens()) {
        String cnField = st.nextToken();
        if(cnField.startsWith("CN=")) {
            cns.add(cnField.substring(3));
        }
    }

    return cns;
}

protected SSLSocketFactory getSslSocketFactory() {
    SSLSocketFactory sslSocketFactory = null;
    synchronized(this) {
        if(this.sslContext != null) {
            sslSocketFactory = this.sslContext.getSocketFactory();
        }
    }

    if(sslSocketFactory == null) {
        sslSocketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
    }

    return sslSocketFactory;
}

public synchronized void setSSLContext(SSLContext sslContext) {
    this.sslContext = sslContext;
}

}

ل httpclient، يمكننا القيام بذلك:

SSLContext ctx = SSLContext.getInstance("TLS");
        ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());
        SSLContext.setDefault(ctx);

        String uri = new StringBuilder("url").toString();

        HostnameVerifier hostnameVerifier = new HostnameVerifier() {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        };

        HttpClient client = HttpClientBuilder.create().setSSLContext(ctx)
                .setSSLHostnameVerifier(hostnameVerifier).build()

اتبع التعليمات الواردة أدناه ل Java 1.7، لإنشاء شهادة SSL باستخدام ملف برنامج InstallCert.java.

https://github.com/escline/installcert.

يجب إعادة تشغيل tomcat

استخدم ما يلي مع DefaultTrustManager وعمل في HTTPClient مثل سحر. شكرا طن !! تضمين التغريدة

    SSLContext ctx = null;
    SSLConnectionSocketFactory sslsf = null;
    try {

        ctx = SSLContext.getInstance("TLS");
        ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());
        SSLContext.setDefault(ctx);

        sslsf = new SSLConnectionSocketFactory(
                ctx,
                new String[] { "TLSv1" },
                null,
                SSLConnectionSocketFactory.getDefaultHostnameVerifier());

    } catch (Exception e) {
        e.printStackTrace();
    }

     CloseableHttpClient client = HttpClients.custom()
            .setSSLSocketFactory(sslsf)
            .build();

لقد حدثت مواجهة نفس المشكلة، فجأة كانت جميع وارداتي مفقودة. حاولت حذف جميع المحتويات في مجلد .m2 الخاص بي. ومحاولة إعادة استيراد كل شيء، ولكن لا يزال لا شيء يعمل. أخيرا، افتتح ما قمت بفتح الموقع الإلكتروني الذي كان عليه IDE أنه لا يمكن تنزيله في متصفحي. ورأى الشهادة التي كان يستخدمها، ورأيت في بلدي

$ keytool -v -list  PATH_TO_JAVA_KEYSTORE

المسار إلى KeyStore الخاص بي كان /Library/java/javavavinarmachines/jdk1.8.0_171.jdk/contentents/home/jre/lib/security/cacerts

هذه الشهادة الخاصة لم تكن هناك.

لذلك كل ما عليك فعله هو وضع الشهادة في Keystore Java JVM Keystore مرة أخرى. يمكن القيام به باستخدام الأمر أدناه.

$ keytool -import -alias ANY_NAME_YOU_WANT_TO_GIVE -file PATH_TO_YOUR_CERTIFICATE -keystore PATH_OF_JAVA_KEYSTORE

إذا طلبت كلمة المرور، فجرب كلمة المرور الافتراضية "التغيير" إذا حصلت على خطأ إذن عند تشغيل الأمر أعلاه. في Windows افتحه في وضع الإدارة. في Mac و UNIX استخدام Sudo.

بعد إضافة المفتاح بنجاح، يمكنك عرضه باستخدام:

$ keytool -v -list  /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/security/cacerts 

يمكنك عرض SHA-1 فقط باستخدام الأمر Teh

$ keytool -list  /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/security/cacerts 
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top