Package Exports
- globalid-crypto-library
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 (globalid-crypto-library) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
⚠️ globalid-crypto-library version 3 is deprecated.
globalid-crypto-library
This library groups together all the crypto-related functionality in the globaliD app, 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; to use this
library, import it as a dependency within your project.
Breaking Changes
Support for Node 10 and up
globaliD crypto library version 4 will only support Node 10 and up
Dependencies
Currently the project has these dependencies:
- bcrypt v5.0.0 or higher
- node-jose v1.1.5 or higher
ATTENTION: globalid-crypto-library will only work with node version 10 or higher
Installation
To install, simply add the crypto library as a dependency within your project. For example:
npm install globalid-crypto-library --saveBuilding for Node.js
Specific requirements to use the crypto library within a Node program is your need node v10 or higher, because of bcrypt 5.0.0. 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 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 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.jwk: json web key format transformation.crypto.jwe: json web key encryption and decryption.
crypto.rsa
generateKeyPair
async 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
async crypto.rsa.encrypt(public_key: string, data: string): Promise<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 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: nodeCrypto.RsaPrivateKey | string, encrypted_data: string): Promise<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
async crypto.rsa.sign(private_key: PrivateKey | string, data: string): Promise<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
async cypto.rsa.verifySignature(public_key: string, data: string, signature: string): Promise<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.bcrypt
generateSalt
async crypto.bcrypt.generateSalt(num_rounds: number): Promise<string>
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: string, salt: string): Promise<string>
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: string, num_iterations?: number =20000, salt_length?: number = 16, key_length?: number = 16): Promise<Pbkdf2generate>
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.hashThe generated hash, as a hex-encoded string.keySize: The specified key length.
get
async crypto.pbkdf.get(data: string, salt: string | Buffer, iterations: number, keySize: number): Promise<string>
Uses a previously-generated PBDKF function to hash a password. Returns values encoded in hex.
crypto.aes
encrypt
async crypto.aes.encrypt(data: string, password: string): Promise<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
async crypto.aes.decrypt(data: string, password: string): Promise<string>
Decrypt some data previously encrypted using the await 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
async crypto.aes.encryptBuffer(data: Buffer, password: string): Promise<Buffer>
Encrypt Buffer data using AES-256-CBC. First 16 bytes are IV value everything else it is encrypted value Buffer type.
decryptBuffer
async crypto.aes.decryptBuffer(data, password): Promise<Buffer>
Decrypt Buffer data previously encrypted using the await 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.hmac
md5
async crypto.hmac.md5(data: string, key: string): Promise<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
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.jwk
publicKeyToPem
crypto.jwk.publicKeyToPem(key): Promise<string>
Returns JWK public key in PEM format.
privateKeyToPem
crypto.jwk.privateKeyToPem(key): Promise<string>
Returns JWK private key in PEM format.
crypto.jwe
encrypt
crypto.jwe.encrypt(public_key, data): Promise<string>
Encrypts data using public Json Web Key. AES-256-cbc is used for content encryption and SHA-512 for data integrity. Returns JWE formatted string with encrypted data.
decrypt
crypto.jwe.decrypt(private_key, encrypted_data): Promise<string>
Decrypts JWE formatted string with encrypted data using private Json Web Key. Returns decrypted data string.
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.
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.
hashSHA512
crypto.util.hmacSHA512(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.
hashSHA512 with salt
crypto.util.hmacSHA512(data: string | NodeJS.ArrayBufferView, salt: string | NodeJS.ArrayBufferView): string;
Calculate the SHA-512 hash 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.
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)
})
// 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)
})