5.3.2 • Published 8 months ago

globalid-crypto-library v5.3.2

Weekly downloads
959
License
-
Repository
-
Last release
8 months ago

globalid-crypto-library

This library groups together all the crypto-related functionality in the globaliD app, and make it available so that it works for Node.js on the server.

Note that this is not a standalone npm package in its own right; to use this library, import it as a dependency within your project.

Dependencies

Currently the project has this dependencies:

  • bcrypt v3.0.7 or higher

Installation

To install, simply add the crypto library as a dependency within your project. For example:

npm add globalid-crypto-library

Building for Node.js

Specific requirements to use the crypto library within a Node program is your need node v12.13.0 or higher, because of bcrypt 3.0.7. Simply install the library as a dependency and you can start using it right away.

Usage

To use the globalid-crypto-library, simply require the library, like this in the commonJS format:

const crypto = require('globalid-crypto-library')

or if you using a transpiler (i.e. when using TypeScript):

import * as crypto from 'globalid-crypto-library'

Once it has been required, you can use a consistent interface across all the various platforms, following the API described below. For example:

let keypair = crypto.rsa.generateKeyPair()

Testing

The globalid-crypto-library includes a comprehensive set of unit tests. In order to test the library within a react-native app, you need to run the tests within a react-native app -- only the Node.js code can be tested from the command line.

Your testing code will need to provide a log() function that accepts a string and displays that string in a console log of some sort. For example:

let console = []

function log(msg) {
  console.push(msg)
  // update UI to show changed console.
}

On the server, your log() function can be as simple as:

function log(msg) {
  console.log(msg)
}

You can then run the tests by calling the following function:

crypto.tests.run(log)

The progress of the tests will be updated by successive calls to the log() function. Note that crypto.tests.run() returns a Promise that gets resolved once all the tests have been run.

Available Functions

The crypto library is broken into several sections, grouping functions according to the type of cryptographic functionality they provide:

  • crypto.rsa: key generation, signing, encryption and decryption.
  • crypto.bcrypt: hashing and salt generation.
  • crypto.pbkdf: key-generation using passwords.
  • crypto.aes: symmetric encryption and decryption.
  • crypto.hmac: HMAC hashing algorithms.
  • crypto.util: utility functions.
  • crypto.test: unit tests.

crypto.rsa

generateKeyPair

async crypto.rsa.generateKeyPair()

Upon completion, return an array containing two strings, the public and private key making up a new key pair.

Returns an object with public_key and private_key fields.

encrypt

async crypto.rsa.encrypt(public_key, data)

Encrypt the given data using the given public key, using RSA. Both public_key and data should be strings.

Upon completion, returns the encrypted data as a base64-encoded string.

Note that the promise can be rejected with a "DATA_TOO_LARGE" exception if the data is too large to be encrpyted.

Note for Node: the encrypt method as first parameter, public_key, can accept pem encoded string of the key or path to the pem file in the filesystem.

decrypt

async crypto.rsa.decrypt(private_key, encrypted_data)

Decrypt the given encrypted data using the given private key, using RSA. Both private_key and encrypted_data should be strings.

Upon completion, returns the encrypted data as a string.

Note for Node: first parameter private_key of the decrypt method can be string or object.

  • private_key: <Object> | <string> - key:<string> A PEM encoded private key. - passphrase: <string> An optional passphrase for the private key. - file: <string> Absolute or relative path to the pem file

sign

async crypto.rsa.sign(private_key, data)

Sign a piece of data using the given private key. This generates an SHA256 signature hash of the given data using the given private key. Both private_key and data should be strings.

Upon completion, returns the digital signature as a base64-encoded string.

Note for Node: first parameter private_key of the decrypt sign can be string or object.

  • private_key: <Object> | <string> - key:<string> A PEM encoded private key. - passphrase: <string> An optional passphrase for the private key. - file: <string> Absolute or relative path to the pem file

verifySignature

async cypto.rsa.verifySignature(public_key, data, signature)

Verify a previously-signed piece of data using the given public key. The given signature is verified as being generated using the private key associated with the given public key and the given data. All three parameters should be strings.

Upon completion, returns a boolean indicating whether or not the verification was successful.

Note for Node: the encrypt method as first parameter, public_key, can accept pem encoded string of the key or path to the pem file in the filesystem.

crypto.bcrypt

generateSalt

async crypto.bcrypt.generateSalt(num_rounds)

Generate a salt to use for bcrypt hashing. num_rounds should be the "cost" or number of rounds to go through for generating the salt. The higher the num_rounds value, the longer it will take to generate the hash.

hash

async crypto.bcrypt.hash(password, salt)

