JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • 0
  • Score
    100M100P100Q23707F
  • License MIT

Encrypting and decrypting your data in chains made easy!

Package Exports

  • cipher-chain

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (cipher-chain) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

cipher-chain

HitCount Package quality Build Status Coverage Status Licensing Repo size Downloads per week Node version Help us and star this project

Symmetric encryption and decryption of string(s) or file(s) protected via a secret string or secretFile

Installation

npm install cipher-chain --save

How it works

- Encrypting

When creating a cipher-chain instance you are presented with some options, you can use a secret or use a secretFile, a secretFile is a computer generated 'key' if you will that is a unique signature representing your secret

Secondly you will need to define a chain, this will be the path the encryption/decryption process goes through to get the encrypted and plaintext respectively. chainis a array with string representing all cipher algorithms. The cipher algorithm list can be viewed by calling cipherchain.ciphers

When you create a cipher-chain instance the script goes through the chain list and for every algorithm it creates a kdf generated hashed key derived from the secret that matches the key length requirements for that particular cipher

Then when you call the cipherchain.encrypt function it checks what the chain is and will convert your plaintext to ciphertext via traversal of the chain list.

So if you have a chain value of ['aes-256-gcm', 'aes-192-gcm', 'camellia-256-cbc']

then the encryption process will be:

plaintext -> aes-256-gcm -> aes-192-gcm -> camellia-256-cbc -> ciphertext

and decryption process will be:

ciphertext -> camellia-256-cbc -> aes-192-gcm -> aes-256-gcm -> plaintext

After encryption chain end a hmac is computed of the end resulting ciphertext and before decryption chain start the hmac is compared (timings safe) against the end resulting ciphertext of that decryption process. If it not verifies a error is thrown

For each algorithm encryption chain pass a random initialization vector is generated

- Decrypting

All encrypted strings have the same format and recgonisable by the starting prefix of @CC2- indicating its a cipher-chain version 2 string. They can look like this:

@CC2-72887cf9ecf196d8b13bb05a6141a34c73af7ca719abf994d170ca2cc6629e169d743ef6c93c486079f60 d8cbdf1b7787eee937fe9c4cf62522d0d4d8c304195:0:1:0:ab561e52d1e9c68d3d63c62952c0314f3c73ff01 99657849ef20708af21a291e:3522e975157c2dc1:cbb83e90afeb9a3de67638502148c40b

If you look closely you can see : being delimiters which will have the following result when split:

first the @CC2- is removed internally when decrypting the string

;[
    '72887cf9ecf196d8b13bb05a6141a34c73af7ca719abf994d170ca2cc6629e169d743ef6c93c486079f60d8cbdf1b7787eee937fe9c4cf62522d0d4d8c304195',
    '0',
    '1',
    '0',
    'ab561e52d1e9c68d3d63c62952c0314f3c73ff0199657849ef20708af21a291e',
    '3522e975157c2dc1',
    'cbb83e90afeb9a3de67638502148c40b'
]

The mapping for this format is as followed:

@CC2-[hmac]:[cipherAlgorithmId]:[autoPadding]:[authTag]:[kdfSalt]:[initializationVector]:[encryptedData]

So we can conclude we have the following data when decrypting the string:

const data = {
    hmac: '72887cf9ecf196d8b13bb05a6141a34c73af7ca719abf994d170ca2cc6629e169d743ef6c93c486079f60d8cbdf1b7787eee937fe9c4cf62522d0d4d8c304195',
    cipherAlgorithmId: '0',
    autoPadding: '1',
    authTag: '0',
    kdfSalt: 'ab561e52d1e9c68d3d63c62952c0314f3c73ff0199657849ef20708af21a291e',
    initializationVector: '3522e975157c2dc1',
    encryptedData: 'cbb83e90afeb9a3de67638502148c40b'
}

Cipher-chain knows this internally when trying to decrypt your strings. The only piece of the puzzle here to decrypt the encryptedData variable is if we know the secret

Usage

const CipherChain = require('cipher-chain')

const start = async () => {
    const cipherchain = await new CipherChain({
        secret: 'very secret!',
        kdf: 'argon2',
        chain: ['aes-256-gcm', 'blowfish', 'camellia-256-cbc'],
        options: {
            argon2: {
                timeCost: 6,
                memoryCost: 1024 * 4,
                parallelism: 1
            }
        }
    })

    const ciphers = cipherchain.ciphers // List of cipher algorithms to use in your chain
    const kdfs = cipherchain.kdfs // List of KDFs (key derivation function) to use

    // Encrypt/decrypt a string
    const ciphertext = await cipherchain.encrypt('encrypt this')
    const plaintext = await cipherchain.decrypt(ciphertext)

    // Encrypt/decrypt a file
    await cipherchain.encryptFile('./file.txt')
    await cipherchain.decryptFile('./file.txt')

    // Encrypt/decrypt a directory
    await cipherchain.encryptFile('./directory')
    await cipherchain.decryptFile('./directory')
}

start()

Api

cipherchain.ciphers

Gets a list of all available ciphers to work with

cipherchain.kdfs

Gets a list of all available KDFs to work with

cipherchain.encrypt(plaintext:[string])

Encrypts a plaintext to a ciphertext

example:

let encrypted = await cipherchain.encrypt('secret data')

cipherchain.decrypt(ciphertext:[string])

Decrypts a ciphertext to a plaintext

example:

let decrypted = await cipherchain.decrypt(encrypted)

cipherchain.encryptFile(filename:[path])

Encrypts a file

example:

await cipherchain.encryptFile(path.join('../', 'encryptme.txt'))

cipherchain.decryptFile(filename:[path])

Decrypts a file

example:

await cipherchain.decryptFile(path.join('../', 'encryptme.txt'))

cipherchain.encryptDirectory(directory:[path])

Encrypts a directory

example:

await cipherchain.encryptDirectory(path.join('../', 'encryptme'))

cipherchain.decryptDirectory(directory:[path])

Decrypts a directory

example:

await cipherchain.decryptDirectory(path.join('../', 'encryptme'))

License

Copyright (c) 2020 by GiveMeAllYourCats. Some rights reserved.
cipher-chain is licensed under the MIT License as stated in the LICENSE file.