NaviServer - programmable web server
4.99  5.0

[ Main Table Of Contents | Table Of Contents | Keyword Index ]

ns_crypto(n) 5.0.0a naviserver "NaviServer Built-in Commands"

Name

ns_crypto - Low level cryptographic functions based on the OpenSSL crypto library

Table Of Contents

Synopsis

Description

These functions perform low-level cryptographic functions based on the OpenSSL crypto library. These commands are only implemented when NaviServer was compiled with OpenSSL support. The level of support depends on the version of OpenSSL. Versions earlier than OpenSSL 1.0 are not supported.

For some higher level functions (e.g. performing e.g. digest or HMAC operations of huge amounts of data) see e.g.ns_md and ns_hmac.

Note: some common options are described in a separate section below.

COMMANDS

ns_crypto::aead::encrypt string ?-binary? ?-aad aad? ?-cipher cipher? ?-encoding encoding? ?-iv iv? ?-key key? input

encrypt data following the Authenticated Encryption with Associated Data (AEAD) scheme, which provides confidentiality, integrity, and authenticity. Currently, only GCM mode (Galois/Counter Mode) is supported. For details about AEAD in GCM mode, see e.g. https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf

AEAD has the following properties:

Secrecy

Nobody will be able to get any information about the encrypted plaintext, except the length.

Authenticity

Without the key it is impossible to change the plaintext underlying the ciphertext undetected.

Symmetric

Encrypting the message and decrypting the ciphertext is done with the same key.

Randomization

The encryption is randomized. Two messages with the same plaintext will not yield the same ciphertext. This prevents attackers from knowing which ciphertext corresponds to a given plaintext.

The function returns a dict consisting of bytes and the authentication tag used for decryption.

The option -aad can be used to specify Additional Authenticated Data (AAD), which is data handled by encryption, which is sent in clear text. The encryption still provides authenticity for AAD. AAD can be used e.g. for addresses, ports, sequence numbers, protocol version numbers.

The option -cipher can be used to specify the used cipher such as e.g. aes-128-gcm (default) or aes-256-gcm. Possible values are defined by OpenSSL.

The option -iv specifies the initialization vector (IV) for encryption. IV is essentially a nonce value, a value that is unique within the specified context (see the NIST publication for details).

The option -key specifies the key for the encryption.

The argument input is the data to be encrypted.

When the option -binary is specified, it applies to -key, -aad, -iv, input.

 % ns_crypto::aead::encrypt string -cipher aes-128-gcm -iv 123456789 -key secret "hello world"
 bytes fa260f97eae35e3e3df0b7 tag 93654f78fd189b559c091acb410a0040
ns_crypto::aead::decrypt string ?-binary? ?-aad aad? ?-cipher cipher? ?-encoding encoding? ?-iv iv? ?-key key? ?-tag tag? input

This function implements the inverse function of ns_crypto::aead::encrypt string. Note that the resulting tag of the encryption result is used as an input for decryption. The result is a byte string of the decrypted input (no dict).

When the option -binary is specified, it applies to -key, -aad, -iv, and -tag. The argument input (the cipher text) is always treated as byte array.

 % set d [ns_crypto::aead::encrypt string -cipher aes-128-gcm -iv 123456789 \
    -key secret -encoding binary \
    "hello world"]
 % ns_crypto::aead::decrypt string -cipher aes-128-gcm -iv 123456789 \
    -key secret -tag [dict get $d tag] \
    -encoding binary [dict get $d bytes]
ns_crypto::argon2 ?-binary? ?-password password? ?-salt salt? ?-ad ad? ?-iter iter? ?-lanes lanes? ?-memcost memcost? ?-outlen outlen? ?-secret secret? ?-threads threads? ?-variant Argon2id|Argon2i|Argon2d?

Compute a password hash or a derived key based on the Argon2 family of functions (RFC 9106, published in 2021) and return the hash (named "tag" in the RFC) in the specified encoding (default hex).

Argon2 is a modern replacement for crypt and bcrypt and derives more secret keys from a secret string. Argon2 was selected as the winner of the 2015 Password Hashing Competition and is the recommended password hashing algorithm of the OWASP project. The algorithm is defined in 3 different variants, named Argon2d (providing resistance GPU cracking attacks), Argon2i (resist side-channel attacks) and Argon2id (hybrid version, based on Argon2d and Argon2i).

Argon2 has several parameters to provide control over execution time, required memory, and degree of parallelism to tailor security requirements of a site, to provide high security against modern password cracking hardware. The function requires the compilation of NaviServer against OpenSSL 3.2 or newer. The names of the parameters correspond to the names of the parameters provided for the C-level API, so additional information can be obtained from the OpenSSL documentation.

When the option -binary is specified, it applies to the input parameters -ad, -password, -salt, and -secret.

The provided -salt must be at least 8 bytes.

The option -iter can be used to specify the number of iterations of the algorithm (sometimes named "passes"). The default value is 3.

