Как Импортировать Сертификат В Java?

Getcertificates()

Получив экземпляр CertPath, вы можете получить экземпляры Certificate, из которых состоит CertPath, вызвав метод getCertificates(). Вот пример получения сертификатов из экземпляра CertPath:

List<Certificate> certificates = certPath.getCertificates();

Getencoded()

Метод getEncoded() сертификата возвращает закодированную версию сертификата в виде байтового массива. Например, если сертификат является сертификатом X509, возвращенный байтовый массив будет содержать версию экземпляра сертификата в кодировке X.590 (ASN.1 DER). Вот пример использования методаgetEncoded():

byte[] encodedCertificate = certificate.getEncoded();

Getpublickey()

Метод сертификата getPublicKey() возвращает открытый ключ этого экземпляра сертификата. Вот пример метода getPublicKey():

PublicKey certificatePublicKey = certificate.getPublicKey();

Gettype()

Метод getType() возвращает строку, указывающую, какой тип сертификатов (например, X.509) содержится в этом экземпляре CertPath. Вот пример получения типа CertPath через методом getType():

String type = certPath.getType();

Java certificatefactory (фабрика сертификатов

Класс CertificateFactory (java.security.cert.CertificateFactory) способен создавать экземпляры сертификата (Certificate) из двоичных данных сертификатов с кодировками X.509 (ASN.1 DER). CertificateFactory также может создавать экземпляры CertPath. CertPath — это цепочка сертификатов, где каждый сертификат подписан следующим сертификатом в данной цепочке.

Keystore & truststore

Говоря о JKS, стоит отметить, что данные файлы могут использоваться как KeyStore так и TrustStore. Это два различных типа хранилищ, которые находятся в JKS файлах. Одно из них (KeyStore) содержит более чувствительную информацию типа приватного ключа, и поэтому требует пароля для доступа к этой информации.

Но так же эти сертификаты идут в поставке Java в файле cacerts, который по умолчанию расположен в директории java.homelibsecurity и имеет пароль по умолчанию changeit.

Данная информация может быть полезна в тех случаях, когда установка JDK/JRE осуществляется в компании централизовано из одного источника, и имеется возможность добавления туда своих доверенных сертификатов компании для prod/uat окружения.

Ниже приведена таблица с некоторыми различиями KeyStore & TrustStore.

Verify()

Класс сертификата содержит три метода verify(). Эти методы могут использоваться для проверки того, что сертификат действительно подписан с закрытым ключом, соответствующим ожидаемому открытому ключу. Вот пример проверки сертификата:

// получение ожидаемого открытого ключа (не из сертификата!)
PublicKey expectedPublicKey = ... ;

try{
    certificate.verify(expectedPublicKey);

} catch (InvalidKeyException e) {
    // сертификат не был подписан данным открытым ключом

} catch (NoSuchAlgorithmException |
         NoSuchProviderException |
         SignatureException |
         CertificateException e){
    // что-то еще пошло не так
}

Метод verify() не возвращает значения. Если проверка не пройдена, будет выдано исключение InvalidKeyException. Если не сгенерировано исключение, экземпляр сертификата можно считать проверенным.

Как импортировать сертификат .cer в хранилище ключей java?

Во время разработки клиента веб-сервиса Java я столкнулся с проблемой. Аутентификация для веб-сервиса использует сертификат клиента, имя пользователя и пароль. Клиентский сертификат, полученный от компании за веб-сервисом, имеет .cerформат. Когда я проверяю файл с помощью текстового редактора, он имеет следующее содержимое:

-----BEGIN CERTIFICATE-----[Some base64 encoded data]-----END CERTIFICATE-----

Я могу импортировать этот файл в качестве сертификата в Internet Explorer (без необходимости ввода пароля!) И использовать его для аутентификации в веб-сервисе.

Про сертификаты:  К вопросу о правовой природе подарочных карт

Мне удалось импортировать этот сертификат в хранилище ключей, сначала обрезав первую и последнюю строку, преобразовав в unix новые строки и выполнив base64-декодирование. Полученный файл можно импортировать в хранилище ключей (используя keytoolкоманду). Когда я перечисляю записи в хранилище ключей, эта запись имеет тип trustedCertEntry. Из-за этого типа записи (?) Я не могу использовать этот сертификат для аутентификации в веб-сервисе. Я начинаю думать, что предоставленный сертификат является публичным сертификатом, который используется для аутентификации …

Обходной путь, который я нашел, состоит в том, чтобы импортировать сертификат в IE и экспортировать его как .pfxфайл. Этот файл может быть загружен как хранилище ключей и может использоваться для аутентификации с помощью веб-службы. Однако я не могу ожидать, что мои клиенты будут выполнять эти шаги каждый раз, когда они получают новый сертификат. Поэтому я хотел бы загрузить .cerфайл непосредственно в Java. Есть предположения?

Дополнительная информация: компания, стоящая за веб-сервисом, сказала мне, что сертификат следует запрашивать (используя IE и веб-сайт) с ПК и пользователя, который позже импортирует сертификат.

Как импортировать существующий сертификат x509 и закрытый ключ в хранилище ключей java для использования в ssl? | блог о программировании

в моем случае у меня был файл pem, который содержал два сертификата и зашифрованный закрытый ключ для использования во взаимной аутентификации SSL.
Так что мой PEM файл выглядел так:

-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,C8BF220FC76AA5F9
...
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

вот что я сделал:

разделить файл на три отдельных файла, так что каждый из них содержит только одну запись,
начиная с » — — — Начать..»и заканчивая» — — — конец..» русло. Предположим, что теперь у нас есть три файла: cert1.УГР cert2.Пем и ПКИ.Пем

конвертировать pkey.PEM в дер форматирование с использованием openssl и следующего синтаксиса:

openssl pkcs8 -topk8 -nocrypt -in pkey.pem -inform PEM -out pkey.der -outform DER

обратите внимание, что если закрытый ключ зашифрован, вам необходимо предоставить пароль( получить его от поставщика исходного файла pem )
для преобразования в формат DER,
openssl запросит у вас пароль следующим образом: «введите pass phraze для pkey.УГР: »
Если преобразование прошло успешно, вы получите новый файл с именем «pkey.дер»

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

String keypass = "password";  // this is a new password, you need to come up with to protect your java key store file
String defaultalias = "importkey";
KeyStore ks = KeyStore.getInstance("JKS", "SUN");

// this section does not make much sense to me, 
// but I will leave it intact as this is how it was in the original example I found on internet:   
ks.load( null, keypass.toCharArray());
ks.store( new FileOutputStream ( "mykeystore"  ), keypass.toCharArray());
ks.load( new FileInputStream ( "mykeystore" ),    keypass.toCharArray());
// end of section..


// read the key file from disk and create a PrivateKey

FileInputStream fis = new FileInputStream("pkey.der");
DataInputStream dis = new DataInputStream(fis);
byte[] bytes = new byte[dis.available()];
dis.readFully(bytes);
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);

