UNPKG

futoin-secvault

Version:

FutoIn Secure Vault reference implementation

625 lines (460 loc) 19.3 kB
[![NPM Version](https://img.shields.io/npm/v/futoin-secvault.svg?style=flat)](https://www.npmjs.com/package/futoin-secvault) [![NPM Downloads](https://img.shields.io/npm/dm/futoin-secvault.svg?style=flat)](https://www.npmjs.com/package/futoin-secvault) [![Build Status](https://travis-ci.org/futoin/core-js-ri-secvault.svg)](https://travis-ci.org/futoin/core-js-ri-secvault) [![stable](https://img.shields.io/badge/stability-stable-green.svg?style=flat)](https://www.npmjs.com/package/futoin-secvault) [![NPM](https://nodei.co/npm/futoin-secvault.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/futoin-secvault/) # About FutoIn Secure Vault (SV) is a concept to minimize sensitive cryptographic data exposure in projects. It allows different type of key management, data encryption and signing. This reference implementation is based on encrypted SQL storage. However, the same interface can be implemented in Host Secure Modules (HSM) on demand. Features: * Key types: - AES - RSA - HMAC - Password (plain password) * Key derivation: - PBKDF2 - HKDF * Key manipulations: - Generation - Injection - Encrypted injection - Plain exposure - Encrypted exposure - Wipe out - Derivation - Public key exposure * Data manipulations - Encryption & Decryption - Signing & Verification **Documentation** --> [FutoIn Guide](https://futoin.org/docs/secvault/) Reference implementation of: * [FTN13: FutoIn Secure Vault](https://specs.futoin.org/final/preview/ftn13_secure_vault.html) Author: [Andrey Galkin](mailto:andrey@futoin.org) # Installation for Node.js Command line: ```sh $ npm install futoin-secvault --save ``` or: ```sh $ yarn add futoin-secvault --save ``` # Examples ```javascript ``` # API documentation ## Classes <dl> <dt><a href="#DataFace">DataFace</a></dt> <dd><p>Data Face</p> </dd> <dt><a href="#DataService">DataService</a></dt> <dd><p>Data Service</p> </dd> <dt><a href="#KeyFace">KeyFace</a></dt> <dd><p>Keys Face</p> </dd> <dt><a href="#KeyService">KeyService</a></dt> <dd><p>Key Service</p> </dd> <dt><a href="#BaseFace">BaseFace</a></dt> <dd><p>Base Face with neutral common registration functionality</p> </dd> <dt><a href="#BaseService">BaseService</a></dt> <dd><p>Base Service with common registration logic</p> </dd> <dt><a href="#AESPlugin">AESPlugin</a></dt> <dd><p>AES plugin</p> </dd> <dt><a href="#HKDFPlugin">HKDFPlugin</a></dt> <dd><p>HKDF plugin</p> </dd> <dt><a href="#HMACPlugin">HMACPlugin</a></dt> <dd><p>HMAC plugin</p> </dd> <dt><a href="#PasswordPlugin">PasswordPlugin</a></dt> <dd><p>Password plugin</p> <p>Allows passwords from 4 to 255 unicode characters in length. Supports custom characters set through options.chars.</p> <p>Supports secure password verification.</p> </dd> <dt><a href="#PBKDF2Plugin">PBKDF2Plugin</a></dt> <dd><p>PBKDF2 plugin</p> </dd> <dt><a href="#RSAPlugin">RSAPlugin</a></dt> <dd><p>RSA plugin</p> </dd> <dt><a href="#VaultPlugin">VaultPlugin</a></dt> <dd><p>Base for SecVault plugins</p> </dd> <dt><a href="#CachedStorageWrapper">CachedStorageWrapper</a></dt> <dd><p>Storage wapper with advanced caching &amp; invalidation</p> </dd> <dt><a href="#DBStorage">DBStorage</a></dt> <dd><p>Database Encrypted secret storage</p> </dd> <dt><a href="#EncryptedStorage">EncryptedStorage</a></dt> <dd><p>Encrypted secret storage base</p> <p>Assume there is</p> </dd> <dt><a href="#KeyInfo">KeyInfo</a></dt> <dd><p>Sealed key info</p> </dd> <dt><a href="#SQLStorage">SQLStorage</a></dt> <dd><p>SQL secret storage</p> </dd> <dt><a href="#Storage">Storage</a></dt> <dd><p>Secret storage base</p> </dd> </dl> <a name="DataFace"></a> ## DataFace Data Face **Kind**: global class <a name="DataService"></a> ## DataService Data Service **Kind**: global class <a name="KeyFace"></a> ## KeyFace Keys Face **Kind**: global class <a name="KeyService"></a> ## KeyService Key Service **Kind**: global class <a name="BaseFace"></a> ## BaseFace Base Face with neutral common registration functionality **Kind**: global class **Note**: Not official API * [BaseFace](#BaseFace) * [.LATEST_VERSION](#BaseFace.LATEST_VERSION) * [.PING_VERSION](#BaseFace.PING_VERSION) * [.register(as, ccm, name, endpoint, [credentials], [options])](#BaseFace.register) <a name="BaseFace.LATEST_VERSION"></a> ### BaseFace.LATEST\_VERSION Latest supported FTN13 version **Kind**: static property of [<code>BaseFace</code>](#BaseFace) <a name="BaseFace.PING_VERSION"></a> ### BaseFace.PING\_VERSION Latest supported FTN4 version **Kind**: static property of [<code>BaseFace</code>](#BaseFace) <a name="BaseFace.register"></a> ### BaseFace.register(as, ccm, name, endpoint, [credentials], [options]) CCM registration helper **Kind**: static method of [<code>BaseFace</code>](#BaseFace) | Param | Type | Default | Description | | --- | --- | --- | --- | | as | <code>AsyncSteps</code> | | steps interface | | ccm | <code>AdvancedCCM</code> | | CCM instance | | name | <code>string</code> | | CCM registration name | | endpoint | <code>\*</code> | | see AdvancedCCM#register | | [credentials] | <code>\*</code> | <code></code> | see AdvancedCCM#register | | [options] | <code>object</code> | <code>{}</code> | interface options | | [options.version] | <code>string</code> | <code>&quot;1.0&quot;</code> | interface version to use | <a name="BaseService"></a> ## BaseService Base Service with common registration logic **Kind**: global class * [BaseService](#BaseService) * [new BaseService(storage, options)](#new_BaseService_new) * [.register(as, executor, storage, options)](#BaseService.register) ⇒ <code>LimitsService</code> <a name="new_BaseService_new"></a> ### new BaseService(storage, options) C-tor | Param | Type | Default | Description | | --- | --- | --- | --- | | storage | [<code>Storage</code>](#Storage) | | low-level storage instance | | options | <code>object</code> | | passed to superclass c-tor | | options.failure_limit | <code>integer</code> | <code>10000</code> | limit crypt key decrypt failures | <a name="BaseService.register"></a> ### BaseService.register(as, executor, storage, options) ⇒ <code>LimitsService</code> Register futoin.xfers.limits interface with Executor **Kind**: static method of [<code>BaseService</code>](#BaseService) **Returns**: <code>LimitsService</code> - instance | Param | Type | Description | | --- | --- | --- | | as | <code>AsyncSteps</code> | steps interface | | executor | <code>Executor</code> | executor instance | | storage | [<code>Storage</code>](#Storage) | low-level storage instance | | options | <code>object</code> | implementation defined options | <a name="AESPlugin"></a> ## AESPlugin AES plugin **Kind**: global class <a name="AESPlugin.register"></a> ### AESPlugin.register() Register this plugin **Kind**: static method of [<code>AESPlugin</code>](#AESPlugin) <a name="HKDFPlugin"></a> ## HKDFPlugin HKDF plugin **Kind**: global class <a name="HKDFPlugin.register"></a> ### HKDFPlugin.register() Register this plugin **Kind**: static method of [<code>HKDFPlugin</code>](#HKDFPlugin) <a name="HMACPlugin"></a> ## HMACPlugin HMAC plugin **Kind**: global class <a name="HMACPlugin.register"></a> ### HMACPlugin.register() Register this plugin **Kind**: static method of [<code>HMACPlugin</code>](#HMACPlugin) <a name="PasswordPlugin"></a> ## PasswordPlugin Password plugin Allows passwords from 4 to 255 unicode characters in length. Supports custom characters set through options.chars. Supports secure password verification. **Kind**: global class <a name="PasswordPlugin.register"></a> ### PasswordPlugin.register() Register this plugin **Kind**: static method of [<code>PasswordPlugin</code>](#PasswordPlugin) <a name="PBKDF2Plugin"></a> ## PBKDF2Plugin PBKDF2 plugin **Kind**: global class <a name="PBKDF2Plugin.register"></a> ### PBKDF2Plugin.register() Register this plugin **Kind**: static method of [<code>PBKDF2Plugin</code>](#PBKDF2Plugin) <a name="RSAPlugin"></a> ## RSAPlugin RSA plugin **Kind**: global class <a name="RSAPlugin.register"></a> ### RSAPlugin.register() Register this plugin **Kind**: static method of [<code>RSAPlugin</code>](#RSAPlugin) <a name="VaultPlugin"></a> ## VaultPlugin Base for SecVault plugins **Kind**: global class * [VaultPlugin](#VaultPlugin) * _instance_ * [.defaultBits()](#VaultPlugin+defaultBits) * [.isAsymetric()](#VaultPlugin+isAsymetric) ⇒ <code>boolean</code> * [.generate(as, options)](#VaultPlugin+generate) * [.validateKey(as, key)](#VaultPlugin+validateKey) * [.derive(as, base, bits, hash, options)](#VaultPlugin+derive) * [.pubkey(as, key, options)](#VaultPlugin+pubkey) * [.encrypt(as, key, data, options)](#VaultPlugin+encrypt) * [.decrypt(as, key, edata, options)](#VaultPlugin+decrypt) * [.sign(as, key, data, options)](#VaultPlugin+sign) * [.verify(as, key, edata, sig, options)](#VaultPlugin+verify) * [.random(as, size)](#VaultPlugin+random) * _static_ * [.registerPlugin(name, impl)](#VaultPlugin.registerPlugin) * [.getPlugin(name)](#VaultPlugin.getPlugin) ⇒ [<code>VaultPlugin</code>](#VaultPlugin) <a name="VaultPlugin+defaultBits"></a> ### vaultPlugin.defaultBits() Default bits to use, if applicable **Kind**: instance method of [<code>VaultPlugin</code>](#VaultPlugin) <a name="VaultPlugin+isAsymetric"></a> ### vaultPlugin.isAsymetric() ⇒ <code>boolean</code> Check if type conforms to asymmetric cryptography requirements **Kind**: instance method of [<code>VaultPlugin</code>](#VaultPlugin) **Returns**: <code>boolean</code> - true, if assymetric <a name="VaultPlugin+generate"></a> ### vaultPlugin.generate(as, options) Generate new key **Kind**: instance method of [<code>VaultPlugin</code>](#VaultPlugin) **Note**: passes raw key buffer to the next step | Param | Type | Description | | --- | --- | --- | | as | <code>AsyncSteps</code> | AsyncSteps interface | | options | <code>object</code> | implementation-defined options | | options.bits | <code>integer</code> | key length, if applicable | <a name="VaultPlugin+validateKey"></a> ### vaultPlugin.validateKey(as, key) Validate key data **Kind**: instance method of [<code>VaultPlugin</code>](#VaultPlugin) | Param | Type | Description | | --- | --- | --- | | as | <code>AsyncSteps</code> | AsyncSteps interface | | key | <code>Buffer</code> | key data to validate | <a name="VaultPlugin+derive"></a> ### vaultPlugin.derive(as, base, bits, hash, options) Derive new key **Kind**: instance method of [<code>VaultPlugin</code>](#VaultPlugin) **Note**: passes raw key buffer to the next step | Param | Type | Default | Description | | --- | --- | --- | --- | | as | <code>AsyncSteps</code> | | AsyncSteps interface | | base | <code>Buffer</code> | | base key as is | | bits | <code>integer</code> | | key length | | hash | <code>string</code> | | hash name to use | | options | <code>object</code> | | implementation-defined options | | options.salt | <code>string</code> | <code>&quot;&#x27;&#x27;&quot;</code> | salt, if any | | options.info | <code>string</code> | <code>&quot;&#x27;&#x27;&quot;</code> | info, if any | | options.rounds | <code>integer</code> | <code>1000</code> | rounds, if any | <a name="VaultPlugin+pubkey"></a> ### vaultPlugin.pubkey(as, key, options) Get public key from private key **Kind**: instance method of [<code>VaultPlugin</code>](#VaultPlugin) **Note**: passes raw key buffer to the next step | Param | Type | Description | | --- | --- | --- | | as | <code>AsyncSteps</code> | AsyncSteps interface | | key | <code>Buffer</code> | raw private key | | options | <code>object</code> | implementation-defined options | <a name="VaultPlugin+encrypt"></a> ### vaultPlugin.encrypt(as, key, data, options) Encrypt arbitrary data **Kind**: instance method of [<code>VaultPlugin</code>](#VaultPlugin) **Note**: Passes Buffer { edata | iv | authtag } to the next step | Param | Type | Default | Description | | --- | --- | --- | --- | | as | <code>AsyncSteps</code> | | AsyncSteps interface | | key | <code>Buffer</code> | | raw key | | data | <code>Buffer</code> | | raw data | | options | <code>object</code> | | implementation-defined options | | options.iv | <code>Buffer</code> | <code></code> | custom IV, if needed | | options.aad | <code>Buffer</code> | <code></code> | additional data, if supported | <a name="VaultPlugin+decrypt"></a> ### vaultPlugin.decrypt(as, key, edata, options) Decrypt arbitrary data **Kind**: instance method of [<code>VaultPlugin</code>](#VaultPlugin) **Note**: Passes Buffer of raw data to the next step | Param | Type | Description | | --- | --- | --- | | as | <code>AsyncSteps</code> | AsyncSteps interface | | key | <code>Buffer</code> | raw key | | edata | <code>object</code> | encrypted data as generated by encrypt | | options | <code>object</code> | implementation-defined options | | options.aad | <code>string</code> | additional authentication data, if applicable | <a name="VaultPlugin+sign"></a> ### vaultPlugin.sign(as, key, data, options) Encrypt arbitrary data **Kind**: instance method of [<code>VaultPlugin</code>](#VaultPlugin) **Note**: Passes Buffer { sig } to the next step | Param | Type | Description | | --- | --- | --- | | as | <code>AsyncSteps</code> | AsyncSteps interface | | key | <code>Buffer</code> | raw key | | data | <code>Buffer</code> | raw data | | options | <code>object</code> | implementation-defined options | | options.hash | <code>string</code> | hash name, if applicable | <a name="VaultPlugin+verify"></a> ### vaultPlugin.verify(as, key, edata, sig, options) Decrypt arbitrary data **Kind**: instance method of [<code>VaultPlugin</code>](#VaultPlugin) **Note**: Passes Buffer of raw data to the next step | Param | Type | Description | | --- | --- | --- | | as | <code>AsyncSteps</code> | AsyncSteps interface | | key | <code>Buffer</code> | raw key | | edata | <code>object</code> | encrypted data as generated by encrypt | | sig | <code>Buffer</code> | signature to verify | | options | <code>object</code> | implementation-defined options | | options.hash | <code>string</code> | hash name, if applicable | <a name="VaultPlugin+random"></a> ### vaultPlugin.random(as, size) Common API to generate random data **Kind**: instance method of [<code>VaultPlugin</code>](#VaultPlugin) **Note**: Passes Buffer of renadom data to the next step | Param | Type | Description | | --- | --- | --- | | as | <code>AsyncSteps</code> | AsyncSteps interface | | size | <code>integer</code> | how many bytes to generate | <a name="VaultPlugin.registerPlugin"></a> ### VaultPlugin.registerPlugin(name, impl) Register plugin **Kind**: static method of [<code>VaultPlugin</code>](#VaultPlugin) | Param | Type | Description | | --- | --- | --- | | name | <code>string</code> | plugin identifier | | impl | [<code>VaultPlugin</code>](#VaultPlugin) | plugin implementation | <a name="VaultPlugin.getPlugin"></a> ### VaultPlugin.getPlugin(name) ⇒ [<code>VaultPlugin</code>](#VaultPlugin) Get plugin by name **Kind**: static method of [<code>VaultPlugin</code>](#VaultPlugin) **Returns**: [<code>VaultPlugin</code>](#VaultPlugin) - plugin instance | Param | Type | Description | | --- | --- | --- | | name | <code>string</code> | plugin identifier | <a name="CachedStorageWrapper"></a> ## CachedStorageWrapper Storage wapper with advanced caching & invalidation **Kind**: global class <a name="new_CachedStorageWrapper_new"></a> ### new CachedStorageWrapper(ccm, target, options) C-tor | Param | Type | Description | | --- | --- | --- | | ccm | <code>AdvancedCCM</code> | CCM instance | | target | [<code>Storage</code>](#Storage) | target slow storage | | options | <code>object</code> | extra options for fine tune | | options.evtpushExecutor | <code>object</code> | executor instace with PushService | | [options.cacheSize] | <code>integer</code> | max cache entries | | [options.ttlMs] | <code>integer</code> | Cache Time-To-Live in ms | | [options.syncDelayMs] | <code>integer</code> | Cache Sync delay in ms | | [options.syncThreads] | <code>integer</code> | Cache Sync parallelism | <a name="DBStorage"></a> ## DBStorage Database Encrypted secret storage **Kind**: global class <a name="EncryptedStorage"></a> ## EncryptedStorage Encrypted secret storage base Assume there is **Kind**: global class * [EncryptedStorage](#EncryptedStorage) * [.setStorageSecret(as, secret, cipher_opts, kdf_opts)](#EncryptedStorage+setStorageSecret) * [.isLocked()](#EncryptedStorage+isLocked) ⇒ <code>boolean</code> <a name="EncryptedStorage+setStorageSecret"></a> ### encryptedStorage.setStorageSecret(as, secret, cipher_opts, kdf_opts) Configure common storage secret which is used to encrypt keys **Kind**: instance method of [<code>EncryptedStorage</code>](#EncryptedStorage) | Param | Type | Default | Description | | --- | --- | --- | --- | | as | <code>AsyncSteps</code> | | AsyncSteps interface | | secret | <code>Buffer</code> | | some arbitrary secret | | cipher_opts | <code>object</code> | <code>{}</code> | options for encryption/decryption | | cipher_opts.type | <code>string</code> | <code>&quot;AES&quot;</code> | cipher type | | cipher_opts.bits | <code>integer</code> | <code>256</code> | key length for KDF | | cipher_opts.mode | <code>string</code> | <code>&quot;GCM&quot;</code> | cipher block mode | | cipher_opts.aad | <code>string</code> | <code>&quot;SecVault&quot;</code> | additional auth data | | kdf_opts | <code>object</code> \| <code>null</code> | <code>{}</code> | KDF options, null to disable | | kdf_opts.type | <code>string</code> | <code>&quot;HKDF&quot;</code> | KDF type | | kdf_opts.salt | <code>string</code> | <code>&quot;SecVault&quot;</code> | KDF salt | | kdf_opts.info | <code>string</code> | <code>&quot;KEK&quot;</code> | info parameter for HKDF | | kdf_opts.rounds | <code>string</code> | <code>1000</code> | rounds for PBKDF2 | <a name="EncryptedStorage+isLocked"></a> ### encryptedStorage.isLocked() ⇒ <code>boolean</code> Check if storage is locked **Kind**: instance method of [<code>EncryptedStorage</code>](#EncryptedStorage) **Returns**: <code>boolean</code> - true, if locked <a name="KeyInfo"></a> ## KeyInfo Sealed key info **Kind**: global class <a name="new_KeyInfo_new"></a> ### new KeyInfo(info) C-tor | Param | Type | Default | Description | | --- | --- | --- | --- | | info | <code>object</code> | <code>{}</code> | optional default values | <a name="SQLStorage"></a> ## SQLStorage SQL secret storage **Kind**: global class <a name="new_SQLStorage_new"></a> ### new SQLStorage(ccm, options) C-tor | Param | Type | Default | Description | | --- | --- | --- | --- | | ccm | <code>AdvancedCCM</code> | | CCM instance with registered 'secvault' DB | | options | <code>object</code> | | options | | options.key_table | <code>string</code> | <code>&quot;enc_keys&quot;</code> | name of encrypted key table | <a name="Storage"></a> ## Storage Secret storage base **Kind**: global class