Electronic signature

An electronic signature is generated by the algorithm ГОСТ R 34.10-2012 (256 and 512 bits) according to the XMLDSig standard. The Signature section, which contains the XMLDSig-generated EP, is placed in the SgntrSt section inside the SplmtryData section, which is designed to accommodate arbitrary data. Each Signature section contains a link to the section to be signed (s) inside the xml document. The message must be fully signed, including the section

<SplmtryData>
    <Envlp>
        <SgntrSt>
        </SgntrSt>
    </Envlp>
</SplmtryData>

General recommendations for generating an XMLDSig signature:

1) You can use a certified combination of the cryptographic provider CryptoPro CSP and the API from Java to it CryptoPro JavaCSP, but you must specify JavaCSP in your software

2)You can use CryptoPro JCP 2.0. There is .jar with examples: samples.jar samples-sources.jar including xmlSign in its distribution.

When you sign with two keys, you should sign only the data. When you sign with the second signature, the first signature is not signed

To avoid the "UnrecoverableKeyException: Get Key failed" error, you need to transfer the keys and certificate from the * .pfx repository to the HDImageStore repository (this will be a folder with 6 * .key files), which Java distinguishes with installed CryptoPro (more details https://www.cryptopro.ru/forum2/default.aspx?g=posts&t=8271)

Examples of implementation and signed documents: https://github.com/Host-to-Host-Instructions/iso20022-signature

Signature Formation Example
<CstmrCdtTrfInitn>
    ...
    <SplmtryData>
        <Envlp>
            <SgntrSt>
                <Signature хmlns="http://www.w3.org/2000/09/xmldsig#">
                    {ЭП #1 …}
                </Signature>

                <Signature хmlns="http://www.w3.org/2000/09/xmldsig#">
                    {ЭП #2 …}
                </Signature>
            </SgntrSt>
        </Envlp>
    </SplmtryData>
</CstmrCdtTrfInitn>
Example request summary extract with signature
<?xml version="1.0" encoding="UTF-8"?>
<p:Document xmlns:p="urn:iso:std:iso:20022:tech:xsd:camt.060.001.03" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:camt.060.001.03">
    <p:AcctRptgReq>
        <p:GrpHdr>
            <p:MsgId>MSG_20170830_test_55</p:MsgId>
            <p:CreDtTm>2017-05-26T12:00:00</p:CreDtTm>
        </p:GrpHdr>
        <p:RptgReq>
            <p:Id>REQ_20170830_test_55</p:Id>
            <p:ReqdMsgNmId>HMQSTASCF</p:ReqdMsgNmId>
            <p:Acct>
                <p:Id>
                    <p:Othr>
                        <p:Id>40702810200000000083</p:Id>
                    </p:Othr>
                </p:Id>
            </p:Acct>
            <p:AcctOwnr>
                <p:Pty>
                    <p:Nm>ООО "Тест Альфа-Линк"</p:Nm>
                </p:Pty>
            </p:AcctOwnr>
            <p:RptgPrd>
                <p:FrToDt>
                    <p:FrDt>2017-02-23</p:FrDt>
                    <p:ToDt>2017-02-23</p:ToDt>
                </p:FrToDt>
                <p:FrToTm>
                    <p:FrTm>00:00:00</p:FrTm>
                    <p:ToTm>24:00:00</p:ToTm>
                </p:FrToTm>
                <p:Tp>ALLL</p:Tp>
            </p:RptgPrd>
        </p:RptgReq>
        <p:RptgReq>
            <p:Id>REQ_20170830_test_56</p:Id>
            <p:ReqdMsgNmId>HMQSTASCF</p:ReqdMsgNmId>
            <p:Acct>
                <p:Id>
                    <p:Othr>
                        <p:Id>40702810100000000921</p:Id>
                    </p:Othr>
                </p:Id>
            </p:Acct>
            <p:AcctOwnr>
                <p:Pty>
                    <p:Nm>ООО "Тест Альфа-Линк"</p:Nm>
                </p:Pty>
            </p:AcctOwnr>
            <p:RptgPrd>
                <p:FrToDt>
                    <p:FrDt>2017-02-23</p:FrDt>
                    <p:ToDt>2017-02-23</p:ToDt>
                </p:FrToDt>
                <p:FrToTm>
                    <p:FrTm>00:00:00</p:FrTm>
                    <p:ToTm>24:00:00</p:ToTm>
                </p:FrToTm>
                <p:Tp>ALLL</p:Tp>
            </p:RptgPrd>
        </p:RptgReq>
        <p:SplmtryData>
            <p:Envlp>
                <SgntrSt>
                    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="sigID1">
                        <ds:SignedInfo>
                            <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                            <ds:SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256"/>
                            <ds:Reference URI="">
                                <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="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256"/>
                                <ds:DigestValue>Xv/EW5v1khoK3nKbs3GVK5JtFW6Ij4sl7i17Vk+zkhA=</ds:DigestValue>
                            </ds:Reference>
                        </ds:SignedInfo>
                        <ds:SignatureValue>dPJn/pPMbY3If7iThchSUnhLiCv40FMiOkxxBtQ3gKtCAi2xvHq0u17xsLCQr5nVW13PG02+8SsKF0ohqv+gug==</ds:SignatureValue>
                        <ds:KeyInfo>
                            <ds:X509Data>
                                <ds:X509Certificate>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</ds:X509Certificate>
                            </ds:X509Data>
                        </ds:KeyInfo>
                    </ds:Signature>
                </SgntrSt>
            </p:Envlp>
        </p:SplmtryData>
    </p:AcctRptgReq>
</p:Document>

Getting test certificates

We strongly recommend using the certificates from certificates folder in the archive of this documentation.

If there is a reason why you need to use your own certificates, you will find instructions for issuing self-signed certificates on MacOs below. Please note that certificates issued by CryptoPro are NOT suitable for testing.

For issuing self-signed test certificates on MacOs :

  1. Run in terminal:

brew install openssl
brew install cmake
brew install git
git clone https://github.com/gost-engine/engine
cd engine
git submodule update --init
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release .. -DOPENSSL_ENGINES_DIR=/usr/local/opt/openssl@3/lib/engines-3
cmake --build . --target install --config Release
  • Check that "gost.dylib" file has appeared by entering command:

ls -l /usr/local/opt/openssl@3/lib/engines-3/
  • In the file /usr/local/etc/openssl@3/openssl.cnf Add the line "openssl_conf = openssl_def"

    1. if openssl_conf = openssl_init exists, then after this line

    2. if openssl_conf = openssl_init doesnt exists - then at the beginning of the file

  • At the end of the file add the following 3 sections:

[openssl_def]
engines = engine_section

[engine_section]
gost = gost_section

[gost_section]
engine_id = gost
dynamic_path = /usr/local/opt/openssl@3/lib/engines-3/gost.dylib
default_algorithms = ALL
CRYPT_PARAMS = id-Gost28147-89-CryptoPro-A-ParamSet

dynamic_path = /usr/local/opt/openssl@3/lib/engines-3/gost.dylib - it is a path to the library generated above

  • Save file

Standard openssl may not provide a link to the required binary, so you need to change the link or access the binary directly /usr/local/opt/openssl@3/bin/openssl

  • Reopen the terminal

  • Generate key

The extension can be selected: pem/key/crt

openssl req -x509 -nodes -days 365 -newkey gost2012_256 -pkeyopt paramset:A -keyout privateKey.key -out certificate.crt
  • Fill in all fields (using Latin letters only):

    1. Country Name (2 letter code) [AU]:

    2. State or Province Name (full name) [Some-State]:

    3. Locality Name (eg, city) []:

    4. Organization Name (eg, company) [Internet Widgits Pty Ltd]:

    5. Organizational Unit Name (eg, section) []:

    6. Common Name (e.g. server FQDN or YOUR name) []:

    7. Email Address[]:

  • Build file pkcs12 or pfx

openssl pkcs12 -export -in certificate.crt -inkey privateKey.key \
-out privateKey.p12 -name privateKey \
-CAfile ca.crt -caname root

Send the public key (file format .cer/.crt) in the archive .zip to the address ASedov@alfabank.ru with the theme "Connecting to the Host-to-host test stand"