byte[] key = new byte[bais.available()];
KeyFactory kf = KeyFactory.getInstance("RSA");
bais.read(key, 0, bais.available());
bais.close();

PKCS8EncodedKeySpec keysp = new PKCS8EncodedKeySpec ( key );
PrivateKey ff = kf.generatePrivate (keysp);


// read the certificates from the files and load them into the key store:

Collection  col_crt1 = CertificateFactory.getInstance("X509").generateCertificates(new FileInputStream("cert1.pem"));
Collection  col_crt2 = CertificateFactory.getInstance("X509").generateCertificates(new FileInputStream("cert2.pem"));

Certificate crt1 = (Certificate) col_crt1.iterator().next();
Certificate crt2 = (Certificate) col_crt2.iterator().next();
Certificate[] chain = new Certificate[] { crt1, crt2 };

String alias1 = ((X509Certificate) crt1).getSubjectX500Principal().getName();
String alias2 = ((X509Certificate) crt2).getSubjectX500Principal().getName();

ks.setCertificateEntry(alias1, crt1);
ks.setCertificateEntry(alias2, crt2);

// store the private key
ks.setKeyEntry(defaultalias, ff, keypass.toCharArray(), chain );

// save the key store to a file         
ks.store(new FileOutputStream ( "mykeystore" ),keypass.toCharArray());

(необязательно) проверьте содержимое вашего нового хранилища ключей:

Про сертификаты:  Ковровая плитка Betap |

keytool -list -keystore mykeystore -storepass password

тип хранилища ключей: JKS поставщик хранилища ключей: SUN

ваше хранилище ключей содержит 3 записи

cn=…, ou=…,о.=., 2 сентября 2021, trustedCertEntry, сертификат
отпечаток пальца (SHA1): 2C: B8:…

importkey, Sep 2, 2021, PrivateKeyEntry, отпечаток пальца сертификата
(SHA1): 9C: B0:…