The option -lanes can be used to specify the number of memory segments that can be processed in parallel. The number of used threads depends on the -threads parameter. The provided value influences the result. The default value of "lanes" is 1.

The option -memcost can be used to specify the memory cost specified in 1 KB blocks. The default value is 1024 (i.e. 1 MB).

The option -outlen can be used to specify the length of the resulting tag in bytes. The default value is 64.

The option -secret can be used to specify an additional secret (sometimes called pepper) to be used an optional secret data used along the password.

The option -threads can be used to specify the number of threads for the computation of the lanes. The provided value does not influence the result, but just the duration of the command. The default value is 1.

The option -variant can be used to specify the variant of the command. The default value is "Argon2id".

 % ::ns_crypto::argon2 -variant argon2id -salt saltsalt -password 42 -outlen 16
 d508696098fa42e70058a3141d1c7464
ns_crypto::eckey generate ?-name name? -pem pem

Generate an EC pemfile without the need of an external command. If no -name is provided (name of the elliptic curve), prime256v1 is assumed. An other popular candidate is secp384r1. The -pem denotes the name of the output file, which is in PEM format.

This function requires OpenSSL compiled with EC support enabled.

 % ns_crypto::eckey generate -name prime256v1 -pem /tmp/priv.key.pem
ns_crypto::eckey import ?-binary? ?-string string? ?-encoding encoding?

When the option -binary is specified, it applies to -string.

This function requires OpenSSL compiled with EC support enabled.

ns_crypto::eckey priv ?-encoding encoding? ?-pem pem? ?-passphrase passphrase?

Obtain the private key in various encodings from an elliptic curve PEM file. When the .pem-file is secured by a passphrase, this has to be provided via -passphrase.

This function requires OpenSSL compiled with EC support enabled.

ns_crypto::eckey sharedsecret ?-binary? ?-encoding encoding? ?-passphrase passphrase? ?-pem pem? pubkey

Generate a shared secret based on the private key from the .pem file and the provided public key. When the .pem file is secured by a passphrase, this has to be provided via -passphrase.

When the option -binary is specified, it applies to pubkey.

This function requires OpenSSL 1.1 or newer, compiled with EC support enabled.

ns_crypto::eckey pub ?-pem pem? ?-passphrase passphrase? ?-encoding encoding?

Obtain the public key in various encodings from an elliptic curves PEM file. When the .pem file is secured by a passphrase, this has to be provided via -passphrase.

This function requires OpenSSL compiled with EC support enabled.

ns_crypto::hmac string ?-binary? ?-digest digest? ?-encoding encoding? key message

Return a keyed-hash message authentication code (HMAC) for the specified key and message using the specified message digest algorithm and return it in the specified encoding. An HMAC is a message authentication code of a key (secret) with a message. It may be used to simultaneously verify both the data integrity and the authentication of a message. For details of HMAC, consult RFC 4231.

When the option -binary is specified, it applies to key and message.

 % ns_hmac string -digest sha256 "Jefe" "what do ya want for nothing?"
 5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843

This low-level function operates just on an input string (which has to be in memory). In order to compute HMACs on large data, use ns_hmac.

ns_crypto::md string ?-digest digest? ?-encoding encoding? ?-passphrase passphrase? ?-sign pemfile? ?-signature signatureString? ?-verify pemfile? ?-binary? message

Return a message digest for the provided message and return it in the specified encoding. Optionally, this function can return a signature based on the provided private key, or it can verify such a signature.

When the option -binary is specified, it applies to message.

 % ns_crypto::md string -digest sha256 "what do ya want for nothing?"
 b381e7fec653fc3ab9b178272366b8ac87fed8d31cb25ed1d0e1f3318644c89c

This low-level function operates just on an input string (which has to be in memory). In order to compute digests on large data (such as from files), use ns_md.

The ns_crypto::md string interface can be as well used for digital signing and verification of the signature, when the respective keys are passed in as PEM files. When the PEM file is secured by a passphrase, the option -passphrase ... has to be used to decipher the key.

The option -sign pemfile is used to sign the given message.

The options -verify pemfile and -signature signatureString can be used to verify a signature using the private key from provided PEM file. The signatureString is required to be a binary string, therefore, produced with the output option -encoding binary in the example below:

 % set sig [::ns_crypto::md string \
 	     -digest sha1 \
 	     -encoding binary \
 	     -sign /usr/local/src/naviserver/myprivate.pem \
 	     "abcdefghijklmnopqrstuxvwxyz\n"]
 
 % set vfy [::ns_crypto::md string \
 	     -digest sha1 \
 	     -verify /usr/local/src/naviserver/myprivate.pem \
 	     -signature $sig \
 	     "abcdefghijklmnopqrstuxvwxyz\n"]
 1

The PEM files provided to -sign and -verify are private keys that can have the following key types: CMAC, DSA, ECDSA, HMAC and RSA.

