मैं एक POST अनुरोध बनाने के लिए HttpURLConnection का उपयोग कर रहा हूं (कुछ OAuth2 टोकन एंडपॉइंट पर टोकन लाने के लिए)। टोकन एंडपॉइंट HTTPS का उपयोग करता है। मुझे आश्चर्य है कि HTTPS के संबंध में होस्टनाम सत्यापन कैसे काम करता है। HttpsURLConnection का डिफ़ॉल्ट होस्टनाम सत्यापनकर्ता निम्नलिखित प्रतीत होता है [1]:

     /**
     * HostnameVerifier provides a callback mechanism so that
     * implementers of this interface can supply a policy for
     * handling the case where the host to connect to and
     * the server name from the certificate mismatch.
     *
     * The default implementation will deny such connections.
     */
    private static HostnameVerifier defaultHostnameVerifier =
        new HostnameVerifier() {
            public boolean verify(String urlHostname, String certHostname) {
                return false;
            }
        };

मुझे उम्मीद थी कि मेरा POST अनुरोध विफल हो जाएगा क्योंकि यह सत्यापनकर्ता हमेशा false लौटाता है। यह वह मामला नहीं है। टिप्पणी पहले से ही बताती है कि किसी प्रकार का कॉलबैक तंत्र है। जो मैं नहीं जानता वह है: क्या defaultHostnameVerifier कनेक्शन और प्रमाणपत्र के होस्टनाम को सत्यापित करता है या यह एक डमी कार्यान्वयन है?

मेरा वर्तमान कोडिंग निम्न भाग जैसा दिखता है:

private HttpURLConnection openConnection(String url) throws IOException {
    URL urly = new URL(url);
    final HttpURLConnection con;
    Proxy proxy = getProxy();
    if (proxy == null) {
        con = (HttpURLConnection) urly.openConnection();
    } else {
        con = (HttpURLConnection) urly.openConnection(proxy);
    }

    if (con instanceof HttpsURLConnection) {
        HostnameVerifier verifier = ((HttpsURLConnection) con).getHostnameVerifier(); // there is a default set
        System.out.println(verifier.getClass().getName());
        
    }
    return con;
}

मुझे AsyncHttpClient [2] के संबंध में कुछ स्पष्टीकरण मिला है। चूंकि मैं इस समय इसका उपयोग नहीं करता हूं, क्या मैं डिफ़ॉल्ट कार्यान्वयन के साथ सुरक्षित हूं?

[१] https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/com/sun/net/ssl/HttpsURLConnection.java#L76

[2] https:// kevinlocke.name/bits/2012/10/03/ssl-certificate-verification-in-dispatch-and-asynchttpclient/

2
monti 16 अक्टूबर 2020, 15:44

1 उत्तर

सबसे बढ़िया उत्तर

जैसा कि शीर्ष पर टिप्पणियां कहती हैं, उस वर्ग का अब उपयोग नहीं किया जाता है; यह अमूर्त उपयोगकर्ता-दृश्यमान वर्ग था जिसे अब javax.net.HttpsURLConnection जिसे आप देखेंगे, उसका कोड समान होगा। लेकिन https URL के लिए कार्यान्वयन वर्ग है sun.net.www.protocol.https.HttpsURLConnectionImpl जो सिर्फ sun.net.www.protocol.https .DelegateHttpsURLConnection जो उपवर्ग sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection जो वास्तविक कनेक्शन बनाने के लिए sun.net .www.protocol.HttpsClient और विशेष रूप से .afterConnect()। पृष्ठभूमि के रूप में, जावा के पुराने संस्करणों में SSLSocket ने होस्टनाम सत्यापन नहीं किया था, इसलिए HttpsURLConnection के कार्यान्वयन को इसे जोड़ना पड़ा। जावा 7 अप में, SSLSocket 'समापन बिंदु पहचान' का समर्थन करता है, इसलिए जब afterConnect() यह पहचानता है कि इस URL कनेक्शन पर होस्टनाम सत्यापनकर्ता डिफ़ॉल्ट था, तो यह needToCheckSpoofing को बंद कर देता है और SSLSocket सेट करता है। समापन बिंदु पहचान करने के लिए।

javax. net.ssl.SSLSocket समान रूप से एक अमूर्त वर्ग है जिसे वास्तव में sun.security.ssl.SSLSocketImpl और sun.security.ssl.ClientHandshaker.serverCertificate() जो कॉन्फ़िगर करने योग्य ट्रस्टमैनेजर को कॉल करता है जो डिफ़ॉल्ट रूप से sun.security.ssl.X509TrustManagerImpl जो checkTrusted() चूंकि एंडपॉइंट पहचान के लिए कॉल का अनुरोध किया गया था checkIdentity() जिसे sun.security.util.HostnameChecker TYPE_TLS (वास्तव में HTTPS RFC 2818 का अर्थ है) के साथ, और वह वास्तविक जाँच करता है।

खुशी है आपने पूछा?

पुनश्च: उस वेबपेज पर विश्लेषण, कि HttpsURLConnection.DefaultHostnameVerifier को केवल बेमेल के लिए कहा जाता है, काफी गलत है। ऊपर के रूप में इसे छोड़ दिया गया है और वास्तविक कार्यान्वयन द्वारा कभी नहीं कहा जाता है।

साथ ही मुझे लगता है कि आपको एहसास है कि जब तक आप भुगतान नहीं करते हैं तब तक जावा 7 को वर्षों से समर्थित नहीं किया गया है। हालांकि यह क्षेत्र नहीं बदला है जिसे मैं हाल के संस्करणों में जानता हूं। जावा 11 एक नया java.net.http.HttpClient जोड़ता है जो कार्यात्मक रूप से [Http,Https]URLConnection का स्थान लेता है।

0
dave_thompson_085 16 अक्टूबर 2020, 18:10