cn=…,о.=…, 2 сентября 2021, trustedCertEntry, отпечаток пальца сертификата
(SHA1): 83: 63:…

(необязательно) Проверьте сертификаты и закрытый ключ из нового хранилища ключей на сервере SSL:
( Вы можете включить отладку как вариант ВМ: -Djavax.чистая.отладки=все )

        char[] passw = "password".toCharArray();
        KeyStore ks = KeyStore.getInstance("JKS", "SUN");
        ks.load(new FileInputStream ( "mykeystore" ), passw );

        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
        kmf.init(ks, passw);

        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(ks);
        TrustManager[] tm = tmf.getTrustManagers();

        SSLContext sclx = SSLContext.getInstance("TLS");
        sclx.init( kmf.getKeyManagers(), tm, null);

        SSLSocketFactory factory = sclx.getSocketFactory();
        SSLSocket socket = (SSLSocket) factory.createSocket( "192.168.1.111", 443 );
        socket.startHandshake();

        //if no exceptions are thrown in the startHandshake method, then everything is fine..

наконец зарегистрируйте свои сертификаты с помощью HttpsURLConnection, если планируете его использовать:

        char[] passw = "password".toCharArray();
        KeyStore ks = KeyStore.getInstance("JKS", "SUN");
        ks.load(new FileInputStream ( "mykeystore" ), passw );

        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
        kmf.init(ks, passw);

        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(ks);
        TrustManager[] tm = tmf.getTrustManagers();

        SSLContext sclx = SSLContext.getInstance("TLS");
        sclx.init( kmf.getKeyManagers(), tm, null);

        HostnameVerifier hv = new HostnameVerifier()
        {
            public boolean verify(String urlHostName, SSLSession session)
            {
                if (!urlHostName.equalsIgnoreCase(session.getPeerHost()))
                {
                    System.out.println("Warning: URL host '"   urlHostName   "' is different to SSLSession host '"   session.getPeerHost()   "'.");
                }
                return true;
            }
        };

        HttpsURLConnection.setDefaultSSLSocketFactory( sclx.getSocketFactory() );
        HttpsURLConnection.setDefaultHostnameVerifier(hv);

Как правильно импортировать самоподписанный сертификат в хранилище ключей java, которое по умолчанию доступно всем приложениям java?

Простая команда ‘keytool’ также работает в Windows и / или с Cygwin.

Если вы используете Cygwin, вот модифицированная команда, которую я использовал в нижней части ответа «S.Botha»:

  1. убедитесь, что вы указали JRE внутри JDK, который вы будете использовать
  2. Запустите вашу подсказку / cygwin как администратор
  3. перейдите в каталог bin этого JDK, например, cd / cygdrive / c / Program Files / Java / jdk1.8.0_121 / jre / bin
  4. Выполните команду keytool изнутри, где в конце укажите путь к вашему новому сертификату, например, так:

    ./keytool.exe -import-trustcacerts -keystore ../lib/security/cacerts  -storepass changeit -noprompt -alias myownaliasformysystem -file "D:Stuffsaved-certsca.cert"

Обратите внимание, потому что, если это в Cygwin, вы указываете путь к не-Cygwin программе, поэтому путь похож на DOS и в кавычках.

Ответ 2

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

Ответ 5

Это сработало для меня.:)

sudo keytool -importcert -file filename.cer -alias randomaliasname -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit 

Ответ 6

Возможно, вы захотите попробовать

keytool -import -trustcacerts -noprompt -keystore <full path to cacerts> -storepass changeit -alias $REMHOST -file $REMHOST.pem

я честно понятия не имею, где он помещает ваш сертификат, если вы просто пишете cacerts, просто дайте ему полный путь

Ответ 7

Простая команда «keytool» также работает на Windows и/или с Cygwin.

Подключение ssl в grpc / rsocket

Если говорить о двунаправленном обмене бинарными данными, современных тенденциях к написанию реактивных приложений, стоит отметить gRPC и RSocket для создания подобных приложений. Но поскольку в основании этих протоколов можно использовать Netty как транспорт, логика конфигурирования останется. Поэтому я не буду уделять этому много внимания.

Подключение ssl в spring boot для restcontroller

Но в мире Java разработки Spring стал де факто стандартом для DI. А вместе с внедрением зависимости люди используют и другие технологии, которые удобно собрать в одном Spring Boot приложении, не расходуя множество времени на конфигурирование всего зоопарка технологий.

