2016-06-24 15:54:08 +01:00
# js-libp2p-crypto
2016-05-19 18:47:48 +02:00
2019-02-26 03:25:16 -05:00
[](http://protocol.ai)
[](http://libp2p.io/)
[](http://webchat.freenode.net/?channels=%23libp2p)
2019-04-18 18:29:45 +01:00
[](https://discuss.libp2p.io)
[](https://codecov.io/gh/libp2p/js-libp2p-crypto)
[](https://travis-ci.com/libp2p/js-libp2p-crypto)
2016-09-11 12:55:41 -04:00
[](https://david-dm.org/libp2p/js-libp2p-crypto)
[](https://github.com/feross/standard)
2016-10-03 23:15:21 +11:00
2016-05-19 18:47:48 +02:00
> Crypto primitives for libp2p in JavaScript
2017-07-22 10:57:27 -07:00
This repo contains the JavaScript implementation of the crypto primitives needed for libp2p. This is based on this [go implementation ](https://github.com/libp2p/go-libp2p-crypto ).
2016-05-19 18:47:48 +02:00
2018-05-29 14:22:48 +01:00
## Lead Maintainer
2019-09-26 12:51:16 +02:00
[Jacob Heun ](https://github.com/jacobheun/ )
2018-05-29 14:22:48 +01:00
2016-06-24 15:54:08 +01:00
## Table of Contents
2019-07-10 17:15:26 +01:00
- [js-libp2p-crypto ](#js-libp2p-crypto )
- [Lead Maintainer ](#Lead-Maintainer )
- [Table of Contents ](#Table-of-Contents )
- [Install ](#Install )
- [API ](#API )
- [`crypto.aes` ](#cryptoaes )
- [`crypto.aes.create(key, iv)` ](#cryptoaescreatekey-iv )
- [`decrypt(data)` ](#decryptdata )
- [`encrypt(data)` ](#encryptdata )
- [`crypto.hmac` ](#cryptohmac )
- [`crypto.hmac.create(hash, secret)` ](#cryptohmaccreatehash-secret )
- [`digest(data)` ](#digestdata )
- [`crypto.keys` ](#cryptokeys )
- [`crypto.keys.generateKeyPair(type, bits)` ](#cryptokeysgenerateKeyPairtype-bits )
- [`crypto.keys.generateEphemeralKeyPair(curve)` ](#cryptokeysgenerateEphemeralKeyPaircurve )
- [`crypto.keys.keyStretcher(cipherType, hashType, secret)` ](#cryptokeyskeyStretchercipherType-hashType-secret )
- [`crypto.keys.marshalPublicKey(key, [type])` ](#cryptokeysmarshalPublicKeykey -type)
- [`crypto.keys.unmarshalPublicKey(buf)` ](#cryptokeysunmarshalPublicKeybuf )
- [`crypto.keys.marshalPrivateKey(key, [type])` ](#cryptokeysmarshalPrivateKeykey -type)
- [`crypto.keys.unmarshalPrivateKey(buf)` ](#cryptokeysunmarshalPrivateKeybuf )
- [`crypto.keys.import(pem, password)` ](#cryptokeysimportpem-password )
- [`crypto.randomBytes(number)` ](#cryptorandomBytesnumber )
- [`crypto.pbkdf2(password, salt, iterations, keySize, hash)` ](#cryptopbkdf2password-salt-iterations-keySize-hash )
- [Contribute ](#Contribute )
- [License ](#License )
2016-06-24 15:54:08 +01:00
## Install
```sh
npm install --save libp2p-crypto
```
2019-07-17 11:17:18 +01:00
## Usage
```js
const crypto = require('libp2p-crypto')
// Now available to you:
//
// crypto.aes
// crypto.hmac
// crypto.keys
// etc.
//
// See full API details below...
```
### Web Crypto API
The `libp2p-crypto` library depends on the [Web Crypto API ](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API ) in the browser. Web Crypto is available in all modern browsers, however browsers restrict its usage to [Secure Contexts ](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts ).
2019-07-17 15:23:41 +01:00
**This means you will not be able to use some `libp2p-crypto` functions in the browser when the page is served over HTTP.** To enable the Web Crypto API and allow `libp2p-crypto` to work fully, please serve your page over HTTPS.
2019-07-17 11:17:18 +01:00
2017-07-22 10:57:27 -07:00
## API
2016-06-24 15:54:08 +01:00
2017-07-22 10:57:27 -07:00
### `crypto.aes`
2016-06-24 15:54:08 +01:00
2019-07-17 11:17:18 +01:00
Exposes an interface to AES encryption (formerly Rijndael), as defined in U.S. Federal Information Processing Standards Publication 197.
2016-05-19 18:47:48 +02:00
2017-07-22 10:57:27 -07:00
This uses `CTR` mode.
2016-05-19 20:18:31 +02:00
2019-07-10 17:15:26 +01:00
#### `crypto.aes.create(key, iv)`
2016-10-03 23:15:21 +11:00
2017-07-22 10:57:27 -07:00
- `key: Buffer` The key, if length `16` then `AES 128` is used. For length `32` , `AES 256` is used.
- `iv: Buffer` Must have length `16` .
2016-10-03 23:15:21 +11:00
2019-07-10 17:15:26 +01:00
Returns `Promise<{decrypt<Function>, encrypt<Function>}>`
##### `decrypt(data)`
2016-10-03 23:15:21 +11:00
2017-07-22 10:57:27 -07:00
- `data: Buffer`
2016-10-03 23:15:21 +11:00
2019-07-10 17:15:26 +01:00
Returns `Promise<Buffer>`
##### `encrypt(data)`
2016-10-03 23:15:21 +11:00
- `data: Buffer`
2019-07-10 17:15:26 +01:00
Returns `Promise<Buffer>`
2016-10-03 23:15:21 +11:00
2018-05-27 14:38:24 +01:00
```js
2019-07-10 17:15:26 +01:00
const crypto = require('libp2p-crypto')
2018-05-27 14:38:24 +01:00
// Setting up Key and IV
// A 16 bytes array, 128 Bits, AES-128 is chosen
2019-07-10 17:15:26 +01:00
const key128 = Buffer.from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
2018-05-27 14:38:24 +01:00
// A 16 bytes array, 128 Bits,
2019-07-10 17:15:26 +01:00
const IV = Buffer.from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
2018-05-27 14:38:24 +01:00
async function main () {
2019-07-10 17:15:26 +01:00
const decryptedMessage = 'Hello, world!'
2018-05-27 14:38:24 +01:00
// Encrypting
2019-07-10 17:15:26 +01:00
const cipher = await crypto.aes.create(key128, IV)
const encryptedBuffer = await cipher.encrypt(Buffer.from(decryptedMessage))
console.log(encryptedBuffer)
// prints: < Buffer 42 f1 67 d9 2e 42 d0 32 9e b1 f8 3c >
2018-05-27 14:38:24 +01:00
// Decrypting
2019-07-10 17:15:26 +01:00
const decipher = await crypto.aes.create(key128, IV)
const decryptedBuffer = await cipher.decrypt(encryptedBuffer)
console.log(decryptedBuffer)
// prints: < Buffer 42 f1 67 d9 2e 42 d0 32 9e b1 f8 3c >
console.log(decryptedBuffer.toString('utf-8'))
// prints: Hello, world!
2018-05-27 14:38:24 +01:00
}
2019-07-10 17:15:26 +01:00
main()
2017-07-22 10:57:27 -07:00
```
2016-10-03 23:15:21 +11:00
2017-07-22 10:57:27 -07:00
### `crypto.hmac`
2016-10-03 23:15:21 +11:00
2017-07-22 10:57:27 -07:00
Exposes an interface to the Keyed-Hash Message Authentication Code (HMAC) as defined in U.S. Federal Information Processing Standards Publication 198. An HMAC is a cryptographic hash that uses a key to sign a message. The receiver verifies the hash by recomputing it using the same key.
2016-10-03 23:15:21 +11:00
2019-07-10 17:15:26 +01:00
#### `crypto.hmac.create(hash, secret)`
2016-10-03 23:15:21 +11:00
2017-07-22 10:57:27 -07:00
- `hash: String`
- `secret: Buffer`
2016-10-03 23:15:21 +11:00
2019-07-10 17:15:26 +01:00
Returns `Promise<{digest<Function>}>`
##### `digest(data)`
2016-10-03 23:15:21 +11:00
- `data: Buffer`
2019-07-10 17:15:26 +01:00
Returns `Promise<Buffer>`
2016-10-03 23:15:21 +11:00
2017-07-22 10:57:27 -07:00
Example:
2016-10-03 23:15:21 +11:00
2018-05-27 14:38:24 +01:00
```js
2019-07-10 17:15:26 +01:00
const crypto = require('libp2p-crypto')
2018-05-27 14:38:24 +01:00
2019-07-10 17:15:26 +01:00
async function main () {
const hash = 'SHA1' // 'SHA256' || 'SHA512'
const hmac = await crypto.hmac.create(hash, Buffer.from('secret'))
const sig = await hmac.digest(Buffer.from('hello world'))
console.log(sig)
}
2018-05-27 14:38:24 +01:00
2019-07-10 17:15:26 +01:00
main()
2017-07-22 10:57:27 -07:00
```
2016-10-03 23:15:21 +11:00
2017-07-22 10:57:27 -07:00
### `crypto.keys`
2016-10-03 23:15:21 +11:00
2017-07-22 10:57:27 -07:00
**Supported Key Types**
2017-02-04 04:23:38 -05:00
2019-07-10 17:15:26 +01:00
The [`generateKeyPair` ](#generatekeypairtype-bits ), [`marshalPublicKey` ](#marshalpublickeykey-type ), and [`marshalPrivateKey` ](#marshalprivatekeykey-type ) functions accept a string `type` argument.
2017-02-04 04:23:38 -05:00
2020-04-06 15:44:36 -05:00
Currently the `'RSA'` , `'ed25519'` , and `secp256k1` types are supported, although ed25519 and secp256k1 keys support only signing and verification of messages. For encryption / decryption support, RSA keys should be used.
2017-02-04 04:23:38 -05:00
2019-07-10 17:15:26 +01:00
### `crypto.keys.generateKeyPair(type, bits)`
2016-05-19 20:18:31 +02:00
2017-02-04 04:23:38 -05:00
- `type: String` , see [Supported Key Types ](#supported-key-types ) above.
2016-10-03 23:15:21 +11:00
- `bits: Number` Minimum of 1024
2019-07-10 17:15:26 +01:00
Returns `Promise<{privateKey<Buffer>, publicKey<Buffer>}>`
2016-05-19 21:45:43 +02:00
Generates a keypair of the given type and bitsize.
2019-07-10 17:15:26 +01:00
### `crypto.keys.generateEphemeralKeyPair(curve)`
2016-05-19 22:33:09 +02:00
- `curve: String` , one of `'P-256'` , `'P-384'` , `'P-521'` is currently supported
2019-07-10 17:15:26 +01:00
Returns `Promise`
2016-05-19 22:33:09 +02:00
Generates an ephemeral public key and returns a function that will compute the shared secret key.
Focuses only on ECDH now, but can be made more general in the future.
2019-07-10 17:15:26 +01:00
Resolves to an object of the form:
2016-10-03 23:15:21 +11:00
2016-05-20 12:50:16 +02:00
```js
{
key: Buffer,
genSharedKey: Function
}
```
2016-05-19 22:33:09 +02:00
2019-07-10 17:15:26 +01:00
### `crypto.keys.keyStretcher(cipherType, hashType, secret)`
2016-05-20 15:55:19 +02:00
- `cipherType: String` , one of `'AES-128'` , `'AES-256'` , `'Blowfish'`
- `hashType: String` , one of `'SHA1'` , `SHA256` , `SHA512`
- `secret: Buffer`
2019-07-10 17:15:26 +01:00
Returns `Promise`
2016-05-20 15:55:19 +02:00
Generates a set of keys for each party by stretching the shared key.
2019-07-10 17:15:26 +01:00
Resolves to an object of the form:
2017-07-22 10:57:27 -07:00
2016-05-20 15:55:19 +02:00
```js
{
k1: {
iv: Buffer,
cipherKey: Buffer,
macKey: Buffer
},
k2: {
iv: Buffer,
cipherKey: Buffer,
macKey: Buffer
}
}
```
2016-10-03 23:15:21 +11:00
2019-07-10 17:15:26 +01:00
### `crypto.keys.marshalPublicKey(key, [type])`
2016-05-19 21:45:43 +02:00
2020-04-06 15:44:36 -05:00
- `key: keys.rsa.RsaPublicKey | keys.ed25519.Ed25519PublicKey | keys.secp256k1.Secp256k1PublicKey`
2019-07-10 17:15:26 +01:00
- `type: String` , see [Supported Key Types ](#supported-key-types ) above. Defaults to 'rsa'.
Returns `Buffer`
2016-05-19 21:45:43 +02:00
Converts a public key object into a protobuf serialized public key.
2017-07-22 10:57:27 -07:00
### `crypto.keys.unmarshalPublicKey(buf)`
2016-05-19 21:45:43 +02:00
- `buf: Buffer`
2019-07-10 17:15:26 +01:00
Returns `RsaPublicKey|Ed25519PublicKey|Secp256k1PublicKey`
2016-05-19 21:45:43 +02:00
2019-07-10 17:15:26 +01:00
Converts a protobuf serialized public key into its representative object.
### `crypto.keys.marshalPrivateKey(key, [type])`
2016-05-19 21:45:43 +02:00
2020-04-06 15:44:36 -05:00
- `key: keys.rsa.RsaPrivateKey | keys.ed25519.Ed25519PrivateKey | keys.secp256k1.Secp256k1PrivateKey`
2017-02-04 04:23:38 -05:00
- `type: String` , see [Supported Key Types ](#supported-key-types ) above.
2016-05-19 21:45:43 +02:00
2019-07-10 17:15:26 +01:00
Returns `Buffer`
2016-05-19 21:45:43 +02:00
Converts a private key object into a protobuf serialized private key.
2019-07-10 17:15:26 +01:00
### `crypto.keys.unmarshalPrivateKey(buf)`
2016-05-19 21:45:43 +02:00
- `buf: Buffer`
2019-07-10 17:15:26 +01:00
Returns `Promise<RsaPrivateKey|Ed25519PrivateKey|Secp256k1PrivateKey>`
2016-10-03 23:15:21 +11:00
Converts a protobuf serialized private key into its representative object.
2016-05-19 21:45:43 +02:00
2020-08-05 17:14:12 +02:00
### `crypto.keys.import(encryptedKey, password)`
2017-12-20 21:11:47 +13:00
2020-08-05 17:14:12 +02:00
- `encryptedKey: string`
2017-12-20 21:11:47 +13:00
- `password: string`
2019-07-10 17:15:26 +01:00
2020-08-05 17:14:12 +02:00
Returns `Promise<PrivateKey>`
2017-12-20 21:11:47 +13:00
2020-08-05 17:14:12 +02:00
Converts an exported private key into its representative object. Supported formats are 'pem' (RSA only) and 'libp2p-key'.
### `privateKey.export(password, format)`
- `password: string`
- `format: string` the format to export to: 'pem' (rsa only), 'libp2p-key'
Returns `string`
Exports the password protected `PrivateKey` . RSA keys will be exported as password protected PEM by default. Ed25519 and Secp256k1 keys will be exported as password protected AES-GCM base64 encoded strings ('libp2p-key' format).
2017-12-20 21:11:47 +13:00
2017-07-22 10:57:27 -07:00
### `crypto.randomBytes(number)`
2016-12-01 11:42:19 +00:00
- `number: Number`
2019-07-10 17:15:26 +01:00
Returns `Buffer`
2016-12-01 11:42:19 +00:00
Generates a Buffer with length `number` populated by random bytes.
2016-06-24 15:54:08 +01:00
2017-12-20 21:11:47 +13:00
### `crypto.pbkdf2(password, salt, iterations, keySize, hash)`
- `password: String`
- `salt: String`
- `iterations: Number`
- `keySize: Number` in bytes
- `hash: String` the hashing algorithm ('sha1', 'sha2-512', ...)
Computes the Password Based Key Derivation Function 2; returning a new password.
2016-06-24 15:54:08 +01:00
## Contribute
2016-09-30 14:43:40 -04:00
Feel free to join in. All welcome. Open an [issue ](https://github.com/libp2p/js-libp2p-crypto/issues )!
2016-06-24 15:54:08 +01:00
This repository falls under the IPFS [Code of Conduct ](https://github.com/ipfs/community/blob/master/code-of-conduct.md ).
[](https://github.com/ipfs/community/blob/master/contributing.md)
## License
2017-12-20 21:11:47 +13:00
[MIT ](./LICENSE )