NaviServer - programmable web server
4.99  5.0

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

ns_crypto(n) 4.99.30 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::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://tools.ietf.org/id/draft-ietf-webpush-vapid-03.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? ?-n r? ?-n p? ?-encoding encoding? nrbytes

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 requires at least OpenSSL 1.1.1.

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