There is a few difficulties in how to start signing content in NodeJS with GOST algorithms. Let's fight with them.
NodeJS uses OpenSSL under the hood and can do all the things that OpenSSL do. OpenSSL has ccgost engine with GOST algorighms, they are turned off by default. But you can turn it on manually.
openssl.cnf file in your favorite editor (the path is
/etc/ssl/openssl.cnf in Linux and
<OpenSSL-Installation-Directory>\bin\openssl.cnf in Windows).
Add following line just in first line of config:
then add following lines in the end of the file:
[openssl_def] engines = engine_section [engine_section] gost = gost_section [gost_section] default_algorithms = ALL CRYPT_PARAMS = id-Gost28147-89-CryptoPro-A-ParamSet
[openssl_def] engines = engine_section [engine_section] gost = gost_section [gost_section] dynamic_path=gost default_algorithms = ALL CRYPT_PARAMS = id-Gost28147-89-CryptoPro-A-ParamSet
Note that I'm not specifying full path here, because of
gost.dlllying next to
openssl.exeand it's enough due to dynamic-link library search order. Anyway, you can specify full path to
You can verify OpenSSL configuration:
> openssl ciphers | tr ':' '\n' | grep GOST GOST2001-GOST89-GOST89 GOST94-GOST89-GOST89 > openssl list-message-digest-algorithms | grep gost gost-mac md_gost94 gost-mac md_gost94 > openssl list-cipher-algorithms | grep gost gost89 gost89 gost89-cnt
> openssl list-message-digest-algorithms | findstr gost gost-mac md_gost94 gost-mac md_gost94 > openssl list-cipher-algorithms | findstr gost gost89 gost89 gost89-cnt
Signing with GOST in NodeJS
There is crypto module in NodeJS out of the box. To do signing you should:
- set OpenSSL engine with GOST support: it is usually full path to libgost.so (Linux) or gost.dll (Windows)
- create instance of Sign class
- fill Sign class with data
- and, finally, create signature
const crypto = require('crypto'); const fs = require('fs'); // set engine with GOST support (you need execute it only once on application startup time): crypto.setEngine('/usr/lib/x86_64-linux-gnu/openssl-1.0.0/engines/libgost.so'); // create Sign class: const sign = crypto.createSign('md_gost94'); // fill Sign class with the data sign.update('some data'); // signing the content with private key var privateKey = fs.readFileSync('privateKey.pem').toString(); var signedContent = sign.sign(privateKey);
signedContent is instance of Buffer class containing signed data.
Note that location of
libgost.somay be different in your system. You can find actual location with
find / 2> /dev/null | grep libgostcommand in Linux.
Preparing private and public keys
NodeJS expects private and public keys in PEM format. Usually you can export both keys to PFX container and then convert it to PEM using OpenSSL command line utility:
openssl pkcs12 -in certificate.pfx -out certificate.pem -nodes
After this command, you'll find both keys in the
certificate.pem file in base64 encoding.
Signing verification in NodeJS
Verification in NodeJS is very similar to signing:
- you need to create instance of Verify class
- fill Verify class with data
- and, finally, verify it with previous signature
// create Verify class var verify = crypto.createVerify('md_gost94'); // fill it with data verify.update('some data'); // verify signature with public key var publicKey = fs.readFileSync("publicKey.pem").toString(); var verificationResult = verify.verify(publicKey, signature);
verificationResult will contain
true if signature is valid and
false in other cases.
To start signing you should turn on GOST support in OpenSSL, use GOST engine in NodeJS and use private key in PEM format.