Как использовать файл в банке как javax.net.ssl.keystore?

Я пытаюсь сделать что-то вроде

URL clientks = com.messaging.SubscriptionManager.class.getResource( "client.ks" );
String path = clientks.toURI().getPath();
System.setProperty( "javax.net.ssl.keyStore", path);

Где client.ks - это файл, хранящийся в com / messaging в файле jar, который я запускаю.

То, что читает javax.net.ssl.keyStore, ожидает путь к файлу client.ks, который находится в банке. Я бы предпочел не извлекать файл и не загружать его на клиентскую машину, если это возможно. Так можно ли ссылаться на файл в банке?

Это не работает, поскольку getPath () возвращает null. Есть другой способ сделать это?

Название вводит в заблуждение. Похоже, вы спрашиваете, можете ли вы получить ссылку File на ресурс в файле jar; вызов System.setProperty не имеет значения.

Jason Day 05.12.2008 21:50
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
18
1
17 989
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете получить InputStream для ресурса в файле jar, но не File. Если «вещь», которая в конечном итоге читает хранилище ключей, ожидает File или путь к файлу, ваш единственный вариант - извлечь его в файловую систему.

Хорошо спасибо! Тем временем я этим занимался, и это прекрасно работает; это просто не так чисто.

darrickc 05.12.2008 22:05
Ответ принят как подходящий

Все еще работаю над реализацией, но я считаю, что можно загрузить хранилище ключей из банки через InputStream и явно программно установить TrustStore (вместо настройки свойств системы). См. Статью: Установка нескольких доверенных хранилищ на одной JVM

Все заработало!

InputStream keystoreInput = Thread.currentThread().getContextClassLoader()
    .getResourceAsStream(<path in jar>/client.ks");
InputStream truststoreInput = Thread.currentThread().getContextClassLoader()
    .getResourceAsStream(<path in jar>/client.ts");
setSSLFactories(keystoreInput, "password", truststoreInput);
keystoreInput.close();
truststoreInput.close();

private static void setSSLFactories(InputStream keyStream, String keyStorePassword, 
    InputStream trustStream) throws Exception
{    
  // Get keyStore
  KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());    

  // if your store is password protected then declare it (it can be null however)
  char[] keyPassword = keyStorePassword.toCharArray();

  // load the stream to your store
  keyStore.load(keyStream, keyPassword);

  // initialize a key manager factory with the key store
  KeyManagerFactory keyFactory = 
  KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());    
  keyFactory.init(keyStore, keyPassword);

  // get the key managers from the factory
  KeyManager[] keyManagers = keyFactory.getKeyManagers();

  // Now get trustStore
  KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());    

  // if your store is password protected then declare it (it can be null however)
  //char[] trustPassword = password.toCharArray();

  // load the stream to your store
  trustStore.load(trustStream, null);

  // initialize a trust manager factory with the trusted store
  TrustManagerFactory trustFactory = 
  TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());    
  trustFactory.init(trustStore);

  // get the trust managers from the factory
  TrustManager[] trustManagers = trustFactory.getTrustManagers();

  // initialize an ssl context to use these managers and set as default
  SSLContext sslContext = SSLContext.getInstance("SSL");
  sslContext.init(keyManagers, trustManagers, null);
  SSLContext.setDefault(sslContext);    
}

Спасибо! Некоторое время я искал решение, и все остальное, что я видел, выглядело чертовски сложно :)

jeremija 12.09.2014 18:41

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

muttonUp 15.09.2016 14:25

Я добавил новый параметр «String keyPassphrase» и изменил строку на keyFactory.init (keyStore, keyPassphrase.toCharArray ());

muttonUp 15.09.2016 14:26

Вот очищенная версия user2529737 ответ, на случай, если это поможет. Он удалил ненужную настройку хранилища доверенных сертификатов и добавил требуемый импорт, параметры для типа хранилища ключей и пароля ключа.

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.security.KeyStore;

public class PlainJavaHTTPS2Test {

    public void setUp() throws Exception {
        final String KEYSTOREPATH = "clientkeystore.p12"; // or .jks

        // store password can be null if there is no password
        final char[] KEYSTOREPASS = "keystorepass".toCharArray();

        // key password can be null if there is no password
        final char[] KEYPASS = "keypass".toCharArray();

        try (InputStream storeStream = this.getClass().getResourceAsStream(KEYSTOREPATH)) {
            setSSLFactories(storeStream, "PKCS12", KEYSTOREPASS, KEYPASS);
        }
    }
    private static void setSSLFactories(InputStream keyStream, String keystoreType, char[] keyStorePassword, char[] keyPassword) throws Exception
    {
        KeyStore keyStore = KeyStore.getInstance(keystoreType);

        keyStore.load(keyStream, keyStorePassword);

        KeyManagerFactory keyFactory =
                KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());

        keyFactory.init(keyStore, keyPassword);

        KeyManager[] keyManagers = keyFactory.getKeyManagers();

        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(keyManagers, null, null);
        SSLContext.setDefault(sslContext);
    }
}

(Я подумал, должен ли я дать этот собственный ответ или нет, но, прочитав это, я решил оставить его как собственный)

eis 01.02.2018 11:13

Другие вопросы по теме