Одной из распространенных проблем, с которой могут столкнуться разработчики на Java, является исключение sun.security.provider.certpath.SunCertPathBuilderException
. Это исключение обычно возникает при попытке установить защищенное SSL-соединение с сервером, когда на стороне клиента отсутствует доверительный магазин сертификатов (truststore), содержащий требуемые сертификаты для установления доверия к серверу.
Представим себе ситуацию, когда необходимо скачать файл с сервера по протоколу HTTPS. Для этого создается клиент, который устанавливает соединение с сервером и отправляет запрос на скачивание файла. Если в этом случае на стороне клиента не установлены необходимые для подключения сертификаты, то будет выброшено исключение sun.security.provider.certpath.SunCertPathBuilderException
.
import java.io.FileOutputStream; import java.io.IOException; import java.nio.CharBuffer; import java.util.concurrent.Future; import org.apache.http.HttpResponse; import org.apache.http.client.utils.URIUtils; import org.apache.http.impl.nio.client.DefaultHttpAsyncClient; import org.apache.http.nio.IOControl; import org.apache.http.nio.client.HttpAsyncClient; import org.apache.http.nio.client.methods.AsyncCharConsumer; import org.apache.http.nio.client.methods.HttpAsyncGet; import org.apache.http.nio.client.methods.HttpAsyncPost; public class DownloadFile { static FileOutputStream fos; public void DownloadFile(String URI, String Request) throws Exception { java.net.URI uri = URIUtils.createURI("https", "example.com", -1, "download.aspx", "Lang=EN&AuthToken=package", null); HttpAsyncClient httpclient = new DefaultHttpAsyncClient(); httpclient.start(); try { Future<Boolean> future = httpclient.execute( new HttpAsyncGet(uri), new ResponseCallback(), null); Boolean result = future.get(); if (result != null && result.booleanValue()) { System.out.println("Request successfully executed"); } else { System.out.println("Request failed"); } } catch(Exception e){ System.out.println("[DownloadFile] Exception: " + e.getMessage()); } finally { httpclient.shutdown(); } } }
Важно отметить, что игнорирование этого исключения не является рекомендуемым решением, так как это может привести к уязвимостям в безопасности. Вместо этого рекомендуется добавить требуемые сертификаты в доверительный магазин сертификатов на стороне клиента.
Для этого можно использовать утилиту keytool, входящую в состав JDK. Сначала необходимо экспортировать сертификат из сервера, а затем импортировать его в доверительный магазин на стороне клиента.
Экспорт сертификата с сервера:
openssl s_client -connect example.com:443 </dev/null | openssl x509 -out server.crt
Импорт сертификата в доверительный магазин:
keytool -import -alias example -keystore truststore.jks -file server.crt
После этого приложение должно иметь возможность установить защищенное соединение с сервером без выбрасывания исключения sun.security.provider.certpath.SunCertPathBuilderException
.
Добавить комментарий