Многие знают, а многие возможно и не знают, что передача различной чувствительной информации в финансовой и банковской сфере, по требованиям ФСТЭК, должна защищаться отечественными алгоритмами шифрования и продуктами прошедшими сертификацию в ФСБ. Но как тестировать создаваемые продукты на отечественной криптографии, если большинство утилит тестирования ориентируется на западную криптографию ? Для Jmeter есть достаточно простой способ подключить отечественную криптографию.
О чём пойдёт речь в статье ?
Множество QA специалистов, а также специалисты по нагрузочному тестированию, используют jmeter в своей работе из-за его достаточно большой гибкости. Пакет всем хорош, но в своей базовой поставке он ничего не знает про российские алгоритмы шифрования. На самом деле тема с попыткой подключения российской криптографии к jmeter возникла после того, как мои коллеги попытались нагрузить и протестировать связку нового API, закрытого ГОСТовым mTLS, использующим пучок сертификатов выданных различными УЦ. Коллеги начали пилить свои приложения на Java, придумывать варианты с использованием stunnel с поддержкой российской криптографии, что в принципе имело определённый результат, но не имело гибкости в настройках. Поэтому были решено произвести исследования о возможности нативно использовать криптографию КриптоПро в jmeter.
Ремарка: для настройки и запуска jmeter используется Java17, операционная система Ubuntu 20.04
С чего всё началось ?
Так как текущим стандартом для разработки приложений на Java, с поддержкой отечественной криптографии, является использование библиотек от КриптоПро, было решено поисследовать форум компании на предмет подключения внешних библиотек JCP/JCSP к существующим проектам. Тема оказалась не очень популярной и каких-либо конкретных данных особо не нашлось. Правда нашлась информация о том, что практически «из коробки» можно подключить загрузку сертификатов в любое приложение на Java, использующее штатную Java криптографию. Далее началась череда длительных экспериментов подборки различных конфигураций.
Подключение библиотек
Для подключения библиотек КриптоПро, в исполняемый код, достаточно определить для java vm параметр classpath(-cp, —classpath) с указанием директории или списка jar файлов из которых необходимо загрузить дополнительные классы. Стоит сразу сделать несколько оговорок, о которых возможно кто-то не знает:
-
Для Linux и Windows используются различные разделители в списке загружаемых библиотек. В Linux это «:»(двоеточние), в Windows «;»(точка с запятой)
-cp «JCP.jar:JCryptoP.jar:JCPRevCheck.jar:JCPRevTools.jar» -
Загрузка библиотек указанных в classpath не работает для fat jar файлов в режиме запуска java -jar myjarfile.jar
-
Загрузка внешних библиотек не гарантирует корректную инициализацию всех механизмов защиты
-
Корректность инициализации и работы криптопровайдера может зависеть от настроек в java.security
-
Подключение библиотек для работы с ключами не делает автоматически доступной работу с TLS
Решением первой и второй проблемы является использование параметра user.classpath в файле user.properties. Jmeter загружает все указанные в параметре библиотеки при старте основного процесса. Например:
user.classpath=/opt/jcp-2.0.41940-A/*.jar
Решением третьей и четвёртой проблемы является использование отдельной копии java.security с переопределением пути к нему через параметры java vm.
-Djava.security.properties=./java.security
Для корректной инициализации криптопровайдера и библиотек необходимо добавить в файл java.security дополнительные строки:
# # List of providers and their preference orders (see above): # security.provider.1=SUN security.provider.2=SunRsaSign security.provider.3=SunEC security.provider.4=SunJSSE security.provider.5=SunJCE security.provider.6=SunJGSS security.provider.7=SunSASL security.provider.8=XMLDSig security.provider.9=SunPCSC security.provider.10=JdkLDAP security.provider.11=JdkSASL security.provider.12=SunPKCS11 security.provider.13=JCP security.provider.14=RevCheck security.provider.15=Crypto либо security.provider.13=ru.CryptoPro.JCP.JCP security.provider.14=ru.CryptoPro.reprov.RevCheck security.provider.15=ru.CryptoPro.Crypto.CryptoProvider
Это позволит механизмам криптографии определить последовательность «обхода/инициализации» провайдеров в работе.
Для решения пятой проблемы необходимо обеспечить вызов конструкторов по загрузке провайдера в приложение. Об этом мы поговорим чуть позже.
Загрузка ключей КриптоПро при старте приложения
Для загрузки внешних ключей при старте, в Jmeter был добавлен специализированный механизм SSL Manager и JSSESSLManager. SSL Manager имеет два варианта использования:
-
Загрузка ключей из командной строки
-
Загрузка ключей из интерфейса
JSSESSLManager используется для инициализации SSL контекста в jmeter опираясь на параметры SSLManager. Любые действия с ключами и внешними вызовами с SSL/TLS идут через инициализацию JsseSSLManager.
Если внимательно посмотреть в файл system.properties, то там будут присутствовать следующие строки:
# # # SSL properties (moved from jmeter.properties) # # See http://download.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#Customization # for information on the javax.ssl system properties # Truststore properties (trusted certificates) #javax.net.ssl.trustStore=/path/to/[jsse]cacerts #javax.net.ssl.trustStorePassword #javax.net.ssl.trustStoreProvider #javax.net.ssl.trustStoreType [default = KeyStore.getDefaultType()] # Keystore properties (client certificates) # Location #javax.net.ssl.keyStore=.keystore # #The password to your keystore #javax.net.ssl.keyStorePassword=changeit # #javax.net.ssl.keyStoreProvider #javax.net.ssl.keyStoreType [default = KeyStore.getDefaultType()]
Строки относящиеся к keyStore и trustStore позволяют указать параметры контейнеров содержащих ключи шифрования и доверенные сертификаты. Особенность ключевых контейнеров КриптоПро в том, что они не совместимы со штатными JKS контейнерами. Поэтому для их чтения необходима определенная последовательность действий.
Для использования ключей необходимо их скопировать из существующих установок КриптоПро или сгенерировать в поддерживающем ГОСТ 2012 УЦ. Способов тут два:
-
ручной
в ручном режиме создаётся дерево каталогов для хранения ключей пользователя и существующие ключи копируются в это деревоmkdir -p /var/opt/cprocsp/keys/<имя пользователя>
mkdir -p /var/opt/cprocsp/tmp && chmod 1777 /var/opt/cprocsp/tmp
cp -r CONTNR.000 /var/opt/cprocsp/keys/<имя пользователя>/
chown -R <имя пользователя>:<имя пользователя> /var/opt/cprocsp/keys/<имя пользователя>/ -
через браузер
необходим браузер поддерживающий ГОСТ (chromium-gost, yandex browser) с установленным CADES плагином от КриптоПро и установленным КриптоПро CSP на машине.
При получении нового сертификата, плагин автоматически создаст структуру ключей в/var/opt/cprocsp/keys/
Так как ключевой контейнер является нестандартным, описание параметров для доступа к нему тоже нестандартное.-Dkeytool.compat=true -Duse.cert.stub=true -Djavax.net.ssl.keyStore=NONE -Djavax.net.ssl.keyStoreType=HDImageStore -Djavax.net.ssl.keyStorePassword=password
Особенностью загрузки ключей является то, что в параметр keyStore передаётся значение None, а в keyStoreType передаётся значение HDImageStore, JCP сам производит опрос имеющихся ключей и их загрузку. По сути для загрузки конкретного ключа можно в keyStore указать полное длинное имя ключа и библиотека будет искать ключ по указанному имени. Та же ситуация с TrustStore.
Проверяем ключи
Для проверки наличия в системе ключей и правильности их установки необходимо запустить keytool с дополнительными параметрами, определяющими провайдер для криптоконтейнера
$ cd jcp-2.0.41940-A $ keytool -J-Dkeytool.compat=true -J-Duse.cert.stub=true -providerpath JCP.jar:ASN1P.jar:asn1rt.jar:forms_rt.jar:JCPRequest.jar:JCPRevCheck.jar:JCPRevTools.jar -list -v -provider ru.CryptoPro.JCP.JCP -keypass 12345678 -storepass 12345678 -storetype HDImageStore -keystore NONE
Если всё проинициализируется корректно, то вы увидите вот такую картинку
Dec 01, 2024 11:41:23 AM ru.CryptoPro.JCP.tools.Starter <init> INFO: Loading JCP 2.0.41940-A Dec 01, 2024 11:41:23 AM ru.CryptoPro.JCP.tools.Starter <init> INFO: JCP has been loaded. Keystore type: HDIMAGESTORE Keystore provider: JCP Your keystore contains 1 entry Alias name: cfa32f2ab-cbcc-0192-7526-800bb263116 Creation date: Nov 29, 2024 Entry type: PrivateKeyEntry Certificate chain length: 1 Certificate[1]: Owner: CN=Test Certificate Issuer: CN="Тестовый УЦ ООО \"КРИПТО-ПРО\"", O="ООО \"КРИПТО-ПРО\"", L=Москва, ST=г. Москва, C=RU, STREET=ул. Сущёвский вал д. 18, OID.1.2.643.3.131.1.1=#120c303031323334353637383930, OID.1.2.643.100.1=#120d31323334353637383930313233 Serial number: 7c0017a4b6df77756d6c303272000a0017a4b6 Valid from: Fri Nov 29 09:03:09 MSK 2024 until: Sat Jan 04 15:32:02 MSK 2025 Certificate fingerprints: SHA1: B7:C3:67:82:13:99:A2:54:A5:E9:89:6A:6F:13:C6:95:0E:15:A7:50 SHA256: AD:07:89:A8:40:A5:F8:67:EB:DB:9A:88:EC:B9:29:F3:4B:73:3D:06:54:B1:9E:34:1E:57:9D:9A:F6:7D:D5:21 Signature algorithm name: GOST3411_2012_256WITHGOST3410_2012_256 Subject Public Key Algorithm: GOST3410_2012_256 key of unknown size Version: 3 Extensions: #1: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false AuthorityInfoAccess [ [ accessMethod: ocsp accessLocation: URIName: http://testgost2012.cryptopro.ru/ocsp2012g/ocsp.srf , accessMethod: ocsp accessLocation: URIName: http://testgost2012.cryptopro.ru/ocsp2012gst/ocsp.srf , accessMethod: caIssuers accessLocation: URIName: http://testgost2012.cryptopro.ru/CertEnroll/testgost2012(10).crt , accessMethod: caIssuers accessLocation: URIName: http://testgost2012.cryptopro.ru/CertEnroll/testroot.p7b ] ] #2: ObjectId: 2.5.29.35 Criticality=false AuthorityKeyIdentifier [ KeyIdentifier [ 0000: E4 C0 80 96 E4 B4 78 34 12 3C 22 B9 75 CD 96 20 ......x4.<".u.. 0010: 43 30 B0 23 C0.# ] ] #3: ObjectId: 2.5.29.31 Criticality=false CRLDistributionPoints [ [DistributionPoint: [URIName: http://testgost2012.cryptopro.ru/CertEnroll/!0422!0435!0441!0442!043e!0432!044b!0439%20!0423!0426%20!041e!041e!041e%20!0022!041a!0420!0418!041f!0422!041e-!041f!0420!041e!0022(10).crl, URIName: http://testgost2012.cryptopro.ru/CertEnroll/testgost2012(10).crl] ]] #4: ObjectId: 2.5.29.15 Criticality=true KeyUsage [ DigitalSignature Non_repudiation Key_Encipherment Data_Encipherment ] #5: ObjectId: 2.5.29.14 Criticality=false SubjectKeyIdentifier [ KeyIdentifier [ 0000: 48 CE CF 7A FD 83 87 A3 52 DB 4A EA 42 46 BF 7D H..z....R.J.BF.. 0010: BC 99 FC 89 .... ] ] ******************************************* *******************************************
Если получили ошибку, то проверьте правильность расположения ключей, права на файлы ключевого контейнера, пароли и доступность библиотек JCP
Пробуем загрузиться
Команду для старта я вынес в jmeter-run.sh, так удобнее отлаживаться.
#!/bin/bash export JMETER_OPTS='-Djava.security.properties=java.security -Dkeytool.compat=true -Duse.cert.stub=true -Djavax.net.ssl.keyStore=NONE -Djavax.net.ssl.keyStoreType=HDImageStore -Djavax.net.ssl.keyStorePassword=12345678 -Djava.security.debug="jar,jca,keystore,provider,x509,properties"' bin/jmeter
Первичный запуск с добавленными провайдерами, но без указания пути к библиотекам, приводит к ошибке.
/projects/jmeter_docker/apache-jmeter-6.0.0-GOST$ ./jmeter-run.sh properties: java.security properties: Initial security property: jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, DSA keySize < 1024, SHA1 denyAfter 2019-01-01 properties: Initial security property: jdk.security.legacyAlgorithms=SHA1, RSA keySize < 2048, DSA keySize < 2048 properties: Initial security property: crypto.policy=unlimited properties: Initial security property: jceks.key.serialFilter=java.base/java.lang.Enum;java.base/java.security.KeyRep;java.base/java.security.KeyRep$Type;java.base/javax.crypto.spec.SecretKeySpec;!* properties: Initial security property: login.configuration.provider=sun.security.provider.ConfigFile properties: Initial security property: security.overridePropertiesFile=true properties: Initial security property: jdk.tls.legacyAlgorithms=NULL, anon, RC4, DES, 3DES_EDE_CBC properties: Initial security property: security.provider.7=SunSASL properties: Initial security property: security.provider.8=XMLDSig properties: Initial security property: security.provider.9=SunPCSC properties: Initial security property: jdk.security.caDistrustPolicies=SYMANTEC_TLS properties: Initial security property: security.provider.1=SUN properties: Initial security property: security.provider.2=SunRsaSign properties: Initial security property: security.provider.3=SunEC properties: Initial security property: security.provider.4=SunJSSE properties: Initial security property: networkaddress.cache.negative.ttl=10 properties: Initial security property: jdk.tls.alpnCharset=ISO_8859_1 properties: Initial security property: security.provider.5=SunJCE properties: Initial security property: security.provider.6=SunJGSS properties: Initial security property: ssl.KeyManagerFactory.algorithm=SunX509 properties: Initial security property: ssl.TrustManagerFactory.algorithm=PKIX properties: Initial security property: policy.allowSystemProperty=true properties: Initial security property: jdk.io.permissionsUseCanonicalPath=false properties: Initial security property: package.access=sun.misc.,sun.reflect.,org.GNOME.Accessibility. properties: Initial security property: package.definition=sun.misc.,sun.reflect. properties: Initial security property: security.provider.13=ru.CryptoPro.JCP.JCP properties: Initial security property: security.provider.12=SunPKCS11 properties: Initial security property: security.provider.15=ru.CryptoPro.Crypto.CryptoProvider properties: Initial security property: security.provider.14=ru.CryptoPro.reprov.RevCheck properties: Initial security property: policy.provider=sun.security.provider.PolicyFile properties: Initial security property: policy.url.1=file:${java.home}/conf/security/java.policy properties: Initial security property: policy.url.2=file:${user.home}/.java.policy properties: Initial security property: securerandom.source=file:/dev/random properties: Initial security property: jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224, SHA1 usage SignedJAR & denyAfter 2019-01-01 properties: Initial security property: jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, DTLSv1.0, RC4, DES, MD5withRSA, DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL properties: Initial security property: policy.ignoreIdentityScope=false properties: Initial security property: keystore.type.compat=true properties: Initial security property: security.provider.11=JdkSASL properties: Initial security property: security.provider.10=JdkLDAP properties: Initial security property: jdk.sasl.disabledMechanisms= .... ProviderConfig: Loading provider ru.CryptoPro.JCP.JCP ProviderConfig: Attempt to load ru.CryptoPro.JCP.JCP using SL ProviderConfig: Found SL Provider named JdkSASL ProviderConfig: Found SL Provider named XMLDSig ProviderConfig: Found SL Provider named SunPCSC ProviderConfig: Found SL Provider named SunJGSS ProviderConfig: Found SL Provider named SunEC ProviderConfig: Found SL Provider named SunPKCS11 ProviderConfig: Found SL Provider named SunSASL ProviderConfig: Found SL Provider named JdkLDAP ProviderConfig: Loading legacy provider: ru.CryptoPro.JCP.JCP ProviderConfig: Error loading legacy provider ru.CryptoPro.JCP.JCP java.lang.ClassNotFoundException: ru.CryptoPro.JCP.JCP at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525) .... 2024-11-29 21:50:55,312 DEBUG o.a.h.i.e.MainClientExec: Opening connection {s}->https://www.cryptopro.ru:443 2024-11-29 21:50:55,423 INFO o.a.j.p.h.s.h.LazyLayeredConnectionSocketFactory: Setting up HTTPS TrustAll Socket Factory 2024-11-29 21:50:55,438 DEBUG o.a.j.p.h.s.HTTPHC4Impl$JMeterDefaultHttpClientConnectionOperator: Connecting to www.cryptopro.ru/193.37.157.43:443 2024-11-29 21:50:55,438 DEBUG o.a.h.c.s.SSLConnectionSocketFactory: Connecting socket to www.cryptopro.ru/193.37.157.43:443 with timeout 0 2024-11-29 21:50:55,447 DEBUG o.a.j.u.JsseSSLManager: Creating threadLocal SSL context for: Thread Group 1-1 2024-11-29 21:50:55,632 INFO o.a.j.u.SSLManager: JmeterKeyStore Location: NONE type HDImageStore 2024-11-29 21:50:55,646 DEBUG o.a.h.i.c.DefaultManagedHttpClientConnection: http-outgoing-0: Shutdown connection 2024-11-29 21:50:55,647 DEBUG o.a.h.i.e.MainClientExec: Connection discarded 2024-11-29 21:50:55,647 DEBUG o.a.h.i.c.PoolingHttpClientConnectionManager: Connection released: [id: 0][route: {s}->https://www.cryptopro.ru:443][total available: 0; ro ute allocated: 0 of 2; total allocated: 0 of 20] 2024-11-29 21:50:55,647 DEBUG o.a.j.p.h.s.HTTPHC4Impl: RuntimeException java.lang.IllegalArgumentException: Could not create keystore: HDImageStore not found at org.apache.jmeter.util.SSLManager.getKeyStore(SSLManager.java:133) ~[ApacheJMeter_core.jar:6.0.0-SNAPSHOT] at org.apache.jmeter.util.JsseSSLManager.createContext(JsseSSLManager.java:235) ~[ApacheJMeter_core.jar:6.0.0-SNAPSHOT]
Это говорит о том, что Java не поняла наших настроек и не загрузила JCP.
Любые попытки загрузить классы путём добавления/изменения флагов/properties, чтоб их увидел jmeter ничем хорошим обычно не заканчиваются. Можно положить КриптоПро JCP библиотеки в lib/ext, но данный метод работает очень нестабильно.
Можно попробовать обойти указанную проблему через загрузку main класса
java -cp "*:bin/*:../lib/*:../lib/ext/*:../jcp-2.0.41940-A/*" -Dkeytool.compat=true -Duse.cert.stub=true -Djava.util.logging.ConsoleHandler.level=ALL -Dru.CryptoPro.ssl.SSLLogger.level=ALL -Dru.CryptoPro.ssl.SSLLogger.handlers=java.util.logging.ConsoleHandler -Djava.security.debug="jar,jca,keystore,provider,x509,properties" -Djavax.net.ssl.keyStore=NONE -Djavax.net.ssl.keyStoreType=HDImageStore -Djavax.net.ssl.keyStorePassword=12345678 -Djavax.net.ssl.trustStore=NONE -Djavax.net.ssl.trustStoreType=HDImageStore -Djavax.net.ssl.trustStorePassword=12345678 -Djavax.net.ssl.provider=ru.CryptoPro.JCP.JCP -Djava.security.properties=../java.security org.apache.jmeter.NewDriver
И jmeter даже увидит ключи
2024-11-29 22:34:34,653 DEBUG o.a.j.p.h.s.HTTPHC4Impl: Start : sample https://www.cryptopro.ru/certsrv/a3.gif method GET followingRedirect false depth 0 2024-11-29 22:34:34,753 DEBUG o.a.j.p.h.s.HTTPHC4Impl: Created new HttpClient: @1829529146 https://www.cryptopro.ru 2024-11-29 22:34:34,759 DEBUG o.a.j.p.h.c.HC4CookieHandler: Found 0 cookies for https://www.cryptopro.ru/certsrv/a3.gif 2024-11-29 22:34:34,759 DEBUG o.a.j.p.h.s.HTTPHC4Impl: Storing in HttpContext the user token: Thread Group 1-1 2024-11-29 22:34:34,780 DEBUG o.a.h.c.p.RequestAddCookies: CookieSpec selected: default 2024-11-29 22:34:34,781 DEBUG o.a.h.c.p.RequestAddCookies: Unsupported cookie policy: default 2024-11-29 22:34:34,781 DEBUG o.a.h.c.p.RequestAuthCache: Auth cache not set in the context 2024-11-29 22:34:34,783 DEBUG o.a.h.i.c.PoolingHttpClientConnectionManager: Connection request: [route: {s}->https://www.cryptopro.ru:443][state: Thread Group 1-1][total available: 0; route allocated: 0 of 2; total allocated: 0 of 20] 2024-11-29 22:34:34,804 DEBUG o.a.h.i.c.PoolingHttpClientConnectionManager: Connection leased: [id: 0][route: {s}->https://www.cryptopro.ru:443][total available: 0; route allocated: 1 of 2; total allocated: 1 of 20] 2024-11-29 22:34:34,808 DEBUG o.a.h.i.e.MainClientExec: Opening connection {s}->https://www.cryptopro.ru:443 2024-11-29 22:34:34,827 INFO o.a.j.p.h.s.h.LazyLayeredConnectionSocketFactory: Setting up HTTPS TrustAll Socket Factory 2024-11-29 22:34:34,838 INFO o.a.j.u.JsseSSLManager: Using default SSL protocol: TLS 2024-11-29 22:34:34,838 INFO o.a.j.u.JsseSSLManager: SSL session context: per-thread 2024-11-29 22:34:34,838 INFO o.a.j.u.JsseSSLManager: SSL providers list: null 2024-11-29 22:34:34,853 DEBUG o.a.j.p.h.s.HTTPHC4Impl$JMeterDefaultHttpClientConnectionOperator: Connecting to www.cryptopro.ru/193.37.157.43:443 2024-11-29 22:34:34,853 DEBUG o.a.h.c.s.SSLConnectionSocketFactory: Connecting socket to www.cryptopro.ru/193.37.157.43:443 with timeout 0 2024-11-29 22:34:34,862 INFO o.a.j.u.SSLManager: Init null SSLManager 2024-11-29 22:34:34,864 DEBUG o.a.j.u.JsseSSLManager: ssl Provider = null 2024-11-29 22:34:34,869 DEBUG o.a.j.u.JsseSSLManager: SSL stuff all set 2024-11-29 22:34:34,869 DEBUG o.a.j.u.JsseSSLManager: JsseSSLManager installed 2024-11-29 22:34:34,869 INFO o.a.j.u.SSLManager: Reuse SSLManager: org.apache.jmeter.util.JsseSSLManager@3769c4b0 2024-11-29 22:34:34,870 DEBUG o.a.j.u.JsseSSLManager: Creating threadLocal SSL context for: Thread Group 1-1 2024-11-29 22:34:34,989 INFO o.a.j.u.SSLManager: JmeterKeyStore Location: NONE type HDImageStore 2024-11-29 22:34:35,579 INFO o.a.j.u.SSLManager: KeyStore created OK 2024-11-29 22:34:35,579 WARN o.a.j.u.SSLManager: No password provided, and no GUI present so cannot prompt 2024-11-29 22:34:37,137 DEBUG o.a.j.u.k.JmeterKeyStore: Certificate at index 1 with alias cfa32f2ab-cbcc-0192-7526-800bb263116 2024-11-29 22:34:37,479 DEBUG o.a.j.u.k.JmeterKeyStore: Subject DN: CN=Test Certificate 2024-11-29 22:34:37,480 DEBUG o.a.j.u.k.JmeterKeyStore: Issuer DN: CN="Тестовый УЦ ООО \"КРИПТО-ПРО\"", O="ООО \"КРИПТО-ПРО\"", L=Москва, ST=г. Москва, C=RU, STREET=ул. Сущёвский вал д. 18, OID.1.2.643.3.131.1.1=#120c303031323334353637383930, OID.1.2.643.100.1=#120d31323334353637383930313233 2024-11-29 22:34:37,481 DEBUG o.a.j.u.k.JmeterKeyStore: Not valid before: 2024-11-29T06:03:09Z 2024-11-29 22:34:37,482 DEBUG o.a.j.u.k.JmeterKeyStore: Not valid after: 2025-01-04T12:32:02Z 2024-11-29 22:34:38,522 INFO o.a.j.u.SSLManager: Total of 1 aliases loaded OK from PKCS11 2024-11-29 22:34:38,522 DEBUG o.a.j.u.SSLManager: JmeterKeyStore type: class org.apache.jmeter.util.keystore.JmeterKeyStore 2024-11-29 22:34:38,523 DEBUG o.a.j.u.JsseSSLManager: JmeterKeyStore type: class org.apache.jmeter.util.keystore.JmeterKeyStore 2024-11-29 22:34:38,525 INFO o.a.j.u.SSLManager: TrustStore Location: NONE 2024-11-29 22:34:38,529 INFO o.a.j.u.SSLManager: TrustStore created OK, Type: JKS 2024-11-29 22:34:38,529 WARN o.a.j.u.SSLManager: Truststore file not found, loading empty truststore
Но во первых это не очень красиво, во вторых не решает проблему ГОСТ TLS трафика, т.к. ключ грузится от КриптоПро, а соединение устанавливается через RSA TLS
2024-11-29 22:34:38,552 DEBUG o.a.j.u.JsseSSLManager: Supported Cipher: TLS_EMPTY_RENEGOTIATION_INFO_SCSV 2024-11-29 22:34:38,553 DEBUG o.a.j.u.JsseSSLManager: Using threadLocal SSL context for: Thread Group 1-1 2024-11-29 22:34:38,637 DEBUG o.a.h.c.s.SSLConnectionSocketFactory: Enabled protocols: [TLSv1.3, TLSv1.2] 2024-11-29 22:34:38,638 DEBUG o.a.h.c.s.SSLConnectionSocketFactory: Enabled cipher suites:[TLS_AES_256_GCM_SHA384, TLS_AES_128_GCM_SHA256, TLS_CHACHA20_POLY1305_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV] 2024-11-29 22:34:38,639 DEBUG o.a.h.c.s.SSLConnectionSocketFactory: Starting handshake 2024-11-29 22:34:38,740 DEBUG o.a.j.u.CustomX509TrustManager: Server certificate 1: Subject DN: CN=*.cryptopro.ru, O=Crypto-Pro LLC, L=Moscow, ST=Moscow, C=RU Signature Algorithm: SHA256withRSA Valid from: 2024-03-25T13:38:39.000+0300 Valid until: 2025-04-26T13:38:38.000+0300 Issuer: CN=GlobalSign RSA OV SSL CA 2018, O=GlobalSign nv-sa, C=BE 2024-11-29 22:34:38,740 DEBUG o.a.j.u.CustomX509TrustManager: Server certificate 2: Subject DN: CN=GlobalSign RSA OV SSL CA 2018, O=GlobalSign nv-sa, C=BE Signature Algorithm: SHA256withRSA Valid from: 2018-11-21T03:00:00.000+0300 Valid until: 2028-11-21T03:00:00.000+0300 Issuer: CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R3 2024-11-29 22:34:38,810 DEBUG o.a.h.c.s.SSLConnectionSocketFactory: Secure session established 2024-11-29 22:34:38,810 DEBUG o.a.h.c.s.SSLConnectionSocketFactory: negotiated protocol: TLSv1.2 2024-11-29 22:34:38,810 DEBUG o.a.h.c.s.SSLConnectionSocketFactory: negotiated cipher suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 2024-11-29 22:34:38,811 DEBUG o.a.h.c.s.SSLConnectionSocketFactory: peer principal: CN=*.cryptopro.ru, O=Crypto-Pro LLC, L=Moscow, ST=Moscow, C=RU 2024-11-29 22:34:38,811 DEBUG o.a.h.c.s.SSLConnectionSocketFactory: peer alternative names: [*.cryptopro.ru, cryptopro.ru] 2024-11-29 22:34:38,811 DEBUG o.a.h.c.s.SSLConnectionSocketFactory: issuer principal: CN=GlobalSign RSA OV SSL CA 2018, O=GlobalSign nv-sa, C=BE 2024-11-29 22:34:38,812 DEBUG o.a.j.p.h.s.HTTPHC4Impl$JMeterDefaultHttpClientConnectionOperator: Connection established 192.168.68.105:54872<->193.37.157.43:443 2024-11-29 22:34:38,812 DEBUG o.a.h.i.e.MainClientExec: Executing request GET /certsrv/a3.gif HTTP/1.1
Решив найти причину такого поведения, взор был обращён на исходный код JsseSSLManager. Как оказалось, «фича» загрузки внешних провайдеров находится в статусе «TODO», ну и собственно инициализация SSLContext вызывается с пустым идентификатором провайдера. Что естественно не позволяет правильно инициализировать механизмы крипропровайдеров.
Было решено добавить механизм динамической загрузки внешних провайдеров по имени класса. Патч добавляет несколько строк и позволяет, в виде перечисления, указать через запятую список используемых провайдеров.
diff --git a/src/core/src/main/java/org/apache/jmeter/util/JsseSSLManager.java b/src/core/src/main/java/org/apache/jmeter/util/JsseSSLManager.java index f4ca272c59..e10f6cb4a0 100644 --- a/src/core/src/main/java/org/apache/jmeter/util/JsseSSLManager.java +++ b/src/core/src/main/java/org/apache/jmeter/util/JsseSSLManager.java @@ -17,6 +17,7 @@ package org.apache.jmeter.util; +import java.lang.reflect.Constructor; import java.net.HttpURLConnection; import java.net.Socket; import java.security.GeneralSecurityException; @@ -62,6 +63,9 @@ public class JsseSSLManager extends SSLManager { private static final boolean SHARED_SESSION_CONTEXT = JMeterUtils.getPropDefault("https.sessioncontext.shared",false); // $NON-NLS-1$ + private static final String SSL_PROVIDER_CLASSES_LIST = + JMeterUtils.getPropDefault("https.providers",null); // $NON-NLS-1$ + /** * Characters per second, used to slow down sockets */ @@ -71,6 +75,7 @@ public class JsseSSLManager extends SSLManager { if (log.isInfoEnabled()) { log.info("Using default SSL protocol: {}", DEFAULT_SSL_PROTOCOL); log.info("SSL session context: {}", SHARED_SESSION_CONTEXT ? "shared" : "per-thread"); + log.info("SSL providers list: {}", SSL_PROVIDER_CLASSES_LIST); if (CPS > 0) { log.info("Setting up HTTPS SlowProtocol, cps={}", CPS); @@ -97,6 +102,23 @@ public class JsseSSLManager extends SSLManager { */ public JsseSSLManager(Provider provider) { log.debug("ssl Provider = {}", provider); + if (SSL_PROVIDER_CLASSES_LIST != null) { + log.debug("ssl Provider classes list = {}", SSL_PROVIDER_CLASSES_LIST); + String[] providerclasses = SSL_PROVIDER_CLASSES_LIST.split(","); + for (String providerclass : providerclasses) { + if (providerclass == null) { + continue; + } + try { + Class<?> cl = Class.forName(providerclass); + Constructor<?> con = cl.getConstructor(); + setProvider((Provider) con.newInstance()); + log.info("Added provider class {}", providerclass); + } catch (Exception ex) { + log.error(ex.getMessage(), ex); + } + } + } setProvider(provider); if (null == this.rand) { // Surely this is always null in the constructor? this.rand = new SecureRandom();
Для корректной инициализации контекста теперь достаточно добавить в user.properties два параметра: список провайдеров для загрузки и используемый протокол.
https.providers=ru.CryptoPro.ssl.Provider,ru.CryptoPro.Crypto.CryptoProvider,ru.CryptoPro.JCP.JCP,ru.CryptoPro.reprov.RevCheck https.default.protocol=GostTLS
И всё, как по мановению волшебной палочки, начинает работать как нужно
024-11-30 20:05:09,854 DEBUG o.a.h.i.e.MainClientExec: Opening connection {s}->https://www.cryptopro.ru:443 2024-11-30 20:05:09,866 INFO o.a.j.p.h.s.h.LazyLayeredConnectionSocketFactory: Setting up HTTPS TrustAll Socket Factory 2024-11-30 20:05:09,873 INFO o.a.j.u.JsseSSLManager: Using default SSL protocol: GostTLS 2024-11-30 20:05:09,873 INFO o.a.j.u.JsseSSLManager: SSL session context: per-thread 2024-11-30 20:05:09,874 INFO o.a.j.u.JsseSSLManager: SSL providers list: ru.CryptoPro.ssl.Provider,ru.CryptoPro.Crypto.CryptoProvider,ru.CryptoPro.JCP.JCP,ru.CryptoPro.reprov.RevCheck 2024-11-30 20:05:09,888 DEBUG o.a.j.p.h.s.HTTPHC4Impl$JMeterDefaultHttpClientConnectionOperator: Connecting to www.cryptopro.ru/193.37.157.43:443 2024-11-30 20:05:09,888 DEBUG o.a.h.c.s.SSLConnectionSocketFactory: Connecting socket to www.cryptopro.ru/193.37.157.43:443 with timeout 0 2024-11-30 20:05:09,905 INFO o.a.j.u.SSLManager: Init null SSLManager 2024-11-30 20:05:09,907 DEBUG o.a.j.u.JsseSSLManager: ssl Provider = null 2024-11-30 20:05:09,907 DEBUG o.a.j.u.JsseSSLManager: ssl Provider classes list = ru.CryptoPro.ssl.Provider,ru.CryptoPro.Crypto.CryptoProvider,ru.CryptoPro.JCP.JCP,ru.CryptoPro.reprov.RevCheck 2024-11-30 20:05:10,041 INFO o.a.j.u.JsseSSLManager: Added provider class ru.CryptoPro.ssl.Provider 2024-11-30 20:05:10,047 INFO o.a.j.u.JsseSSLManager: Added provider class ru.CryptoPro.Crypto.CryptoProvider 2024-11-30 20:05:10,094 INFO o.a.j.u.JsseSSLManager: Added provider class ru.CryptoPro.JCP.JCP 2024-11-30 20:05:10,096 INFO o.a.j.u.JsseSSLManager: Added provider class ru.CryptoPro.reprov.RevCheck 2024-11-30 20:05:10,098 DEBUG o.a.j.u.JsseSSLManager: SSL stuff all set 2024-11-30 20:05:10,102 DEBUG o.a.j.u.JsseSSLManager: JsseSSLManager installed 2024-11-30 20:05:10,102 INFO o.a.j.u.SSLManager: Reuse SSLManager: org.apache.jmeter.util.JsseSSLManager@7a305e49 2024-11-30 20:05:10,102 DEBUG o.a.j.u.JsseSSLManager: Creating threadLocal SSL context for: Thread Group 1-1 2024-11-30 20:05:10,126 INFO o.a.j.u.SSLManager: JmeterKeyStore Location: NONE type HDImageStore 2024-11-30 20:05:10,128 INFO o.a.j.u.SSLManager: KeyStore created OK 2024-11-30 20:05:10,128 WARN o.a.j.u.SSLManager: No password provided, and no GUI present so cannot prompt 2024-11-30 20:05:11,119 DEBUG o.a.j.u.k.JmeterKeyStore: Certificate at index 1 with alias cfa32f2ab-cbcc-0192-7526-800bb263116 2024-11-30 20:05:11,186 DEBUG o.a.j.u.k.JmeterKeyStore: Subject DN: CN=Test Certificate 2024-11-30 20:05:11,187 DEBUG o.a.j.u.k.JmeterKeyStore: Issuer DN: CN="Тестовый УЦ ООО \"КРИПТО-ПРО\"", O="ООО \"КРИПТО-ПРО\"", L=Москва, ST=г. Москва, C=RU, STREET=ул. Сущёвский вал д. 18, OID.1.2.643.3.131.1.1=#120c303031323334353637383930, OID.1.2.643.100.1=#120d31323334353637383930313233 2024-11-30 20:05:11,188 DEBUG o.a.j.u.k.JmeterKeyStore: Not valid before: 2024-11-29T06:03:09Z 2024-11-30 20:05:11,188 DEBUG o.a.j.u.k.JmeterKeyStore: Not valid after: 2025-01-04T12:32:02Z 2024-11-30 20:05:11,514 INFO o.a.j.u.SSLManager: Total of 1 aliases loaded OK from PKCS11 2024-11-30 20:05:11,514 DEBUG o.a.j.u.SSLManager: JmeterKeyStore type: class org.apache.jmeter.util.keystore.JmeterKeyStore 2024-11-30 20:05:11,515 DEBUG o.a.j.u.JsseSSLManager: JmeterKeyStore type: class org.apache.jmeter.util.keystore.JmeterKeyStore 2024-11-30 20:05:11,598 DEBUG o.a.j.u.JsseSSLManager: Default Cipher: TLS_CIPHER_2012 2024-11-30 20:05:11,598 DEBUG o.a.j.u.JsseSSLManager: Supported Cipher: TLS_CIPHER_2012 2024-11-30 20:05:11,598 DEBUG o.a.j.u.JsseSSLManager: Default Cipher: TLS_CIPHER_2001 2024-11-30 20:05:11,599 DEBUG o.a.j.u.JsseSSLManager: Supported Cipher: TLS_CIPHER_2001 2024-11-30 20:05:11,599 DEBUG o.a.j.u.JsseSSLManager: Using threadLocal SSL context for: Thread Group 1-1 2024-11-30 20:05:11,619 DEBUG o.a.h.c.s.SSLConnectionSocketFactory: Enabled protocols: [TLSv1.2] 2024-11-30 20:05:11,619 DEBUG o.a.h.c.s.SSLConnectionSocketFactory: Enabled cipher suites:[TLS_CIPHER_2012, TLS_CIPHER_2001] 2024-11-30 20:05:11,619 DEBUG o.a.h.c.s.SSLConnectionSocketFactory: Starting handshake 2024-11-30 20:05:11,660 DEBUG o.a.j.u.CustomX509TrustManager: Server certificate 1: Subject DN: CN="Веб-сервер ООО \"КРИПТО-ПРО\"", C=RU, ST=г. Москва, L=Москва, O="ООО \"КРИПТО-ПРО\"" Signature Algorithm: GOST3411_2012_256WITHGOST3410_2012_256 Valid from: 2024-03-26T12:47:39.000+0300 Valid until: 2025-06-26T12:47:39.000+0300 Issuer: CN=CryptoPro TLS CA, O="LLC \"Crypto-Pro\"", L=Moscow, ST=Moscow, C=RU, OID.1.2.643.100.1=#120d31303337373030303835343434, OID.1.2.643.100.4=#120a37373137313037393931 2024-11-30 20:05:11,660 DEBUG o.a.j.u.CustomX509TrustManager: Server certificate 2: Subject DN: CN=CryptoPro TLS CA, O="LLC \"Crypto-Pro\"", L=Moscow, ST=Moscow, C=RU, OID.1.2.643.100.1=#120d31303337373030303835343434, OID.1.2.643.100.4=#120a37373137313037393931 Signature Algorithm: GOST3411_2012_256WITHGOST3410_2012_256 Valid from: 2022-12-19T16:56:08.000+0300 Valid until: 2032-12-19T16:56:08.000+0300 Issuer: CN=CryptoPro GOST Root CA, O="LLC \"Crypto-Pro\"", L=Moscow, ST=Moscow, C=RU, OID.1.2.643.3.131.1.1=#120c303037373137313037393931, OID.1.2.643.100.1=#120d31303337373030303835343434 2024-11-30 20:05:11,661 DEBUG o.a.j.u.CustomX509TrustManager: Server certificate 3: Subject DN: CN=CryptoPro GOST Root CA, O="LLC \"Crypto-Pro\"", L=Moscow, ST=Moscow, C=RU, OID.1.2.643.3.131.1.1=#120c303037373137313037393931, OID.1.2.643.100.1=#120d31303337373030303835343434 Signature Algorithm: GOST3411_2012_256WITHGOST3410_2012_256 Valid from: 2022-12-19T18:10:59.000+0300 Valid until: 2032-12-19T18:10:59.000+0300 Issuer: CN=CryptoPro GOST Root CA, O="LLC \"Crypto-Pro\"", L=Moscow, ST=Moscow, C=RU, OID.1.2.643.3.131.1.1=#120c303037373137313037393931, OID.1.2.643.100.1=#120d31303337373030303835343434 2024-11-30 20:05:11,997 DEBUG o.a.h.c.s.SSLConnectionSocketFactory: Secure session established 2024-11-30 20:05:11,997 DEBUG o.a.h.c.s.SSLConnectionSocketFactory: negotiated protocol: TLSv1.2 2024-11-30 20:05:11,998 DEBUG o.a.h.c.s.SSLConnectionSocketFactory: negotiated cipher suite: TLS_CIPHER_2012 2024-11-30 20:05:11,998 DEBUG o.a.h.c.s.SSLConnectionSocketFactory: peer principal: CN="Веб-сервер ООО \"КРИПТО-ПРО\"", C=RU, ST=г. Москва, L=Москва, O="ООО \"КРИПТО-ПРО\"" 2024-11-30 20:05:11,998 DEBUG o.a.h.c.s.SSLConnectionSocketFactory: peer alternative names: [*.cryptopro.ru, cryptopro.ru, *.crypto-pro.ru, crypto-pro.ru, xn--h1adnadbdep.xn--p1ai] 2024-11-30 20:05:11,998 DEBUG o.a.h.c.s.SSLConnectionSocketFactory: issuer principal: CN=CryptoPro TLS CA, O="LLC \"Crypto-Pro\"", L=Moscow, ST=Moscow, C=RU, OID.1.2.643.100.1=#120d31303337373030303835343434, OID.1.2.643.100.4=#120a37373137313037393931 2024-11-30 20:05:11,999 DEBUG o.a.j.p.h.s.HTTPHC4Impl$JMeterDefaultHttpClientConnectionOperator: Connection established 192.168.68.105:50590<->193.37.157.43:443 2024-11-30 20:05:11,999 DEBUG o.a.h.i.e.MainClientExec: Executing request GET /certsrv/a3.gif HTTP/1.1 2024-11-30 20:05:11,999 DEBUG o.a.h.i.e.MainClientExec: Target auth state: UNCHALLENGED 2024-11-30 20:05:12,000 DEBUG o.a.h.i.e.MainClientExec: Proxy auth state: UNCHALLENGED 2024-11-30 20:05:12,001 DEBUG o.a.h.headers: http-outgoing-0 >> GET /certsrv/a3.gif HTTP/1.1 2024-11-30 20:05:12,001 DEBUG o.a.h.headers: http-outgoing-0 >> Connection: keep-alive 2024-11-30 20:05:12,001 DEBUG o.a.h.headers: http-outgoing-0 >> Host: www.cryptopro.ru 2024-11-30 20:05:12,001 DEBUG o.a.h.headers: http-outgoing-0 >> User-Agent: Apache-HttpClient/4.5.14 (Java/17.0.13) 2024-11-30 20:05:12,002 DEBUG o.a.h.wire: http-outgoing-0 >> "GET /certsrv/a3.gif HTTP/1.1[\r][\n]" 2024-11-30 20:05:12,002 DEBUG o.a.h.wire: http-outgoing-0 >> "Connection: keep-alive[\r][\n]" 2024-11-30 20:05:12,002 DEBUG o.a.h.wire: http-outgoing-0 >> "Host: www.cryptopro.ru[\r][\n]" 2024-11-30 20:05:12,002 DEBUG o.a.h.wire: http-outgoing-0 >> "User-Agent: Apache-HttpClient/4.5.14 (Java/17.0.13)[\r][\n]" 2024-11-30 20:05:12,002 DEBUG o.a.h.wire: http-outgoing-0 >> "[\r][\n]" 2024-11-30 20:05:12,003 DEBUG o.a.j.p.h.s.HTTPHC4Impl: Sent 133 bytes 2024-11-30 20:05:12,018 DEBUG o.a.h.wire: http-outgoing-0 << "HTTP/1.1 200 OK[\r][\n]" 2024-11-30 20:05:12,018 DEBUG o.a.h.wire: http-outgoing-0 << "Server: nginx[\r][\n]" 2024-11-30 20:05:12,018 DEBUG o.a.h.wire: http-outgoing-0 << "Date: Sat, 30 Nov 2024 17:01:11 GMT[\r][\n]" 2024-11-30 20:05:12,018 DEBUG o.a.h.wire: http-outgoing-0 << "Content-Type: image/gif[\r][\n]" 2024-11-30 20:05:12,018 DEBUG o.a.h.wire: http-outgoing-0 << "Content-Length: 49[\r][\n]"
Если сервер поддерживает mTLS, то в логах вы увидите результаты mTLS Handshake.
Данный механизм был проверен на нескольких сайтах поддерживающих ГОСТ TLS. Тех кто будет экспериментировать с сайтом www.cryptopro.ru сразу предупреждаю, после первых 60rps вы получите permban на ваш внешний адрес. Поэтому если хотите проверять корректность работы, да простит меня компания КриптоПро, не выставляйте количество ниток более 1. Так же рекомендую вызывать для теста статический контент, например https://www.crypropro.ru/certsrv/a3.gif.
Подведём итог. Для внедрения ГОСТ криптографии в Jmeter необходимо:
-
Создать локальную конфигурацию java.security добавив строки с криптопровадерами из библиотек КриптоПро JCP
-
Добавить параметры user.classpath,https.providers,https.default.protocol в файл user.properties
-
Создать файл для запуска jmeter с указанием параметров ключей, либо прописать данные параметры в security.properties или user.properties
-
Иметь в наличии КриптоПро ГОСТ ключи в виде КриптоПро контейнера
-
Пересобрать необходимую версию Jmeter применив к коду указанный в статье патч
-
При первичной отладке выставить параметры раширенной детализации в java.security.debug
PS: Для долгосрочной промышленной эксплуатации крайне рекомендуется приобретение лицензии на право использования СКЗИ КриптоПро JCP версии 2.0 на одном рабочем месте стоимостью 1200 рублей.
Удачного тестирования!
ссылка на оригинал статьи https://habr.com/ru/articles/862188/
Добавить комментарий