Generate a hash of the given password, using the given salt. Returns the hash as a string.

crypto.pbkdf

generate

async crypto.pbkdf.generate(data, num_iterations=20000, salt_length=16, key_length=16)

Generate a new password-based key derivation function (PBKDF) using HMAC-SHA256. Returns an object with the following fields:

  • iterations: The number of iterations used to generate the PBKDF.
  • _salt: A copy of the salt, as a Uint8Array.
  • _pbkdf: A copy of the generated hash, as a Uint8Array.
  • salt: A copy of the salt, as a base64-encoded string.
  • hash The generated hash, as a hex-encoded string.
  • keySize: The specified key length.

get

async crypto.pbkdf.get(data, salt, num_iterations, key_size)

Uses a previously-generated PBDKF function to hash a password.

crypto.aes

encrypt

async crypto.aes.encrypt(data, password)

Encrypt some data using AES-CBC. A key is derived from the supplied password using PBKDF and 16-byte random salt and IV values. Returns a string containing the hex-encoded salt and IV followed by the base64-encoded encrypted data.

decrypt

async crypto.aes.decrypt(data, password)

Decrypt some data previously encrypted using the crypto.aes.encrypt() function.

encryptBuffer

async crypto.aes.encryptBuffer(data, password)

Encrypt Buffer data using AES-CBC. A key is derived from the supplied password using PBKDF and 16-byte random salt and IV values. Returns a Buffer containing the IV followed by the encrypted data.

decryptBuffer

async crypto.aes.decryptBuffer(data, password)

Decrypt Buffer data previously encrypted using the crypto.aes.encryptBuffer() function.

encryptStream

crypto.aes.encryptStream(password): stream.Transform

Get the encrypt stream which can then be piped to destination.

decryptStream

crypto.aes.decryptStream(password): stream.Transform

Get the decrypt stream which can then be piped to destination.

crypto.hmac

md5

async crypto.hmac.md5(data, key)

Calculate the MD5 hash of the given data, using the given salt. data should be the data to hash, as a string, and key should be a hex-encoded string to use as the key.

Returns the hash as a hex-encoded string.

sha1

async crypto.hmac.sha1(data, key)

Calculate the SHA-1 hash of the given data, using the given salt. data should be the data to hash, as a string, and key should be a hex-encoded string to use as the key.

Returns the hash as a hex-encoded string.

sha256

async crypto.hmac.sha256(data, key)

Calculate the SHA-256 hash of the given data, using the given salt. data should be the data to hash, as a string, and key should be a hex-encoded string to use as the key.

Returns the hash as a hex-encoded string.

sha512

async crypto.hmac.sha512(data, key)

Calculate the SHA-512 hash of the given data, using the given salt. data should be the data to hash, as a string, and key should be a hex-encoded tring to use as the key.

Returns the hash as a hex-encoded string.

crypto.util

randomBytes

async crypto.util.randomBytes(num_bytes)

Generates an array of num_bytes cryptographically-random bytes. Each array entry will be an integer in the range 0..255.

bytesToUint8Array

bytesToUint8Array(bytes)

Convert an array of bytes into a Uint8Array.

uint8ArrayToBytes

uint8ArrayToBytes(array)

Convert a Uint8Array back into a regular array.

bytesToString

bytesToString(bytes)

Convert an array of bytes into a string. Each byte in the array will correspond to a single character with that ordinal value in the resulting string.

stringToBytes

stringToBytes(string)

Convert a string back into an array of bytes. Each character in the string corresponds to one byte in the returned array.

bytesToBase64

bytesToBase64(bytes)

Convert an array of bytes into a base64-encoded string.

base64ToBytes

base64ToBytes(string)

Convert a base64-encoded string back into an array of bytes.

bytesToHex

bytesToHex(bytes)

Convert an array of bytes into a hex-encoded string.

hexToBytes

hexToBytes(string)

Convert a hex-encoded string back into an array of bytes.

hashSHA512

async crypto.util.hashSHA512(data)

Calculate the SHA-512 hash of the given data. data can be a string or a Buffer object.

Returns the hash as a hex-encoded string.

crypto.tests

run

async crypto.tests.run(log)

Run the unit tests, passing log messages to the given log function. The returned promise will be resolved once the tests are complete, or rejected if a test fails.

Additional notes

If you want to use this library with Node version 8.x or lower use the version ~2.0.2 of this library npm i globalid-crypto-library@~2.0.2

Examples with encrypt / decrypt streams

// encrypt the file
createReadStream('file path')
.pipe(encryptStream(password))
.on('error', handleError)
.pipe(createWriteStream('encrypted file path'))
.on('close', done)

