2016-08-09 2 views
0

Мне нужно интегрировать приложение с внешним веб-сервисом, которое вынуждает использовать https. Авторы этого веб-сервиса предоставили мне файл .crt, который я должен использовать для создания https-запросов. После некоторого исследования я нашел следующий код, который использует класс KeyStore для безопасного доступа по протоколу HTTPS:с помощью KeyStore с .crt

 KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
     FileInputStream instream = new FileInputStream(new File(file)); 
     try { 
      trustStore.load(instream, password.toCharArray()); 
     } finally { 
      instream.close(); 
     } 

     SSLContext sslcontext = 
       SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build(); 
     SSLConnectionSocketFactory sslsf = 
       new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1.2"}, null, 
               BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); 
     HttpClients.custom().setSSLSocketFactory(sslsf).build(); 

В этом коде KeyStore требует входного потока вместе с паролемtrustStore.load(instream, password.toCharArray());. Однако, как я понимаю, нам не нужен пароль при использовании .crt-файла. Поэтому этот способ загрузки сертификата мне не подходит. В то же время, из того, что я обнаружил до сих пор, приведенный здесь код является единственным способом настройки HttpClient для использования сертификата SSL. Существует ли какое-либо решение для настройки HttpClient для использования сертификата .crt?

Спасибо,

Андрей

ответ

1

Я предполагаю, что веб-сервис предоставляет вам самоподписанный сертификат (т.е. не подписан известный CA). Если он уже подписан известным CA, который находится в файле cacerts от Java, вам не нужно ничего делать.

В противном случае, у вас есть несколько вариантов:

  1. Импорт сертификата в глобальные cacerts KeyStore
  2. Запуск приложения с приложением конкретных хранилища ключей

В любом случае, вам в первую очередь необходимо для преобразования файла crt в jks keystore, который использует Java. Вы можете сделать это:

$ keytool -import -keystore mykeystore.jks -storepass horsestaple 

Обратите внимание, что Keytool требует пароль (horsestaple выше), подаваемой для создания JKS магазина. Вы можете положить что-нибудь там; как вы упомянули, общедоступные сертификаты веб-сайтов не нуждаются в защите паролем, они все-таки публичны.

Если вы делаете вариант 1, сделайте резервную копию своих cacerts и поставьте файл cacerts вместо mykeystore.jks. См. Ссылку ниже для местоположения cacerts. Для этой опции вы все настроены, ваше приложение должно подключаться к веб-службе через HTTPS без какой-либо дополнительной настройки, так как Java загружает cacerts по умолчанию.

Если вы делаете вариант 2, который, вероятно, предпочтительно, по меньшей мере, на этапе тестирования, вам необходимо запустить приложение с помощью этого параметра:

-Djavax.net.ssl.trustStore=mykeystore.jks 

Это параметр JVM, поэтому поставить его соответствующим образом. Это зависит от того, как вы используете приложение.

Обратите внимание, что в этом случае у вас будет только импортированный сертификат, поэтому ваши другие соединения HTTPS не будут работать. Вы можете избежать этого, предварительно скопировав стандартные кацеты во временное место, импортировав в него ключ и используя это в приведенной выше команде. Это даст вам все стандартные сертификаты, плюс тот, который вам нужен.

Небольшой недостаток варианта 2 заключается в том, что если новые сертификаты будут добавлены или отменены, ваше хранилище ключей приложения не будет обновлено.Если это является проблемой, вы можете объединить хранилища ключей на лету, например:

В любом случае, теперь вы должны быть в состоянии просто принести стандартный URL, например, в пример, приведенный здесь:

т.е.

final URL url = new URL("https://example.com"); 
try(final InputStream in = url.openStream()){ 
    //… 
} 

Более подробная информация здесь:

  • Keytool и общие сертификаты Информация

https://docs.oracle.com/cd/E19830-01/819-4712/ablqw/index.html

  • Cacerts расположение

http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/keytool.html

  • Других вариантов для импорта самозаверенных сертификатов

How to properly import a selfsigned certificate into Java keystore that is available to all Java applications by default?

Надеется, что это помогает.

+0

Третьим вариантом является использование доверительного хранилища напрямую с API-интерфейсом клиента, что, по-видимому, выглядит как OP. Это лучше, чем любой из двух вариантов, которые вы изначально представляли, поскольку это не мешает никакому другому использованию хранилищ доверия. –

+0

@ ChristopherSchultz Согласен, если OP хочет использовать оригинальное решение, конечно, конечно. Я предполагаю, что это зависит от варианта использования, если он распространяется по нескольким приложениям, может быть проще обновить глобальные cacerts. –

0

Если они не предоставили вам свой файл .crt, которые должны быть использованы для проверки соединений к их, что означало бы, что они используют самостоятельно подписанный сертификат, они не предоставили вам что-нибудь полезное , Если вам нужен сертификат как клиент, первое, что вам нужно, это пара открытого/закрытого ключа, из которого вы создаете CSR, который вы подписываете. Никто другой не может безопасно предоставить любой из них, кроме подписанного сертификата.

Если они представили свой собственный (самоподписанный?) Сертификат, вы должны загрузить его в доверенных сертификатов, а не хранилище ключей, через keytool с опцией -trustcacerts, а затем сказать Java, чтобы использовать эти доверенные сертификаты , либо через системное свойство javax.net.ssl.trustStore, либо путем создания собственного TrustManager и подачи его на заказ SSLContext, как описано в Справочном руководстве JSSE.

Смежные вопросы