java.security.InvalidAlgorithmParameterException: параметр trustAnchors должен быть непустым в Linux, или почему хранилище доверенных сертификатов по умолчанию пусто
Когда вы Google для этого исключения: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
появятся несколько результатов. Однако нет окончательного решения, только догадки.
Проблема возникает (по крайней мере, в моем случае), когда я пытаюсь использовать открытое соединение через SSL. Он отлично работает на моем компьютере с Windows, но когда я развернул его на компьютере с Linux (с установленным Sun jre), он выходит из строя с вышеуказанным исключением.
Проблема в том, что хранилище доверенных сертификатов JRE по умолчанию по какой-то причине пусто (размер всего 32 байта, тогда как в Windows оно составляет 80 КБ).
Когда я скопировал мой jre/lib/security/cacerts
файл из windows в linux, все работало нормально.
Вопрос в том, почему у linux jre пустое хранилище доверия?
Обратите внимание, что это происходит в экземпляре Amazon EC2 с Linux AMI, так что это может быть связано с некоторыми политиками Amazon (я думаю, что Java был предварительно установлен, но я не уверен)
13 ответов
Стандартный Sun JDK для linux имеет абсолютно нормальные cacerts и все файлы в указанном каталоге. Проблема в установке, которую вы используете.
Я получил эту ошибку в Ubuntu. Я увидел, что /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/cacerts была неработающей ссылкой на / etc / ssl / certs / java / cacerts. Это привело меня к этой ошибке: https://bugs.launchpad.net/ubuntu/+source/ca-certificates-java/+bug/983302 README для ca-Certificates-java в конечном итоге показал фактическое исправление:
бежать
update-ca-certificates -f
apt-get install ca-Certificates-Java не работает для меня. Он просто помечен как установленный вручную.
Я избежал этой ошибки (Java 1.6.0 на OSX 10.5.8), поместив фиктивный сертификат в хранилище ключей, например
keytool -genkey -alias foo -keystore cacerts -dname cn=test -storepass changeit -keypass changeit
Конечно, вопрос должен быть: "Почему java не может обрабатывать пустой trustStore?"
Я могу создать эту ошибку, установив системное свойство trustStore в отсутствующий файл JKS. Например
System.setProperty("javax.net.ssl.keyStore", "C:/keystoreFile.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "mypassword");
System.setProperty("javax.net.ssl.trustStore", "C:/missing-keystore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "mypassword");
Этот код по какой-то причине не генерирует исключение FileNotFound, а именно исключение InvalidAlgorithmParameter, указанное выше.
Вид глупого ответа, но я могу воспроизвести.
Была такая же проблема на Ubuntu 14.10 с установленным java-8-oracle.
Решена установка пакета ca-certificate-java:
sudo apt-get install ca-certificates-java
Не ответ на первоначальный вопрос, но, пытаясь решить подобную проблему, я обнаружил, что обновление Macver X для Maverics испортило установку Java (фактически, cacert). Удалить sudo rm -rf /Library/Java/JavaVirtualMachines/*.jdk
и переустановите с http://www.oracle.com/technetwork/java/javase/downloads/index.html
Мое решение в Windows состояло в том, чтобы либо запустить окно консоли в качестве администратора, либо изменить переменную среды MAVEN_OPTS, чтобы использовать жестко заданный путь к trust.jks (например, "C:\Users\oddros") вместо "%USERPROFILE%". Мой MAVEN_OPTS теперь выглядит так:
-Djavax.net.ssl.trustStore=C:\Users\oddros\trust.jks -Djavax.net.ssl.trustStorePassword=changeit
Мой файл cacerts был полностью пуст. Я решил эту проблему, скопировав файл cacerts с моего компьютера с Windows (который использует Oracle Java 7) и скопировал его в мой Linux-пакет (OpenJDK).
cd %JAVA_HOME%/jre/lib/security/
scp cacerts mylinuxmachin:/tmp
а затем на машине Linux
cp /tmp/cacerts /etc/ssl/certs/java/cacerts
Пока все отлично работает.
Если это случается с вами при установке OpenJDK в Mac OS X (в отличие от Linux), и у вас есть официальная Mac OS X Java (то есть последняя версия Java 6), установленная через Software Update, вы можете просто сделать это:
cd $OPENJDK_HOME/Contents/Home/jre/lib/security
ln -s /System/Library/Java/Support/CoreDeploy.bundle/Contents/Home/lib/security/cacerts
ln -s /System/Library/Java/Support/Deploy.bundle/Contents/Home/lib/security/blacklist
ln -s /System/Library/Java/Support/Deploy.bundle/Contents/Home/lib/security/trusted.libraries
где $OPENJDK_HOME
является корневым каталогом вашей установки OpenJDK, обычно OPENJDK_HOME=/Library/Java/JavaVirtualMachines/1.7.0u.jdk
, Это идентично тому, как официальные установки Java в Mac OS X получают эти файлы - они также просто символически связывают их из этих системных пакетов. Работает на Lion, не уверен в более ранних версиях ОС.
Убедитесь, что в JRE/security у вас есть действительные cacerts, иначе вы не сможете обойти недопустимую пустую ошибку trustAnchors.
В моей установке Amazon EC2 Opensuse12 проблема заключалась в том, что файл, указанный cacerts в каталоге безопасности JRE, был неверным:
$ java -version
java version "1.7.0_09"
OpenJDK Runtime Environment (IcedTea7 2.3.4) (suse-3.20.1-x86_64)
OpenJDK 64-Bit Server VM (build 23.2-b09, mixed mode)
$ ls -l /var/lib/ca-certificates/
-rw-r--r-- 1 root 363 Feb 28 14:17 ca-bundle.pem
$ ls -l /usr/lib64/jvm/jre/lib/security/
lrwxrwxrwx 1 root 37 Mar 21 00:16 cacerts -> /var/lib/ca-certificates/java-cacerts
-rw-r--r-- 1 root 2254 Jan 18 16:50 java.policy
-rw-r--r-- 1 root 15374 Jan 18 16:50 java.security
-rw-r--r-- 1 root 88 Jan 18 17:34 nss.cfg
Поэтому я решил установить старые действующие сертификаты Opensuse 11. (Извини за это!!)
$ ll
total 616
-rw-r--r-- 1 root 220065 Jan 31 15:48 ca-bundle.pem
-rw-r--r-- 1 root 363 Feb 28 14:17 ca-bundle.pem.old
-rw-r--r-- 1 root 161555 Jan 31 15:48 java-cacerts
Я понял, что вы можете использовать keytool для создания нового ( http://mail.openjdk.java.net/pipermail/distro-pkg-dev/2010-April/008961.html). Наверное, скоро мне придётся.
С уважением, Леллис
Я получаю ту же ошибку на своем компьютере с Windows 7, когда права доступа к файлу cacerts в моей папке C:\Program Files\Java\jdk1.7.0_51\jre\lib\security установлены неправильно.
Чтобы разрешить эту проблему, я разрешаю пользователям SERVICE и INTERACTIVE иметь все разрешения на изменение в каскадах, кроме "изменить разрешения" и "стать владельцем" (из расширенных настроек в свойствах безопасности). Я предполагаю, что разрешение этим службам читать и записывать расширенные атрибуты может иметь отношение к исчезновению ошибки.
Есть такая же проблема. Решил это, установив пакет сертификатов ca от Mozilla:
$ zypper in ca-certificates-mozilla
The following NEW package is going to be installed:
ca-certificates-mozilla
1 new package to install.
Retrieving package ca-certificates-mozilla-1.85-8.8.1.noarch
(1/1), 143.7 KiB (239.1 KiB unpacked)
Retrieving: ca-certificates-mozilla-1.85-8.8.1.noarch.rpm.....................[done]
Installing: ca-certificates-mozilla-1.85-8.8.1 ...............................[done]
Additional rpm output:
Updating certificates in /etc/ssl/certs...
144 added, 0 removed.
creating /var/lib/ca-certificates/ca-bundle.pem ...
creating /var/lib/ca-certificates/java-cacerts ...
144 added, 0 removed.
$ ll /var/lib/ca-certificates/
total 392
drwxr-xr-x 2 root root 4096 Apr 26 07:25 ./
drwxr-xr-x 30 root root 4096 Apr 25 15:00 ../
-rw-r--r-- 1 root root 220196 Apr 26 07:25 ca-bundle.pem
-rw-r--r-- 1 root root 161555 Apr 26 07:25 java-cacerts
PS
$ cat /etc/SuSE-release
openSUSE 12.2 (x86_64)
VERSION = 12.2
CODENAME = Mantis
$ java -version
java version "1.7.0_09"
OpenJDK Runtime Environment (IcedTea7 2.3.4) (suse-3.20.1-x86_64)
OpenJDK 64-Bit Server VM (build 23.2-b09, mixed mode)
Это происходит потому, что права доступа различаются в разных ОС. Иерархия доступа к Windows отличается от Unix. Однако это можно преодолеть, выполнив следующие простые шаги:
- Увеличьте доступность с
AccessController.doPrivileged(java.security.PrivilegedAction subclass)
- Установите свой собственный
java.security.Provider
подкласс как свойство безопасности. а. Security.insertProviderAt(new, 2); - Установите свой Алгоритм с
Security.setProperty("ssl.TrustManagerFactory.algorithm" , “XTrust509”);