https://github.com/bkataru/harpo.js
A comprehensive format-preserving-encryption (FPE) implementation for Node.js environments. Built using vanilla ES5 JavaScript.
https://github.com/bkataru/harpo.js
cipher encryption format-preserving-encryption fpe harpo javascript nodejs
Last synced: about 2 months ago
JSON representation
A comprehensive format-preserving-encryption (FPE) implementation for Node.js environments. Built using vanilla ES5 JavaScript.
- Host: GitHub
- URL: https://github.com/bkataru/harpo.js
- Owner: bkataru
- License: mit
- Created: 2019-07-17T02:24:01.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2019-07-19T13:48:59.000Z (almost 6 years ago)
- Last Synced: 2025-03-21T03:06:19.629Z (2 months ago)
- Topics: cipher, encryption, format-preserving-encryption, fpe, harpo, javascript, nodejs
- Language: JavaScript
- Homepage:
- Size: 35.2 KB
- Stars: 5
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# harpo.js
[](https://nodei.co/npm/harpo/)
A comprehensive format-preserving-encryption (FPE) implementation for Node.js.
Built entirely using ES5 vanilla JavaScript and Node's
[crypto](https://nodejs.org/api/crypto.html) module.> An implementation of contemporary format-preserving-encryption algorithms for Node.js environments.
[Format-preserving-encryption](https://en.wikipedia.org/wiki/Format-preserving_encryption) is a type of encryption in
which the format (length, characters, etc) of the output/ciphertext is the same as that of the input.This library implements FPE algorithms from:
- A [prefix cipher](https://en.wikipedia.org/wiki/Format-preserving_encryption#FPE_from_a_prefix_cipher).
This implementation is useful for small domain sizes.
- A recursive [cycle walking algorithm](https://en.wikipedia.org/wiki/Format-preserving_encryption#FPE_from_cycle_walking).
- A [Feistel network](https://en.wikipedia.org/wiki/Format-preserving_encryption#FPE_from_a_Feistel_network).## Changelog
### v0.1 (alpha)
- Alpha build released
- `prefix-cipher` is the only FPE algorithm available.
- Cipher initialization with custom domain options available.
- Basic encryption and decryption functions available.## Further scope
- Implement robust working versions of the `cycle-walking` and `feistel-network` FPE algorithms.
- Functionality to compare the performance and time of the
FPE algorithms using varying input sizes/presets.## Dependencies
- JavaScript :)
- Node.js version 6 and above
- crypto## Quick Start
```js
var harpo = require('harpo');var key = require('crypto').randomBytes(16).toString('hex');
var iv = require('crypto').randomBytes(8).toString('hex');var cipher = harpo.cipher(key, iv);
var text = 'sample-text';// encrypt
cipher.encrypt(text);// decrypt
cipher.decrypt(text);
```## Usage
### cipher(key, iv, fpe_algorithm, cipher_algorithm, domain_options)
To initialize a FPE cipher using harpo.js:
- `key`: (**required**) a key used in the underlying block cipher.
- `iv`:(**required**) an iv (initialization vector) used in the underlying block cipher. Some block ciphers may not require it.
In that case, it can be set to *null* or *''*.
- `fpe_algorithm`: (**optional**, **default**: 'prefix-cipher') The FPE algorithm to be used by the cipher:
- `prefix-cipher`: A prefix cipher algorithm (**currently available**).
- `cycle-walking`: A cycle walking algorithm (**in development**).
- `feistel-network`: A Feistel network implementation (**in development**).
- `cipher_algorithm`: (**optional**, **default**: _aes-256-cbc_) The underlying block cipher algorithm used.
Similar to [crypto.createCipheriv()](https://nodejs.org/api/crypto.html#crypto_crypto_createcipheriv_algorithm_key_iv_options)
of Node's `crypto` module.- `domain_options`: (**optional**, **default**: `{}`, sets domain as the characters of the input text) An object that
contains the configuration specifying the FPE cipher's domain. The object contains the following fields:- *type*: (**string**) The type of the domain configuration to use:
- `default`: Default config. Uses the characters of the input text to be encrypted as the domain.
- `input`: Use only the characters specified in the *domain* field as the domain.
- `preset`: Use one of the many presets available for the specified FPE algorithm.
- `ascii-range`: Use set(s) of specified ASCII characters as the domain.
- *domain*: (**string**/**array**) The domain field. The value of this field depends on the *type* field:
- When `type: default`, the domain field or its value is not considered.
- When `type: input`, the domain field contains the characters to be used as the domain.
- When `type: preset`, the domain field contains one of the many preset domains available:
- Presets for `prefix-cipher`:
- `"numeric"`: `1234567890`
- `"alphalower"`: `abcdefghijklmnopqrstuvwxyz`
- `"alphaupper"`: `ABCDEFGHIJKLMNOPQRSTUVWXYZ`
- Presets for `cycle-walking`:
- `"numeric"`: `1234567890`
- `"alphalower"`: `abcdefghijklmnopqrstuvwxyz`
- `"alphaupper"`: `ABCDEFGHIJKLMNOPQRSTUVWXYZ`
- `"alphanumeric"`: `ABCDEFGHIJKLMNOPQRSTUVWXYZ`, `abcdefghijklmnopqrstuvwxyz`, `1234567890`
- `"text"`: `ABCDEFGHIJKLMNOPQRSTUVWXYZ`, `abcdefghijklmnopqrstuvwxyz`, `1234567890`, `. ,;:/?!@#$%&*()[]-'"`
- Presets for `feistel-network`:
- `"numeric"`: `1234567890`
- `"alphalower"`: `abcdefghijklmnopqrstuvwxyz`
- `"alphaupper"`: `ABCDEFGHIJKLMNOPQRSTUVWXYZ`
- `"alphanumeric"`: `ABCDEFGHIJKLMNOPQRSTUVWXYZ`, `abcdefghijklmnopqrstuvwxyz`, `1234567890`
- `"text"`: `ABCDEFGHIJKLMNOPQRSTUVWXYZ`, `abcdefghijklmnopqrstuvwxyz`, `1234567890`, `. ,;:/?!@#$%&*()[]-'"`
- `"jwt"`: `ABCDEFGHIJKLMNOPQRSTUVWXYZ`, `abcdefghijklmnopqrstuvwxyz`, `1234567890`, `._-`
- `"sha-512"`: `abcdef`, `0123456789`
- When `type: ascii-range`, the domain field contains an array/string that specifies a
set(s) of ASCII characters for the domain.
- *residual_chars*: (**boolean**) Toggle that indicates whether to include any characters of
the input text that are not in the configured domain. Only considered when domain *type* isn't `input`.
- *additional_chars*: (**array**) An array that contains any additional characters to be
included in the domain. Array can contain a few entries of multiple-character
strings (```['abcd', '1264', ...]```) or many entries of single-character
strings (```['a', 'b', 'c', 'd', '1', '2', '6', '4', ...]```). Independent of the domain *type* value.
#### Examples:Initializing a cipher with the default FPE algorithm (prefix-cipher), default encryption algorithm (aes-256-cbc),
and default domain config:```js
var harpo = require('harpo');var key = require('crypto').randomBytes(16).toString('hex');
var iv = require('crypto').randomBytes(8).toString('hex');var cipher = harpo.cipher(key, iv);
```Initializing a cipher with the default FPE algorithm (prefix-cipher), DES encryption algorithm (des-ecb), and
default domain config:```js
var harpo = require('harpo');var key = require('crypto').randomBytes(4).toString('hex');
var cipher = harpo.cipher(key, '', 'prefix-cipher', 'des-ecb');
```Initializing a cipher with the default FPE algorithm (prefix-cipher), default encryption algorithm (aes-256-cbc),
and a custom domain ([A-E]):```js
var harpo = require('harpo');var key = require('crypto').randomBytes(16).toString('hex');
var iv = require('crypto').randomBytes(8).toString('hex');var options = {
type: 'input',
domain: 'ABCDE'
};var cipher = harpo.cipher(key, iv, 'prefix-cipher', 'aes-256-cbc', options);
```Initializing a cipher with the default FPE algorithm (prefix-cipher), default encryption algorithm (aes-256-cbc),
and a custom domain ([alphalower] preset) that includes any out-of-domain characters in the input text.```js
var harpo = require('harpo');var key = require('crypto').randomBytes(16).toString('hex');
var iv = require('crypto').randomBytes(8).toString('hex');var options = {
type: 'preset',
domain: 'alphalower',
residual_chars: true
};var cipher = harpo.cipher(key, iv, 'prefix-cipher', 'aes-256-cbc', options);
```Initializing a cipher with the default FPE algorithm (prefix-cipher), default encryption algorithm (aes-256-cbc),
and a custom domain (ascii-ranges of [65-90] and [97-122]) that includes any out-of-domain characters in the
input text and uses additional symbol characters.```js
var harpo = require('harpo');var key = require('crypto').randomBytes(16).toString('hex');
var iv = require('crypto').randomBytes(8).toString('hex');var options = {
type: 'ascii-range',
domain: ['65-90', '97-122'],
residual_chars: true,
additional_chars: ['!@#$%^', '&*', '(', ')']
};var cipher = harpo.cipher(key, iv, 'prefix-cipher', 'aes-256-cbc', options);
```---
### cipher.encrypt(text) and cipher.decrypt(text)
To encrypt and decrypt a string of text using an initialized FPE cipher. **Note**: the same FPE cipher must be
used for successful encryption and decryption.
```js
var harpo = require('harpo');var key = require('crypto').randomBytes(16).toString('hex');
var iv = require('crypto').randomBytes(8).toString('hex');var cipher = harpo.cipher(key, iv, 'prefix-cipher', 'aes-256-cbc', {
type: 'default',
domain: ''
});cipher.encrypt('bumblebee');
// 'ubmuleuee'cipher.decrypt('ubmuleuee');
// 'bumblebee'// reinitializing cipher with new domain options
cipher = harpo.cipher(key, iv, 'prefix-cipher', 'aes-256-cbc', {
type: 'preset',
domain: 'numeric',
residual_chars: true
});cipher.encrypt('TheCowJumpedOverTheMoon');
// 'OTvpoh0d34v91nvuOTvroo5'cipher.decrypt('OTvpoh0d34v91nvuOTvroo5');
// 'TheCowJumpedOverTheMoon'// reinitializing cipher with new domain options
cipher = harpo.cipher(key, iv, 'prefix-cipher', 'aes-256-cbc', {
type: 'input',
domain: '123456abcdef',
additional_chars: [',./defgh']
});cipher.encrypt('3314526');
// '44dh.ec'cipher.decrypt('44dh.ec');
// '3314526'
```---
### presets()
To obtain a list of domain presets of each FPE algorithm.
```js
var harpo = require('harpo');harpo.presets();
// prefix-cipher:
// numeric: 1234567890
// alphalower: abcdefghijklmnopqrstuvwxyz
// alphaupper: ABCDEFGHIJKLMNOPQRSTUVWXYZ
// cycle-walking:
// numeric: 1234567890
// alphalower: abcdefghijklmnopqrstuvwxyz
// alphaupper: ABCDEFGHIJKLMNOPQRSTUVWXYZ
// ...
```## License
MIT © Baalateja Kataru