ns_crypto::md hkdf ?-binary? ?-digest digest? ?-salt salt? ?-secret secret? ?-info info? ?-encoding encoding? length

Derive keys based on message digests. See: RFC 5869: HMAC-based Extract-and-Expand Key Derivation Function (HKDF) https://tools.ietf.org/html/rfc5869

When the option -binary is specified, it applies to message.

This function requires OpenSSL 1.1.0.

ns_crypto::md vapidsign ?-digest digest? ?-encoding encoding? ?-passphrase passphrase? ?-pem pem? ?-binary? message

Sign a message according to the Voluntary Application Server Identification (VAPID) for Web Push https://www.rfc-editor.org/rfc/rfc8292.html

Essentially, this is a special form of a signed message digest based on elliptic curve cryptography. See also: Generic Event Delivery Using HTTP Push https://tools.ietf.org/html/rfc8030

The signing key is taken from the provided .pem file. When the .pem file is secured by a passphrase, this has to be provided via -passphrase.

When the option -binary is specified, it applies to message.

This function requires OpenSSL compiled with EC support enabled.

ns_crypto::randombytes ?-encoding encoding? nrbytes

Return the specified number of random bytes in the specified encoding (default hex).

 % ns_crypto::randombytes 20
 3191eb4360a3dc9b5ef667641b264d43aa1019aa
ns_crypto::scrypt ?-binary? ?-secret secret? ?-salt salt? ?-n n? ?-r r? ?-p p? ?-encoding encoding?

Compute a password hash based on the scrypt Password-Based Key Derivation Function (RFC 7914) and return the specified number of random bytes in the specified encoding (default hex).

The scrypt function is a modern replacement for crypt and bcrypt and derives more secret keys from a secret string. It is based on memory-hard functions, which offer added protection against attacks using custom hardware and GPU arrays. The function requires the compilation of NaviServer against OpenSSL 3.0 or newer.

The scrypt function is as well used in many cryptocurrencies as a proof-of-work algorithm.

Colin Percival. 2009. Stronger key derivation via sequential memory-hard functions. In BSDCan 09: The Technical BSD Conference.

When the option -binary is specified, it applies to -salt and -secret.

 % ::ns_crypto::scrypt -secret "password" -salt NaCl -n 1024 -r 8 -p 16
 fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b373162
 2eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640
 
 % time {::ns_crypto::scrypt -secret "password" -salt NaCl -n 1024 -r 8 -p 16}
  42011 microseconds per iteration
ns_crypto::pbkdf2_hmac ?-binary? ?-digest digest? ?-dklen dklen? ?-iterations iterations? ?-salt salt? ?-secret secret? ?-encoding encoding? nrbytes

Compute a password hash based on PBKDF2 (Password-Based Key Derivation Function 2, RFC 2898). This function is used to reduce vulnerabilities of brute-force attacks against password hashes and is used e.g. in SCRAM (Salted Challenge Response Authentication Mechanism). It can be used e.g. for SCRAM-sha1 and SCRAM-sha-256. The hash function of SCRAM is PBKDF2 (RFC2898) with HMAC as the pseudorandom function (PRF) and with dkLen == output length of HMAC == output length of the digest function.

The function has less requirements on the version of OpenSSL than ns_crypto::scrypt.

When the option -binary is specified, it applies to -salt and -secret.

The option -dklen specifies the length of the output key and is by default the same as the output length of the used digest.

The option -iterations specifies the number of iterations (repeated HMAC operations) and defaults to 4096. RFC 7677 recommends 15K iterations.

 % ::ns_crypto::pbkdf2_hmac -secret "password" -iterations 4096 -salt "salt" -digest sha1
 4b007901b765489abead49d926f721d065a429c1
 
 % time {::ns_crypto::pbkdf2_hmac -secret "pass\0word" -iterations 15000 -salt "sa\0lt" -dklen 16}
 16027 microseconds per iteration

OPTIONS

-digest digest

Digest algorithm for the checksum computation. The available algorithms are implemented in OpenSSL. The current versions of OpenSSL supports the following message digest algorithms: "blake2b512 blake2s256 md4 md5 md5-sha1 mdc2 ripemd160 sha1 sha224 sha256 sha3-224 sha3-256 sha3-384 sha3-512 sha384 sha512 sha512-224 sha512-256 shake128 shake256 sm3 whirlpool". The default value is "sha256"

-encoding encoding

The option -encoding encoding specifies the output encoding used for the resulting values of the dict. Possible encodings are hex, base64url, base64, or binary. Default is hex.

-binary

When the option -binary is used, the mentioned input arguments are treated as binary. The Tcl byte array value of the provided input argument is used and no UTF-8 interpretation is performed. When the type of the Tcl value is clearly a binary type (pure/proper byte array) then it is not necessary to use -binary explicitly.

See Also

ns_hmac, ns_md, nsd

Keywords

AEAD, HKDF, HMAC, crypto, ecdsa, random