Про сертификаты:  Болид

Конечно же, это приводит к избыточности зависимостей и к увеличению времени загрузки, но упрощает разработку. Куда проще написать аннотацию RestController, чем самому разбираться с тем, как корректно хендлить запросы через сервлеты. А для того, чтобы перенаправить всё взаимодействие через сервлеты в защищённый канал с использованием сертификатов, в Spring Boot есть два пути проcтой и более сложный для кастомных решений.В первом случае достаточно воспользоваться набором пропертей

server.ssl.key-store-type=JKS
server.ssl.key-store=classpath:cert.jks
server.ssl.key-store-password=changeit
server.ssl.key-alias=key
trust.store=classpath:cert.jks
trust.store.password=changeit

И все будет сделано за вас. Либо, если требуется более кастомная конфигурация, поднятие коннекторов на разных портах с нестандартными настройками и так далее, тогда путь лежит в сторону использования интерфейса WebServerFactoryCustomizer, имплементации которого существуют для всех основных контейнеров будь то Jetty, Tomcat или Undertow.

Поскольку это функциональный интерфейс, его довольно просто можно описать через lambda c параметром типа Connector. Для него мы можем выставить флаг setSecure(true), затем заполнить необходимые параметры для ProtocolHandler-а, выставив ему пути до jks c keystore и trustStore и соответствующие пароли к ним. Например, для tomcat код будет выглядеть подобным образом:

Подключение ssl к nettyserver

При создании нового проекта, подразумевающего взаимодействие клиента и сервера бинарными данными(protobuf) через защищенные вебсокеты (wss), возник вопрос подключения SSL в netty сервер. Как оказалось, это не представляет особых проблем, достаточно в билдере сетевого интерфейса добавить метод .withSslContext(), в который необходимо передать созданный контекст.

Получение экземпляра certpath

Обычно экземпляр CertPath получают из фабрики сертификатов (CertificateFactory или CertPathBuilder).

Получение экземпляра сертификата

Вы можете получить экземпляр сертификата следующими способами:

Посмотрите эти два руководства для получения дополнительной информации о получении экземпляра сертификата.

Создание экземпляра certificate

Создав экземпляр CertificateFactory, вы можете начать создавать экземпляры Certificate. Это делается с помощью вызова метода generateCertificate(). Пример вызова методаgenerateCertificate():

InputStream certificateInputStream = new FileInputStream("my-x509-certificate.crt");

Certificate certificate = certificateFactory.generateCertificate(certificateInputStream);

Создание экземпляра certificatefactory

Прежде чем вы сможете создавать экземпляры Certificate, вы должны создать экземпляр CertificateFactory. Пример:

CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");

В этом примере создается экземпляр CertificateFactory, способный создавать экземпляры сертификата X.509 (X509Certificate — подкласс Certificate).

Создание экземпляра certpath

CertificateFactory также может создавать экземпляр CertPath. Экземпляр CertPath создается вызовом метода generateCertPath():

InputStream certificateInputStream = new FileInputStream("my-x509-certificate-chain.crt");

CertPath certPath = certificateFactory.generateCertPath(certificateInputStream);

Тестирование tls/ssl

Для того чтобы провести тестирование реализованного безопасного подключения имеется возможность создать keystore программно, используя классы из пакета java.security.* Это даст возможность тестировать различное поведение системы в случае разных ситуаций типа истекших сертификатов, проверки корректной валидации доверенных сертификатов и так далее.

Чтобы грамотно проверить работоспобность придется пройти по всем составным частям jks и воссоздать программно внутри KeyStore пару ключей KeyPair, свой сертификат X509Certificate, цепочку родительских сертификатов, подпись и доверенные корневые сертификаты.

Для упрощения этой задачи можно воспользоваться библиотекой bouncyСastle, которая предоставляет ряд дополнительный возможностей в дополнение к стандартным классам в Java, посвященным криптографии из Java Cryptography Architecture (JCA) и Java Cryptography Extension (JCE).

Формат сертификатов

В рамках работы с сертификатами обычно используется контейнер PKCS 12 для хранения ключей и сертификатов, но в рамках Java, в дополнение широко используется проприетарный формат JKS (Java KeyStore). Для работы с хранилищем JDK поставляется с консольной утилитой keytool.

Помимо команды, позволяющей создать ключи вместе с keystore, которая выглядит следующим образом:

Оцените статью
Мой сертификат
Добавить комментарий