MongoDB ssl в java работает только с промежуточным сертификатом

Я использую MongoDB 2.6.3 с подключением SSL.
Я не использую проверку клиента, а конфигурация SSL следующая:

sslMode = requireSSL
sslPEMKeyFile = /path/to/MyServerCertificate.pem

Сертификат, который я использую, подписан и выдан моему серверу ЦС, у которого есть корневой ЦС, например:
RootCA ---> SignerCA ---> MyServerCertificate

Проблема в следующем: я пытаюсь подключиться через java, указав хранилище доверия с только SignerCA, и все работает нормально. Но когда я указываю хранилище доверия с только RootCA, я получаю:

com.mongodb.MongoServerSelectionException: невозможно подключиться к любому серверу

В журнале монго я вижу:

ОШИБКА: SSL: ошибка: 14094416: процедуры SSL: SSL3_READ_BYTES: сертификат предупреждения sslv3 неизвестен


Мой Java-код:

Builder options = MongoClientOptions.builder();

KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("path/to/keystore"), "pass".toCharArray());

TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(ks);

SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustFactory.getTrustManagers(), null);

options.socketFactory(sc.getSocketFactory());
new MongoClient("loclahost", options.build());

Когда хранилище ключей, которое я использую, содержит только RootCA, я не могу подключиться по какой-то причине...
Буду рад предложениям. Спасибо.


person matanper    schedule 01.01.2015    source источник
comment
Можете ли вы предоставить параметры запуска сервера MongoDB, которые вы используете — например, указали ли вы SSLCAFile в конфигурации вашего сервера? (Клиент проверяет сервер, но не наоборот: просто удостоверяясь, что это именно то поведение, которое вы намерены использовать.) Кроме того, загрузили ли вы и файл корневого ЦС, и подписывающий ЦС в хранилище ключей? (Я не знаком с Java TrustManager API, но меня беспокоит, что он не знает о связи между подписывающим центром сертификации и корневым центром сертификации.) Является ли корневой центр сертификации KeyStore.TrustedCertificateEntry? Кроме того, просто чтобы уточнить, является ли loclahost опечаткой в ​​этом посте или в вашем коде?   -  person Amalia    schedule 09.01.2015
comment
Спасибо за комментарий. Как вы можете видеть в начале поста, это конфигурация без файла CA, потому что я хочу только проверку клиента, а не проверку сервера. localhost - опечатка, я использую RHLE 6.2 для своих удаленных серверов mongo. Если у меня есть подписанный ЦС в хранилище ключей, соединение устанавливается нормально, и если я добавляю в то же хранилище ключей корневой ЦС, он все еще работает (это не влияет). Проблема в том, что хранилище ключей содержит только корневой ЦС. Если TrustManager не знает, как сделать ссылку, разве это не противоречит принципам сертификатов?   -  person matanper    schedule 10.01.2015


Ответы (1)


Проблема, которую вы видите, заключается в том, что TrustManager не может установить связь между вашим сертификатом, ЦС подписавшего и корневым ЦС. Поскольку ваш сертификат содержит только ссылку на подписывающий ЦС, что касается TrustManager, между сертификатом и корневым ЦС нет связи. Вам необходимо предоставить подписывающий ЦС, чтобы показать, что существует ссылка на доверенный орган.

Чтобы использовать персонифицированный пример, давайте представим, что Алиса ищет работу в Security Corp. У Алисы есть рекомендация (подписанный сертификат) Боба, которого, в свою очередь, рекомендует (подписал) Чарли. Если Служба безопасности имеет доступ только к рекомендации (подписи) Алисы Боба, а Служба безопасности доверяет Чарли, но не знает, кто такой Боб, у них нет причин доверять Алисе. Корпорации безопасности нужен доступ к рекомендациям Чарли о Бобе, чтобы она могла доверять рекомендации Боба об Алисе.

Надеюсь это имеет смысл!

person Amalia    schedule 22.01.2015