Comments 3
К чему все эти громкие слова о шифровании, если HDImageStore — это просто папка с файлами (закрытыми ключами шифрования)? Т.е. любой пользователь на сервере может их скопировать.
0
mihmig, HDImageStore — это нативное хранилище СКЗИ КриптоПро, оно зашифровано и защищено паролем. Конечно, его надежность сильно проигрывает HSM модулям, тем более с неизвлекаемыми ключами, например, JaСarta.
А по поводу того, что любой пользователь может их скопировать с сервера. Так, во-первых, хранилище JKS или cacerts это тоже файлы. А во-вторых для защиты серверов обычно применяются организационные и технические меры защиты.
А по поводу того, что любой пользователь может их скопировать с сервера. Так, во-первых, хранилище JKS или cacerts это тоже файлы. А во-вторых для защиты серверов обычно применяются организационные и технические меры защиты.
+1
Пожалуй просто оставлю вот это здесь.
Оно в тему, да и самому иногда полезно зайти и освежить в памяти :-)
Это пример, как используя java.net.HttpURLConnection поднять TLS ГОСТ защищенное соединение со стороны клиента.
Создаем ГОСТ-овый SSLContext:
В trustStore у нас должен быть корневой сертификат УЦ, от которого цепочка строится к клиентским TLS сертификатам с расширением «Проверка подлинности клиента (1.3.6.1.5.5.7.3.2)»
Я на всякий случай положил туда и сертификаты промежуточных центров сертификации.
В keyStore у нас должны лежать ключи c клиентским сертификатом и в обязательном порядке вся цепочка до коневого УЦ.
Далее используя созданный SSL контекст, открываем HttpsURLConnection:
Далее, все как обычно, готовим тело HTTPS запроса, подключаемся, отправляем его на сервер и читаем ответ:
В итоге при включенном расширенном логировании Включение журналирования КриптоПро JTLS, мы видим всю процедуру проверки ключей и рукопожатия сервера и клиента:
Оно в тему, да и самому иногда полезно зайти и освежить в памяти :-)
Это пример, как используя java.net.HttpURLConnection поднять TLS ГОСТ защищенное соединение со стороны клиента.
Создаем ГОСТ-овый SSLContext:
package ru.alfabank.example.tls;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.Key;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import org.apache.commons.lang.exception.ExceptionUtils;
import ru.alfabank.ccjava.example.exceptions.TLSGostContextException;
import ru.alfabank.ccjava.example.rest.ExampleService;
public class TLSGostContext {
private static final String PRIVATE_KEY_NOT_FOUND = "privateKey not found! ";
private static final String TLS_GOST_CONTEXT_EXCEPTION = "TLSGostContextException: ";
private static final Logger LOGGER = Logger.getLogger(TLSGostContext.class.getName());
private static final char[] PASSWORD = "123456".toCharArray();
private static final String SIGNER_KEY_ALIAS = "vburmistrov";
public SSLContext getContext() throws TLSGostContextException {
SSLContext context = null;
try {
System.setProperty("ru.CryptoPro.reprov.enableCRLDP", "true");
System.setProperty("com.sun.security.enableCRLDP", "true");
System.setProperty("ssl.KeyManagerFactory.algorithm", "GostX509");
System.setProperty("javax.net.ssl.keyStoreType", "HDIMAGE");
System.setProperty("javax.net.ssl.keyStorePassword", "123456");
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load((FileInputStream) ExampleService.class.getClassLoader().getResource("data/trustStore.jks").openStream(), PASSWORD);
KeyStore keyStore = KeyStore.getInstance("HDIMAGE", "JCSP");
keyStore.load(null, PASSWORD);
X509Certificate cert = (X509Certificate) keyStore.getCertificate(SIGNER_KEY_ALIAS);
LOGGER.info("Signer found: " + ((X509Certificate) cert).getSubjectX500Principal().getName());
PrivateKey privateKey = null;
Key key = keyStore.getKey(SIGNER_KEY_ALIAS, PASSWORD);
if (key != null) {
privateKey = (PrivateKey) key;
} else {
LOGGER.log(Level.WARNING, PRIVATE_KEY_NOT_FOUND + SIGNER_KEY_ALIAS);
throw new TLSGostContextException(PRIVATE_KEY_NOT_FOUND + SIGNER_KEY_ALIAS);
}
KeyManagerFactory kmf = KeyManagerFactory.getInstance("GostX509", "JTLS");
kmf.init(keyStore, PASSWORD);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("GostX509", "JTLS");
tmf.init(trustStore);
context = SSLContext.getInstance("GostTLS", "JTLS");
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
} catch (KeyStoreException | NoSuchProviderException e) {
LOGGER.log(Level.INFO, TLS_GOST_CONTEXT_EXCEPTION + ExceptionUtils.getFullStackTrace(e));
throw new TLSGostContextException(e);
} catch (NoSuchAlgorithmException e) {
LOGGER.log(Level.INFO, TLS_GOST_CONTEXT_EXCEPTION + ExceptionUtils.getFullStackTrace(e));
throw new TLSGostContextException(e);
} catch (CertificateException e) {
LOGGER.log(Level.INFO, TLS_GOST_CONTEXT_EXCEPTION + ExceptionUtils.getFullStackTrace(e));
throw new TLSGostContextException(e);
} catch (IOException e) {
LOGGER.log(Level.INFO, TLS_GOST_CONTEXT_EXCEPTION + ExceptionUtils.getFullStackTrace(e));
throw new TLSGostContextException(e);
} catch (UnrecoverableKeyException e) {
LOGGER.log(Level.INFO, TLS_GOST_CONTEXT_EXCEPTION + ExceptionUtils.getFullStackTrace(e));
throw new TLSGostContextException(e);
} catch (KeyManagementException e) {
LOGGER.log(Level.INFO, TLS_GOST_CONTEXT_EXCEPTION + ExceptionUtils.getFullStackTrace(e));
throw new TLSGostContextException(e);
} catch (Exception e) {
LOGGER.log(Level.INFO, TLS_GOST_CONTEXT_EXCEPTION + ExceptionUtils.getFullStackTrace(e));
throw new TLSGostContextException(e);
}
return context;
}
}
В trustStore у нас должен быть корневой сертификат УЦ, от которого цепочка строится к клиентским TLS сертификатам с расширением «Проверка подлинности клиента (1.3.6.1.5.5.7.3.2)»
Я на всякий случай положил туда и сертификаты промежуточных центров сертификации.
В keyStore у нас должны лежать ключи c клиентским сертификатом и в обязательном порядке вся цепочка до коневого УЦ.
Далее используя созданный SSL контекст, открываем HttpsURLConnection:
private HttpsURLConnection openConnection(URL serverAddress, String method) throws IOException, TLSGostContextException {
HttpsURLConnection connection;
//Set up the initial connection
connection = (HttpsURLConnection) serverAddress.openConnection();
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Keep-Alive", "header");
connection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
connection.setRequestMethod(method);
connection.setDoOutput(true);
connection.setReadTimeout(300000);
connection.setSSLSocketFactory(new TLSGostContext().getContext().getSocketFactory());
return connection;
}
Далее, все как обычно, готовим тело HTTPS запроса, подключаемся, отправляем его на сервер и читаем ответ:
try {
URL serverAddress = null;
serverAddress = new URL(WORK_SERVER_URL);
// connection = openSimpleConnection(serverAddress, "POST");
connection = openConnection(serverAddress, "POST");
FileInputStream fis1 = (FileInputStream) ExampleService.class.getClassLoader().getResource("data/req.xml").openStream();
ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
byte[] dataBase64bytes1 = new byte[1024];
int len1;
while ((len1 = fis1.read(dataBase64bytes1)) != -1) {
baos1.write(dataBase64bytes1, 0, len1);
}
byte[] dataBytes = baos1.toByteArray();
String xmlString = new String(dataBytes, "UTF-8");
System.out.println("Send packet: " + xmlString);
DataOutputStream dos = new DataOutputStream(connection.getOutputStream());
dos.write(dataBytes);
dos.flush();
connection.connect();
BufferedReader br = null;
sb = new StringBuilder();
String line;
try {
br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
String connectionResponseMessage = connection.getResponseMessage();
System.out.println("ERROR!!! " + connectionResponseMessage);
br = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
while ((line = br.readLine()) != null) {
sb.append(line);
}
builder = Response.ok().entity(sb.toString().getBytes());
builder.build();
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("RESULT: " + sb.toString());
} catch (IOException e) {
LOGGER.log(Level.INFO, "ERROR!!! " + ExceptionUtils.getFullStackTrace(e));
throw new RuntimeException(e);
} catch (TLSGostContextException e) {
throw new RuntimeException(e);
} catch (Exception e) {
LOGGER.log(Level.INFO, "ERROR!!! " + ExceptionUtils.getFullStackTrace(e));
throw new RuntimeException(e);
} finally {
//close the connection, set all objects to null
connection.disconnect();
connection = null;
}
В итоге при включенном расширенном логировании Включение журналирования КриптоПро JTLS, мы видим всю процедуру проверки ключей и рукопожатия сервера и клиента:
[0m[32m2018-08-29 17:49:51,730 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) Certificate request received.
[0m[32m2018-08-29 17:49:51,731 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) Search for client containers with GOST algorithms.
[0m[32m2018-08-29 17:49:51,731 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) Search for client containers with type: GOST3410_2012_512
[0m[32m2018-08-29 17:49:51,731 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) %% getting aliases for Client
[0m[32m2018-08-29 17:49:51,731 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) %% check public key algorithm
[0m[33m2018-08-29 17:49:51,732 WARNING [ru.CryptoPro.ssl.SSLLogger] (default task-6) %% No alias is match
[0m[32m2018-08-29 17:49:51,732 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) Containers not found.
[0m[32m2018-08-29 17:49:51,732 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) Search for client containers with type: GOST3410_2012_256
[0m[32m2018-08-29 17:49:51,732 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) %% getting aliases for Client
[0m[32m2018-08-29 17:49:51,732 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) %% check public key algorithm
[0m[33m2018-08-29 17:49:51,732 WARNING [ru.CryptoPro.ssl.SSLLogger] (default task-6) %% No alias is match
[0m[32m2018-08-29 17:49:51,732 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) Containers not found.
[0m[32m2018-08-29 17:49:51,732 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) Search for client containers with type: GOST3410EL
[0m[32m2018-08-29 17:49:51,733 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) %% getting aliases for Client
[0m[32m2018-08-29 17:49:51,733 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) %% check public key algorithm
[0m[32m2018-08-29 17:49:51,733 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) %% check extended key usage. size: 14
[0m[32m2018-08-29 17:49:51,733 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) %% check extended key usage of Client
[0m[32m2018-08-29 17:49:51,734 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) matching alias: vburmistrov
[0m[32m2018-08-29 17:49:51,734 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) Check private key: vburmistrov
[0m[32m2018-08-29 17:49:51,734 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) Certificate chain vburmistrov found. Check if DH available…
[0m[32m2018-08-29 17:49:51,734 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) Private key vburmistrov is available. Test key…
[0m[32m2018-08-29 17:49:51,735 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) tls_client_fixed_DH state not allowed. Use cached key vburmistrov
[0m[32m2018-08-29 17:49:51,735 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) Use cached key and certificate with alias vburmistrov
[0m[32m2018-08-29 17:49:51,736 FINE [ru.CryptoPro.ssl.SSLLogger] (default task-6) *** Certificate message
chain [0] = [
[
Version: V3
Subject: SURNAME=Бурмистров, GIVENNAME=Василий ТЕСТ, T=Тестовое, CN=Альфабанк ТЕСТ, O=Альфабанк ТЕСТ, L=Москва, ST=77 г. Москва, C=RU, EMAILADDRESS=test@test.ru, OID.1.2.643.3.131.1.1=#120C303031313131313131313131, OID.1.2.643.100.1=#120D31313131313131313131313131, OID.1.2.643.100.3=#120B3131313131313131313131, OID.1.2.840.113549.1.9.2=«INN=1111111111/KPP=111111111/OGRN=1111111111111»
Signature Algorithm: 1.2.643.2.2.3, OID = 1.2.643.2.2.3
Key: 1.2.643.2.2.19
Validity: [From: Wed Aug 22 10:29:39 MSK 2018,
To: Thu Aug 22 10:39:39 MSK 2019]
Issuer: CN=«ООО \»Ромашка\"", O=«ООО \»Ромашка\"", OU=Отдел информационной безопасности, L=Москва, ST=77 г.Москва, C=RU, OID.1.2.643.3.131.1.1=#120C303037373037373532323330, OID.1.2.643.100.1=#120D31313137373436343830333334
SerialNumber: [ 8dd25d85e811dea5 8dd25d85e811dea5 ]
0
Sign up to leave a comment.
Настройка двусторонней RSA и GOST аутентификации в приложении на JBoss EAP 7