// decrypt the file
createReadStream('encrypted file path')
.pipe(decryptStream(password))
.on('error', handleError)
.pipe(createWriteStream('decrypted file path'))
.on('close', done)

// re-encrypt the file with different password
createReadStream('encrypted file path')
.pipe(decryptStream(password))
.on('error', handleError)
.pipe(encryptStream(newPassword))
.on('error', handleError)
.pipe(createWriteStream('reencrypted file path'))
.on('close', done)

using aws s3

// encrypt the file and upload to s3 bucket

const encryptStream: stream.Transform =
  createReadStream('path to file') // some valid read stream
  .pipe(GIDCrypto.aes.encryptStream(password))

const params: aws.S3.Types.PutObjectRequest = {
  Body: encryptStream,
  Bucket: '<bucket>',
  Key: `<s3 file path>`,
}

await S3.upload(params).promise()
// download decrypted file from s3

return new Promise((resolve, reject) => {

  const params: aws.S3.GetObjectRequest = {
    Bucket: '<bucket>',
    Key: `<path to entrypted file>`,
  }

  // some valid write stream
  const destinationStream = createWriteStream('/path/to/dec/file.ext')

  S3
    .getObject(params)
    .createReadStream()
    .pipe(GIDCrypto.aes.decryptStream(password))
    .on('error', reject)
    .pipe(destinationStream)
    .on('error', reject)
    .on('finish', resolve)
})
// reuploading encrypted file from one S3 bucket to another
// with on-the-fly re-encryption

const password: string = '<current password>'
const newPassword: string = '<new desired password>'

return new Promise((resolve, reject) => {

  // currently encrypted file on s3
  const downloadParams: aws.S3.GetObjectRequest = {
    Bucket: currentBucket,
    Key: `<path to encrypted file>`,
  }

  // decrypt and encrypt stream
  const reencStream: stream.Transform = S3
  .getObject(downloadParams)
  .createReadStream()
  .on('error', reject)
  .pipe(GIDCrypto.aes.decryptStream(password))
  .on('error', reject)
  .pipe(GIDCrypto.aes.encryptStream(newPassword))
  .on('error', reject)

  // upload params for re-encrypted file on different bucket
  const uploadParams: aws.S3.Types.PutObjectRequest = {
    Body: reencStream,
    Bucket: bucket2,
    Key: `<desired encrypted file path>`,
  }

  S3
  .upload(uploadParams)
  .promise()
  .then(resolve)
  .catch(reject)
})
5.3.2

8 months ago

5.3.2-alpha.1

8 months ago

5.3.3-alpha.1

8 months ago

5.3.1

12 months ago

5.3.0

1 year ago

5.3.0-alpha.5

1 year ago

5.3.0-alpha.2

1 year ago

5.3.0-alpha.1

1 year ago

5.3.0-alpha.4

1 year ago

5.3.0-alpha.3

1 year ago

5.2.1

1 year ago

5.2.0

1 year ago

5.3.1-alpha.3

12 months ago

5.1.0

1 year ago

5.1.0-alpha.1

1 year ago

5.0.4

2 years ago

5.0.3

2 years ago

5.0.2

2 years ago

5.0.1-alpha.5

2 years ago

5.0.1

3 years ago

5.0.1-alpha-4

3 years ago

5.0.1-alpha-3

3 years ago

5.0.1-alpha-1

3 years ago

5.0.1-alpha-2

3 years ago

5.0.0

3 years ago

5.0.0-alpha-4

3 years ago

5.0.0-alpha-2

3 years ago

4.0.4

3 years ago

4.0.4-alpha-1

3 years ago

4.0.3

3 years ago

4.0.3-alpha-1

4 years ago

5.0.0-alpha-1

4 years ago

4.0.2

4 years ago

4.0.2-alpha-1

4 years ago

4.0.1

4 years ago

4.0.1-alpha-1

4 years ago

3.1.2-alpha-3

4 years ago

3.1.8-alpha-1

4 years ago

3.1.7

4 years ago

3.1.6

4 years ago

4.0.0

4 years ago

4.0.0-alpha.3

4 years ago

4.0.0-alpha.2

4 years ago

4.0.0-alpha.1

4 years ago

3.1.5

5 years ago

3.1.4

5 years ago

3.1.3

5 years ago

3.1.2

5 years ago

3.1.1

5 years ago

3.0.1

5 years ago

3.0.0

5 years ago

2.1.0

5 years ago

2.0.3

5 years ago

2.0.2

6 years ago

2.0.1

6 years ago

2.0.0

6 years ago

1.1.1

6 years ago

1.1.0

6 years ago

1.0.6

6 years ago

1.0.5

6 years ago

1.0.4

6 years ago

1.0.3

6 years ago