javax.net.ssl.SSLException: java.security.InvalidAlgorithmParameterException: параметр trustAnchors должен быть непустым

Я пытаюсь проанализировать файл XML, который ежедневно обновляет указанный файл. Единственная проблема, с которой я столкнулся, заключается в том, что они используют свой собственный сертификат (https://...), и я не могу использовать этот конкретный URL-адрес, а также нет доступной ссылки http://....

URL url = new URL("https://...");
...
Document document = db.parse(url.openStream());

Этот код выдает следующее исключение при выполнении моих тестов:

javax.net.ssl.SSLException: java.lang.RuntimeException: непредвиденная ошибка: java.security.InvalidAlgorithmParameterException: параметр trustAnchors должен быть непустым

Я видел множество предложений, связанных с созданием различных классов для работы с этим типом соединения или с персональным сервером, а также с добавлением сертификата в хранилище ключей, а затем добавлением этого хранилища ключей в проект Java, но я был не могу этого сделать, и я ищу более простой способ получить доступ к XML в Интернете.


person Acetaminophen    schedule 04.12.2011    source источник
comment
Похоже, вы изменили настройки хранилища доверенных сертификатов, чтобы не использовать настройки по умолчанию. Что вы изменили?   -  person Bruno    schedule 05.12.2011
comment
Это привело к удалению хранилища доверия по умолчанию, поэтому вы получили пустой параметр trustAnchors. Всегда должно быть непустое хранилище доверия.   -  person Bruno    schedule 05.12.2011
comment
См. этот Как ответить[1]. Короче говоря, хранилище ключей не может быть найдено. [1]: stackoverflow.com/a/6788682/207131   -  person FabienB    schedule 12.12.2012
comment
Возможный дубликат Ошибка — параметр trustAnchors должен быть непустым   -  person Jakub Kukul    schedule 01.08.2016


Ответы (4)


Вам нужно хранилище доверенных сертификатов для хранения SSL-сертификатов. Вы можете загрузить сертификат с помощью предпочитаемого веб-браузера. Чтобы загрузить сертификат в хранилище доверенных сертификатов, вам понадобится программа «keytool», которая поставляется с JDK.

Например, если ваш файл сертификата называется «certificate.crt» и вы хотите создать хранилище доверенных сертификатов с именем «secure.ts», вы можете вызвать keytool следующим образом:

keytool -importcert -keystore secure.ts -storepass S3cuR3pas$! -file certificate.crt

Теперь вы должны сообщить своей программе, где находится хранилище ключей, и пароль для его открытия, определив системные свойства "javax.net.ssl.trustStore" и "javax.net.ssl.trustStorePassword" перед открытием. связь

URL url = new URL("https://...");

System.setProperty("javax.net.ssl.trustStore", "secure.ts");
System.setProperty("javax.net.ssl.trustStorePassword", "S3cuR3pas$!");
...
Document document = db.parse(url.openStream());
person Errepunto    schedule 17.09.2013

Это любопытное сообщение означает, что хранилище доверенных сертификатов не найдено.

Ничего общего с XML BTW.

person user207421    schedule 04.12.2011
comment
@Acetaminophen См. Javadoc: Справочное руководство по безопасности/JSSE. - person user207421; 05.12.2011
comment
Я переименовал ‹java-home›/lib/security/cacerts в ‹java-home›/lib/security/cacerts_orig ранее, пытаясь добавить сертификат, который у меня есть, в хранилище ключей — я исправил это и теперь получаю следующее ошибка: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: сбой построения пути PKIX: sun.security.provider.certpath.SunCertPathBuilderException: невозможно найти действительный путь сертификации к запрошенной цели - person Acetaminophen; 05.12.2011
comment
@Acetaminophen, поэтому ваше хранилище доверенных сертификатов не доверяет сертификату сервера. Так что это, вероятно, самоподписанный. Вам нужно импортировать его в свои cacerts или, что более вероятно, скопировать ваши cacerts в локальное хранилище доверенных сертификатов, импортировать в него сертификат сервера и использовать его в качестве хранилища доверенных сертификатов. См. forums.oracle.com/forums/ для возможных импортное решение. Лучшее решение — заставить сервер использовать сертификат, подписанный ЦС. - person user207421; 05.12.2011
comment
У меня есть сертификат с сайта в папке lib/security/ - я просмотрел InstallCert.java, но у меня возникли некоторые проблемы с его использованием при его компиляции, и у меня также возникла ошибка предварительной компиляции с InstallCertJFrame.java. Сертификат, с которым я имею дело, получен из университета, в который я хожу, и они (насколько мне известно) подписаны центром сертификации. - person Acetaminophen; 05.12.2011
comment
Я также видел предложения полностью отключить проверку сертификации, с чем я тоже согласен, хотя я бы предпочел не просто использовать весь код примера, если нет необходимости отключать процесс проверки. - person Acetaminophen; 05.12.2011
comment
@Acetaminophen (а) Какие проблемы? Он компилируется и выполняется нормально для меня. (b) Я никогда не понимал энтузиазма по поводу отключения проверки сертификатов. Если вы не хотите, чтобы это было безопасно, зачем вообще использовать SSL? (c) размещение сертификатов в lib/security ничего не дает. - person user207421; 05.12.2011
comment
а) различные проблемы с форматированием, которые не нравятся Eclipse, б) потому что это веб-сайт, управляемый университетом, с которого мы анализируем данные для использования в приложении Android - у меня нет предпочтений относительно того, является ли это SSL или нет, просто пока я могу анализировать данные из ссылки вместо того, чтобы сохранять их как локальный файл для демонстрации. - person Acetaminophen; 05.12.2011
comment
Также снова попробовал InstallCertJFrame, и он заработал - единственная проблема заключается в том, что он выдает ошибку (исключение в потоке AWT-EventQueue-0 java.lang.NumberFormatException: || или UnknownHostException без https:// перед ссылкой) при попытке импорта из сайт (https://.../file.xml), к которому я обращаюсь. - person Acetaminophen; 05.12.2011
comment
@Acetaminophen, до сих пор ваша проблема не имела ничего общего с XML (@EJP правильно повторно пометил ваш вопрос). Теперь, UnknownHostException: я не уверен, почему вы удалили https:// перед ссылкой. NumberFormatException: это может быть связано с обработкой вашего XML-документа на каком-то этапе. Вероятно, это следует решить в другом вопросе, поскольку сейчас это не имеет ничего общего с SSL. - person Bruno; 05.12.2011
comment
@Acetaminophen Вы не можете убедить меня, что «проблемы с форматированием Eclipse» помешали вам выполнить этот код. - person user207421; 06.12.2011

Вы можете попробовать с этим:

String javaHomePath = System.getProperty("java.home");
String keystore = javaHomePath + "/lib/security/cacerts";
String storepass= "changeit";
String storetype= "JKS";

String[][] props = {
    { "javax.net.ssl.trustStore", keystore, },
    { "javax.net.ssl.keyStore", keystore, },
    { "javax.net.ssl.keyStorePassword", storepass, },
    { "javax.net.ssl.keyStoreType", storetype, },
};
for (int i = 0; i < props.length; i++) {
    System.getProperties().setProperty(props[i][0], props[i][1]);
}
// Now you can proceed to connect to call the webservice.
// SSL will be used automatically if the service endpoint url 
// starts with <a href="https://." target="_blank"         rel="nofollow">https://.</a>
// The server will send its certificate signed by verisign and 
// client will trust and authenticate the server as it recognizes 
// verisign as one trusted root.
person atiruz    schedule 30.12.2015

Я столкнулся с тем же исключением для своего MAC OSX (Yosemite) при разработке приложений Java 6. Вам необходимо загрузить и установить Apple Java для OSX 2014:

http://support.apple.com/kb/DL1572

person MasterV    schedule 04.01.2015