globalid-crypto-library
TypeScript icon, indicating that this package has built-in type declarations

5.3.2 • Public • Published

globalid-crypto-library

This library groups together all the crypto-related functionality in the globaliD platform, and makes 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.

Breaking Changes

Support for Node 12 and up

globaliD crypto library version 5 only supports Node 12 and up. We are going to support version based on the maintenance plan found here - https://nodejs.org/en/about/releases

Migrating from v3/v4 to v5

  • Because all most every method in this package can be done without a promise, we decided to refactor the package so it can be used without a promise.
  • Fixed how the Typescript interfaces are defined and because of that names of the sub-packages changed. The list of renames:
    • cryptosdk.aes -> cryptosdk.AES
    • cryptosdk.gid -> cryptosdk.GID
    • cryptosdk.jwe -> cryptosdk.JWE
    • cryptosdk.jwk -> cryptosdk.JWK
    • cryptosdk.hmac -> cryptosdk.HMAC
    • cryptosdk.pbkdf -> cryptosdk.PBKDF
    • cryptosdk.rsa -> cryptosdk.RSA
    • cryptosdk.util -> cryptosdk.Util
  • Package no longer has a sub-package bcrypt, dependence bcrypt was removed from the project.
  • Package no longer has a default export
  • Method cryptosdk.util.hmacSHA512 was remove, now it can be done with cryptosdk.HMAC.sha512 or cryptosdk.HMAC.nodeHmac('sha512',...)

Example or how to migrate:

// version 3 or 4
import cryptosdk from 'globalid-crypto-library'
const result: string = await cryptosdk.aes.encrypt(data, password)
// version 5
import * as cryptosdk from 'globalid-crypto-library'
const result: string = cryptosdk.AES.encrypt(data, password)
// or 
import { AES } from 'globalid-crypto-library'
const result: string = AES.encrypt(data, password)

Dependencies

Currently the project has only one dependence:

Installation

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

$ npm install globalid-crypto-library --save

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 are 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()

Available Methods

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

  • crypto.AES: symmetric encryption and decryption
  • crypto.GID: utility functions for globaliD identities
  • crypto.JOSE: exporting npm package node-jose
  • crypto.JWE: utility functions to create encryption and decryption
  • crypto.JWS: utility functions to verify and create signature
  • crypto.JWK: utility functions to import JWK keys public or private to PEM format
  • crypto.HMAC: HMAC hashing algorithms
  • crypto.PBKDF: key-generation using passwords
  • crypto.RSA: key generation, signing, signing validation, encryption and decryption with RSA keys
  • crypto.ED25519: key generation, signing, signing validation, encryption and decryption with ED25519 keys
  • crypto.Util: utility functions

crypto.AES

encrypt

crypto.AES.encrypt(data: string, password: string): string

Encrypt string data using AES-256-CBC. Returns a string containing the IV in hex (first 32 characters) and encrypted data in base64-encoded encrypted data.

decrypt

crypto.AES.decrypt(data: string, password: string): string

Decrypt some data previously encrypted using the ```typescript crypto.AES.decrypt(data: string, password: string)` function.

Note: Taking the first 32 characters from the data string is the IV value in hex needed for AES-256-CBC.

encryptBuffer

crypto.AES.encryptBuffer(data: Buffer, password: string): Buffer

Encrypt Buffer data using AES-256-CBC. First 16 bytes are IV value everything else it is encrypted value Buffer type.

decryptBuffer

crypto.AES.decryptBuffer(data, password): Buffer

Decrypt Buffer data previously encrypted using the ```typescript crypto.AES.encryptBuffer(data, password)` 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.GID

aesCbcEncryptSecurity

crypto.GID.aesCbcEncryptSecurity(data: string, password: string): string

Helper function to encrypt data. Password is hashed with PBKDF.get method and then use to encrypt the data. Iteration parameter on PBKDF.get here is hardcoded to value 100001.

aesCbcEncryptIdentity

crypto.GID.aesCbcEncryptIdentity(data: string, password: string, iterations: number = 100000): string

Helper function to encrypt data. Password is hashed with PBKDF.get method and then use to encrypt the data.

aesCbcDecryptSecurity

crypto.GID.aesCbcDecryptSecurity(encryptedData: string, password: string): string

Helper function to decrypt data. Password is hashed with PBKDF.get method and then use to decrypt the data. Iteration parameter on PBKDF.get here is hardcoded to value 100001.

