Skip to content

Instantly share code, notes, and snippets.

@magicdude4eva
Created June 8, 2017 19:05
Show Gist options
  • Save magicdude4eva/8553a1f59eb94d228cededffbc8dd917 to your computer and use it in GitHub Desktop.
Save magicdude4eva/8553a1f59eb94d228cededffbc8dd917 to your computer and use it in GitHub Desktop.
How to bypass SSLProtocolException: handshake alert: unrecognized_name
/** Downloads a file from the specified URL to the specified local file path.
* It returns the number of bytes in the downloaded file,
* or throws an exception if there is an error.
*
* @param aURL
* @param aLocalFilePath
* @param aMilliSecondTimeout
* @param aSkipSNI
* @return
*/
public static void downLoadFileFromURL(String aURL, String aLocalFilePath, int aMilliSecondTimeout, boolean aSkipSNI) {
try {
int responseCode;
HttpURLConnection httpUrlConnection;
String requestURL = aURL;
URL url;
int redirects = 0;
// handle multiple redirects
while(true) {
// open a connection to the URL and check it
url = new URL(requestURL);
URLConnection urlConnection = url.openConnection();
// override hostnmae verifier if skipSNI is set
if (aSkipSNI && urlConnection instanceof HttpsURLConnection) {
HttpsURLConnection httpsUrlConnection = (HttpsURLConnection) urlConnection;
httpsUrlConnection.setHostnameVerifier(new SSLSkipSNIHostnameVerifier());
}
// (GWN: 2010-05-12): We tell the server that we can support gzip/deflate
urlConnection.setRequestProperty("Accept-Encoding","gzip,deflate");
urlConnection.setRequestProperty("User-Agent" , TRADEFEED_USER_AGENT_STRING);
httpUrlConnection = (HttpURLConnection) urlConnection;
httpUrlConnection.setInstanceFollowRedirects(true);
httpUrlConnection.setReadTimeout(aMilliSecondTimeout);
httpUrlConnection.setConnectTimeout(aMilliSecondTimeout);
responseCode = httpUrlConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_MOVED_PERM || responseCode == HttpURLConnection.HTTP_MOVED_TEMP) {
if(++redirects == CONST_MAX_REDIRECTS)
throw new Exception("Too many redirects");
String location = urlConnection.getHeaderField("Location");
URL base = new URL(requestURL);
URL next = new URL(base, location); // Deal with relative URLs
requestURL = next.toExternalForm();
continue;
}
break;
}
// if OK
if(responseCode == HttpsURLConnection.HTTP_OK) {
httpUrlConnection.setReadTimeout(aMilliSecondTimeout);
// (GWN: 2010-05-12): We get the encoding returned by the server and then flip the inputstream accordingly
// If the server does not support gzip/deflate, encoding will be NULL
String encoding = httpUrlConnection.getContentEncoding();
InputStream receiving = null;
// get the file....
}
} catch(Exception e) {
Trace.Log(Trace.MEDIUM, "Download of '" + aURL + "' failed with error=" + e.getMessage());
}
}
/**
*
*/
package com.test;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
/**
*
* During handshaking, if the URL's hostname and the server's identification hostname mismatch, the verification mechanism can call back to implementers
* of this interface to determine if this connection should be allowed.
*
* This allows us to treat some incorrectly configured HTTPS / SNI target servers as valid.
*
* @see javax.net.ssl.HttpsURLConnection#setHostnameVerifier(HostnameVerifier)
In the past we used to pass into the JVM runtime the option "-Djsse.enableSNIExtension=false" which would disable SNI extensions completely, bypassing any handshake checks. With the rewrite of Tradefeeds, this is now problematic, as the setting would apply to all threads executing.
* @author GNaschenweng
*/
public class SSLSkipSNIHostnameVerifier implements HostnameVerifier {
/**
*
*/
public SSLSkipSNIHostnameVerifier() {
}
/*
* We always treat SNI issues as valid. This should only be used in valid and verified cases and not set as the default host name-verifier for all connections
* (non-Javadoc)
* @see javax.net.ssl.HostnameVerifier#verify(java.lang.String, javax.net.ssl.SSLSession)
*/
@Override
public boolean verify (String hostname, SSLSession session) {
// Return true so that we implicitly trust hostname mismatch
return true;
}
}
@magicdude4eva
Copy link
Author

magicdude4eva commented Dec 31, 2017

Donations are always welcome

🍺 Please support me: If the above helped you in any way, then follow me on Twitter or send me some coins:

(CRO)    cro1w2kvwrzp23aq54n3amwav4yy4a9ahq2kz2wtmj (Memo: 644996249) or 0xb83c3Fe378F5224fAdD7a0f8a7dD33a6C96C422C (Cronos)
(USDC)   0xb83c3Fe378F5224fAdD7a0f8a7dD33a6C96C422C
(BTC)    3628nqihXvw2RXsKtTR36dN6WvYzaHyr52
(ETH)    0xb83c3Fe378F5224fAdD7a0f8a7dD33a6C96C422C
(BAT)    0xb83c3Fe378F5224fAdD7a0f8a7dD33a6C96C422C
(LTC)    MQxRAfhVU84KDVUqnZ5eV9MGyyaBEcQeDf
(Ripple) rKV8HEL3vLc6q9waTiJcewdRdSFyx67QFb (Tag: 1172047832)
(XLM)    GB67TJFJO3GUA432EJ4JTODHFYSBTM44P4XQCDOFTXJNNPV2UKUJYVBF (Memo ID: 1406379394)

Go to Curve.com to add your Crypto.com card to ApplePay and signup to Crypto.com for a staking and free Crypto debit card.

Use Binance Exchange to trade #altcoins. Sign up with Coinbase and instantly get $10 in BTC. I also accept old-school PayPal.

If you have no crypto, follow me at least on Twitter.

@ddsky
Copy link

ddsky commented Jun 25, 2018

This code is not working for me. After debugging deep into the apache lib, I can see that the verifyHostName method is called AFTER sslsock.startHandshake(); and therefore the HostNameVerifier is never checked.

@arcifius
Copy link

arcifius commented May 18, 2020

newer versions of java won't work with that code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment