# wget https://www.openssl.org/source/openssl-1.0.2g.tar.gz # tar -xvf openssl-1.0.2g.tar.gz # cd openssl-1.0.2g/ # yum groupinstall "Development Tools" # yum install zlib zlib-devel # ./config shared zlib enable-rfc3779 # make && make install # echo "/usr/local/ssl/lib/" > /etc/ld.so.conf.d/openssl.conf # ldconfig # /usr/local/ssl/bin/openssl ciphers | tr ":" "\n" | grep -i gost GOST2001-GOST89-GOST89 GOST94-GOST89-GOST89 # cat /usr/local/ssl/openssl.cnf ………… openssl_conf = openssl_def [openssl_def] engines = engine_section [engine_section] gost = gost_section [gost_section] engine_id = gost default_algorithms = ALL …………
openssl
utility is called from the python code to generate and verify signatures. The openssl call was caused by the fact that it was not possible to set the used crypto module from the python code. All the necessary software is on both Linux and Windows platforms, because the technique can be called multiplatform. # yum install libxml2 libxml2-devel libxslt libxslt-devel python-devel # pip install lxml --upgrade
# wget https://www.stunnel.org/downloads/stunnel-5.31.tar.gz # tar -xvf stunnel-5.31.tar.gz # cd stunnel-5.31
NOEXPORT char *engine_init(void)
" function; . NOEXPORT char *engine_init(void) { if(engine_initialized) /* either first or already initialized */ return NULL; /* OK */ s_log(LOG_DEBUG, "Initializing engine #%d (%s)", current_engine+1, ENGINE_get_id(engines[current_engine])); if(!ENGINE_init(engines[current_engine])) { if(ERR_peek_last_error()) /* really an error */ sslerror("ENGINE_init"); else s_log(LOG_ERR, "Engine #%d (%s) not initialized", current_engine+1, ENGINE_get_id(engines[current_engine])); return "Engine initialization failed"; } #if 0 /* it is a bad idea to set the engine as default for all sections */ /* the "engine=auto" or "engineDefault" options should be used instead */ if(!ENGINE_set_default(engines[current_engine], ENGINE_METHOD_ALL)) { sslerror("ENGINE_set_default"); return "Selecting default engine failed"; } #endif s_log(LOG_INFO, "Engine #%d (%s) initialized", current_engine+1, ENGINE_get_id(engines[current_engine])); SSL_library_init(); engine_initialized=1; return NULL; /* OK */ }
# ./configure --with-ssl=/usr/local/ssl --disable-libwrap # make && make install
client=yes # (). CAFile=/etc/crypto/CA-SIT.pem engine=gost sslVersion=TLSv1 engineDefault = ALL output=/var/log/stunnel.log DEBUG=4 # eToken-. cert=/etc/crypto/public.pem key=/etc/crypto/private.key [pseudo-https] # , . accept = 10.1.5.133:8080 # , (). connect = 54.76.42.99:60045 ciphers = GOST2001-GOST89-GOST89
#! /bin/bash # # stunnel Start/Stop Stunnel # # chkconfig: 2345 90 60 # description: launches Stunnel # processname: stunnel # config: /etc/stunnel.conf # Source function library. . /etc/init.d/functions # See how we were called. prog="Stunnel CryptoTunnel" RNG=PROGRAM export RNG start() { echo -n $"Starting $prog: " /usr/local/bin/stunnel /etc/stunnel.conf RETVAL=$? [ $RETVAL -eq 0 ] && success [ $RETVAL -ne 0 ] && failure echo return $RETVAL } stop() { echo -n $"Stopping $prog: " /usr/bin/killall /usr/local/bin/stunnel >/dev/null 2>&1 RETVAL=$? [ $RETVAL -eq 0 ] && success [ $RETVAL -ne 0 ] && failure echo return $RETVAL } restart() { stop start } case "$1" in start) start ;; stop) stop ;; restart) restart ;; *) echo $"Usage: $0 {start|stop|status|restart}" exit 1 esac
# curl http://10.1.5.133:8080/ext-bus-nsi-service/services/Nsi?wsdl <?xml version='1.0' encoding='UTF-8'?><wsdl:definitions xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://dom.gosuslugi.ru/schema/integration/8.7.0.7/nsi-service/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:nsi-common="http://dom.gosuslugi.ru/schema/integration/8.7.0.7/nsi-common/" xmlns:nsi="http://dom.gosuslugi.ru/schema/integration/8.7.0.7/nsi/" xmlns:ns="http://www.w3.org/2000/09/xmldsig#" xmlns:base="http://dom.gosuslugi.ru/schema/integration/8.7.0.7/" targetNamespace="http://dom.gosuslugi.ru/schema/integration/8.7.0.7/nsi-service/"> <wsdl:types> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://dom.gosuslugi.ru/schema/integration/8.7.0.7/nsi-service/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:nsi-common="http://dom.gosuslugi.ru/schema/integration/8.7.0.7/nsi-common/" xmlns:nsi="http://dom.gosuslugi.ru/schema/integration/8.7.0.7/nsi/" xmlns:ns="http://www.w3.org/2000/09/xmldsig#" xmlns:base="http://dom.gosuslugi.ru/schema/integration/8.7.0.7/"> <xs:import namespace="http://dom.gosuslugi.ru/schema/integration/8.7.0.7/" schemaLocation="http://54.76.42.99:60046//ext-bus-nsi-service/services/Nsi?xsd=hcs-basetypes-8.7.0.7.xsd"/> <xs:import namespace="http://dom.gosuslugi.ru/schema/integration/8.7.0.7/nsi/" schemaLocation="http://54.76.42.99:60046//ext-bus-nsi-service/services/Nsi?xsd=hcs-nsi-types-8.7.0.7.xsd"/> </xs:schema> ………
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:ns0="http://dom.gosuslugi.ru/schema/integration/8.7.0.3/nsi/" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header> <RequestHeader xmlns="http://dom.gosuslugi.ru/schema/integration/8.7.0.4/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <Date>2016-04-11T14:28:28</Date> <MessageGUID>29f93de1-25b6-21e5-24ae-2c6f65dfe2b2</MessageGUID> <SenderID>4eb0a7d6-6317-45cf-8974-10e75cbb0cbc</SenderID> </RequestHeader> </SOAP-ENV:Header> <ns1:Body> <ns0:exportDataProviderNsiItemRequest Id="signed-element"> <ns0:RegistryNumber>51</ns0:RegistryNumber></ns0:exportDataProviderNsiItemRequest> </ns1:Body> </SOAP-ENV:Envelope>
SenderID
is the identifier of the management company on whose behalf the request is being made. MessageGUID
is a unique ID generated as desired. The body <ns1:Body>
is the request itself with additional fields. Id="signed-element"
- ID of the request, which we indicate, how we want and which we are oriented to, signing the request.<ns1:Body>
(more precisely, the part with Id and without the first and last newline character), is canonized by the C14N algorithm (exclusive = True), the hash sum is calculated from it according to GOST and output as BASE64. We digest1
. Console analog: # cat in.xml ; echo <ns0:exportDataProviderNsiItemRequest Id="signed-element"> <ns0:RegistryNumber>51</ns0:RegistryNumber></ns0:exportDataProviderNsiItemRequest> # cat in.xml | openssl dgst -engine gost -md_gost94 -binary | base64
digest2
.<xades:SignedProperties>
(see the Template) is formed, canonized by the C14N algorithm (exclusive = False) and is considered digest3
(BASE64) from the content.<ds:SignedInfo>
block is formed, canonized by the C14N algorithm (exclusive = False), signed and encoded in BASE64. The value of the <ds:SignatureValue>
block is obtained. Console analog: cat SignedInfo.xml | openssl dgst -sign private.key -engine gost -md_gost94 -binary | base64
<ds:Signature Id="xmldsig-{signature_id}" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411"/> <ds:Reference Id="xmldsig-{signature_id}-ref0" URI="#{signed_id}"> <ds:Transforms> <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411"/> <ds:DigestValue>{digest1}</ds:DigestValue> </ds:Reference> <ds:Reference Type="http://uri.etsi.org/01903#SignedProperties" URI="#xmldsig-{signature_id}-signedprops"> <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411"/> <ds:DigestValue>{digest3}</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue Id="xmldsig-{signature_id}-sigvalue"> {signature_value} </ds:SignatureValue> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:X509Data> <ds:X509Certificate> {x590_cert} </ds:X509Certificate> </ds:X509Data> </ds:KeyInfo> <ds:Object><xades:QualifyingProperties Target="#xmldsig-{signature_id}" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" xmlns:xades141="http://uri.etsi.org/01903/v1.4.1#"><xades:SignedProperties Id="xmldsig-{signature_id}-signedprops"><xades:SignedSignatureProperties><xades:SigningTime>{signing_time}</xades:SigningTime><xades:SigningCertificate><xades:Cert><xades:CertDigest><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411"/><ds:DigestValue>{digest2}</ds:DigestValue></xades:CertDigest><xades:IssuerSerial><ds:X509IssuerName>{x509_issuer_name}</ds:X509IssuerName><ds:X509SerialNumber>{x509_sn}</ds:X509SerialNumber></xades:IssuerSerial></xades:Cert></xades:SigningCertificate></xades:SignedSignatureProperties></xades:SignedProperties></xades:QualifyingProperties></ds:Object> </ds:Signature>
# cat SignedInfo.xml | openssl dgst -engine gost -md_gost94 -verify <(openssl x509 -engine gost -in public.pem -pubkey -noout) -signature signature.sig
<ds:SignedInfo>...</ds:SignedInfo>
block of the checked block. The values ​​of the hash sums are simply compared.gost.lib
. openssl_conf = openssl_def [openssl_def] engines = engine_section [engine_section] gost = gost_section [gost_section] engine_id = gost dynamic_path = ./gost.dll default_algorithms = ALL
set OPENSSL_CONF=C:\OpenSSL-Win32\openssl.cnf
C:\OpenSSL-Win32\bin>openssl.exe ciphers -v | find /I "gost" GOST2001-GOST89-GOST89 SSLv3 Kx=GOST Au=GOST01 Enc=GOST89(256) Mac=GOST89 GOST94-GOST89-GOST89 SSLv3 Kx=GOST Au=GOST94 Enc=GOST89(256) Mac=GOST89
Source: https://habr.com/ru/post/300856/
All Articles