aesCbcDecryptIdentity

crypto.GID.aesCbcDecryptIdentity(encryptedData: string, password: string, iterations: number = 100000): string

Helper function to decrypt data. Password is hashed with PBKDF.get method and then use to decrypt the data.

crypto.JOSE

Exporting package node-jose. You can read more about the package on their NPM page.

crypto.JWE

encrypt

type JwkKey = string | {[key: string]: string | string[] } | JWK.RawKey

async crypto.JWE.encrypt(public_key: JwkKey, data: string): Promise<string>

Encrypt data with JWK public key, with format compact and content algorithm A256CBC-HS512

decrypt

type JwkKey = string | {[key: string]: string | string[] } | JWK.RawKey

async crypto.JWE.decrypt(private_key: JwkKey, encrypted_data: string): Promise<string>

Decrypting data with JWK private key.

crypto.JWK

publicKeyToPem

type JwkKey = string | {[key: string]: string | string[] } | JWK.RawKey

async crypto.JWK.publicKeyToPem(key: JwkKey): Promise<string>

Converting JWK public key format into PEM format

privateKeyToPem

type JwkKey = string | {[key: string]: string | string[] } | JWK.RawKey

async crypto.JWK.privateKeyToPem(key: JwkKey): Promise<string>

Converting JWK private key format into PEM format

crypto.JWS

sign

type JwkKey = string | {[key: string]: string | string[] } | JWK.RawKey
type KeyForm = 'json' | 'private' | 'pkcs8' | 'public' | 'spki' | 'pkix' | 'x509' | 'pem'

async crypto.JWS.sign(private_key: JwkKey, payload: string, key_form?: KeyForm): Promise<string>

Sign payload using JWK private key. Note that if the private key is not in standard JWK format, key_form parameter should also be specified. Signature algorithm used is RSA-SHA256

verify

type JwkKey = string | {[key: string]: string | string[] } | JWK.RawKey
type KeyForm = 'json' | 'private' | 'pkcs8' | 'public' | 'spki' | 'pkix' | 'x509' | 'pem'

async crypto.JWS.verify(public_key: JwkKey, jwk: string, key_form?: KeyForm): Promise<string>

Verify JWK signature using JWK public key. Note that if the private key is not in standard JWK format, key_form parameter should also be specified.

crypto.HMAC

md5

crypto.HMAC.md5(data: string, key: string): string

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 string to use as the key.

Returns the hash as a hex-encoded string.

sha1

crypto.HMAC.sha1(data: string, key: string): string

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

crypto.HMAC.sha256(data: string, key: string): string

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.

sha384

crypto.HMAC.sha384(data: string, key: string): string

Calculate the SHA-384 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

crypto.HMAC.sha512(data: string, key: string): string

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 trying to use as the key.

Returns the hash as a hex-encoded string.

nodeHmac

crypto.HMAC.nodeHmac(algorithm: string, data: string, key: string): string

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

Returns the hash as a hex-encoded string.

crypto.PBKDF

generate

crypto.PBKDF.generate(data: string, num_iterations?: number =20000, salt_length?: number = 16, key_length?: number = 16): Generate

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

crypto.PBKDF.get(data: string, salt: string | Buffer, iterations: number, keySize: number): string

Uses a previously-generated PBDKF function to hash a password. Returns values encoded in hex.

crypto.RSA

generateKeyPair

crypto.RSA.generateKeyPair(bytes?: number = 2048): KeyPair

Upon completion, return an object 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

