There is a few difficulties in how to start signing content in NodeJS with GOST algorithms. Let's fight with them.
Configuring OpenSSL
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.
Open 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:
openssl_conf=openssl_def
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
dynamic_path
in gost_section
: [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 ofgost.dll
lying next toopenssl.exe
and it's enough due to dynamic-link library search order. Anyway, you can specify full path togost.dll
here too.
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);
Now, signedContent
is instance of Buffer class containing signed data.
Note that location of
libgost.so
may be different in your system. You can find actual location withfind / 2> /dev/null | grep libgost
command 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);
Now, verificationResult
will contain true
if signature is valid and false
in other cases.
Summary
To start signing you should turn on GOST support in OpenSSL, use GOST engine in NodeJS and use private key in PEM format.
Happy signing!
Comments