crypto.RSA.encrypt(public_key: string, data: string): string`

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 if can throw an Error with a "DATA_TOO_LARGE" exception if the data is too large to be encrypted.

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

crypto.RSA.decrypt(private_key: nodeCrypto.RsaPrivateKey | string, encrypted_data: string): string

Decrypt the given encrypted data using the given private key, using RSA. Both encrypted_data should be string and private_key should be the following type nodeCrypto.RsaPrivateKey | string.

Upon completion, returns the encrypted data as a string.

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

sign

crypto.RSA.sign(private_key: PrivateKey | string, data: string): string

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. data should be string and private_key should be the following type PrivateKey | string.

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

verifySignature

crypto.RSA.verifySignature(public_key: string, data: string, signature: string): boolean

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.ED25519

We are using the following package here - https://sodium-friends.github.io/docs/

generateKeys

interface Ed25519Keys {
  privateKey: string
  publicSigningKey: string
}

crypto.ED25519.generateKeys(privateKeyBase58?: string): Ed25519Keys

It will generate you a ED25519 keypair, if arguments privateKeyBase58 is send, it will create public key from it and return the keypair.

signMessage

crypto.ED25519.signMessage(message: string, privateKey: string): string

Signing a message with a secret/private key ED25519. Signed message is in Base58.

verifySignature

crypto.ED25519.verifySignature(message: string, publicKey: string, signature: string): boolean

Verifies that the message was signed with the secret/private key.

getSharedSecretHex

crypto.ED25519.getSharedSecretHex(privateKey: string, publicKey: string): string

Generates a shared secret, with secret/private key and public key. Secret and public key needs to either be the following:

  • Secret and public key needs to be converted to curve 25519.
  • Secret key is ED25519 and public key is a scalar multiplication public key based on a secret ED25519 key. Secret Key A and Public Key B will generate the same secret as Secret Key B and Public Key A.

sealedBox

crypto.ED25519.sealedBox(message: string, publicKey: string): string

Encrypt the given message using the given public key. Public key here needs to be ED25519, function will do the conversion to curve25519.

sealedBoxOpen

crypto.ED25519.sealedBoxOpen(ciphertext: string, publicKey: string, privateKey: string): string

Decrypt the given ciphertext using the given public key and secret/private key. Keys here needs to be ED25519, function will do the conversion to curve25519.

getPublicEncryptionKey

crypto.ED25519.getPublicEncryptionKey(publicKey: string): string

Converts an ed25519 public key to curve 25519

getPrivateEncryptionKey

crypto.ED25519.getPrivateEncryptionKey(privateKey: string): string

Converts an ed25519 secret/private key to curve 25519

getXPublicKey

crypto.ED25519.getXPublicKey(secretKey: string): string

Creates a scalar multiplication public key based on a secret key.

deriveIntoED25519Key

crypto.ED25519.deriveIntoED25519Key(secretKey: string, index: number, context: string): string

Creates a new ED25519 signing key, derived based on the secretKey, index and context. secretKey needs to be ED25519 private/secret key.

crypto.Util

randomBytes

crypto.Util.randomBytes(bytes: number): number[]

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

bytesToUint8Array

crypto.Util.bytesToUint8Array(bytes: number[]): Uint8Array

Convert an array of bytes into a Uint8Array.

uint8ArrayToBytes

crypto.Util.uint8ArrayToBytes(uint8Array: Uint8Array): number[]

Convert a Uint8Array back into a regular array of number in the range 0..255.

bytesToString

crypto.Util.bytesToString(bytes: number[]): string

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

crypto.Util.stringToBytes(rawString: string): number[]

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

bytesToBase64

crypto.Util.bytesToBase64(bytesArray: number[]): string

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

base64ToBytes

crypto.Util.base64ToBytes(base64String: string): number[]

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

bytesToHex

crypto.Util.bytesToHex(bytesArray: number[]): string

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

hexToBytes

crypto.Util.hexToBytes(hexString: string): number[]

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

nodeHash

crypto.Util.nodeHash(algorithm: string, data: string | NodeJS.ArrayBufferView): string;

Calculate the hash ( based on algorithm ) of the given data. data can be a string or a Buffer like object, salt should be string or NodeJS.ArrayBufferView.

Returns the hash as a hex-encoded string.

hashSHA512

crypto.Util.hashSHA512(data: string | NodeJS.ArrayBufferView): string

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

Returns the hash as a hex-encoded string.

bytesToBase58

crypto.Util.bytesToBase58(byteData: Uint8Array): string

Convert bytes into an base58 string

base58ToBytes

crypto.Util.base58ToBytes(str: string): Uint8Array

Convert base58 string into bytes ( Uint8Array )

stringToUint8Array

crypto.Util.stringToUint8Array(str: string): Uint8Array

Convert string into Uint8Array array

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')w
.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)
})
// re-uploading 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)
})

Dependencies (3)

Dev Dependencies (20)

Package Sidebar

Install

npm i globalid-crypto-library

Weekly Downloads

146

Version

5.3.2

License

none

Unpacked Size

79.2 kB

Total Files

44

Last publish

Collaborators

  • qloud.io
  • npm-gid