New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@consento/crypto

Package Overview
Dependencies
Maintainers
2
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@consento/crypto

Crypto functionality used in Consento

  • 0.0.9
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
38
increased by3700%
Maintainers
2
Weekly downloads
 
Created
Source

@consento/crypto

@consento/crypto is a set of crypto primitives useful for the communication within the consento workflow.

Setup the crypto system

In order to be quick in node.js and have a functional react-native-compatible implementation @consento/crypto comes with two variants of crypto functions.

  • sodium that uses a modified version of libsodium.js which runs on react-native
  • friends that uses a sodium-universal from sodium-friends which runs efficiently on node.js and in the browser.

To get access to the actual API you will always need to run setup first:

import { setup } from '@consento/crypto'
import { sodium } from '@consento/crypto/core/sodium'
import { friends } from '@consento/crypto/core/friends'

const cryptoFriends = setup(friends) // sodium-universal variant of crypto
const cryptoSodium = setup(sodium) // libsodium.js variant of crypto

Sending/Receiving encrypted messages

The crypto library contains useful primitives for sending e2e encrypted messages through public channels:

const { Sender } = setup(sodium)

You can create a new communication channel by creating a new sender:

const sender = Sender.create()
sender.id // public channel id - can be shared with other people - also used to verify if a message was properly sent.
sender.receiveKey // channel reader id - to be used for decrypting sent messages
sender.sendKey // encryption key for messages

Permission layers

A Sender > Receiver > Annonymous and there are methods to create a receiver/annonymous instance out of a sender instance:

const sender = Sender.create()
const receiver = sender.newReceiver()
const annonymous = sender.newAnnonymous()

Every instance can verify a given message for a channel:

const bool = await annonymous.verify(signature: Uint8Array, body: Uint8Array)
const bool2 = await annonymous.verifyMessage(message: IEncryptedMessage)

Only receivers and senders can decrypt a message:

const message = await receiver.decrypt(message: IEncryptedMessage)

since signing is not the same as encrypting, it is also possible to sign messages for receivers.

const signature = await receiver.sign(message: Uint8Array)

but only senders are able to encrypt messages.

const encrypted: IEncryptedMessage = await sender.encrypt(message)

De-/Serialization

The Sender/Receiver/Annonymous prototypes can be easily stored and restored using:

const senderJson = await sender.quickJSON()
const restoredSender = new Sender(json)

Beside the quickJSON there is also a smallJSON option. quickJSON can be restored quicker but requires a bit more memory. smallJSON needs more memory but the restoring process is a bit slower.

Creating a handshake

crypto also holds primitives for a decentralized handshake mechanism.

const { HandshakeInit, HandshakeAccept } = setup(sodium)

HandshakeInit is to be used by the first person - "Alice".

HandshakeAccept is to be used by the second person - "Bob".

How the handshake works:

  1. Alice needs to create the initial message:

    const alice = new HandshakeInit()
    const initMessage = await alice.initMessage()
    
  2. Alice needs to listen to the channel with the id alice.receiver.id for answers that may come from Bob.

  3. Alice needs to send hand the initial message to Bob using any means. (QR Code, Email,...)

  4. Bob needs to receive the initial message

    const bob = new HandshakeAccept(initMessage)
    
  5. Bob needs to listen to the channel with the id bob.receiver.id for the final message from Alice.

  6. Bob needs to send the message, encrypted to the channel with the id: bob.sender.id:

    await bob.sender.encrypt(await bob.acceptMessage())
    
  7. Alice has to receive the acception message and can generate the channels out of it.

    const package = await alice.confirm((await alice.receiver.decrypt(acceptMessage)).body)
    const {
      sender: aliceToBobSender, // channel to send messages to Bob
      receiver: bobToAliceReceiver, // channel to receive messages from Bob
      finalMessage
    } = package
    
  8. Alice has to send the final message to bob:

    await aliceToBobSender.encrypt(finalMessage)
    
  9. Bob can now finalize the handshake

    const { sender: bobToAliceSender, receiver: aliceToBobReceiver } = await bob.finalize(finalMessage)
    

Now Alice and Bob have each two channels: one to send data to, one to receive data from.

(await bobToAliceReceiver.decrypt(await aliceToBobSender.encrypt('Hello Bob!')).body // Hello Bob!
(await aliceToBobReceiver.decrypt(await bobToAliceSender.encrypt('Hello Alice!'))).body // Hello Alice!

License

MIT

FAQs

Package last updated on 31 Dec 2019

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc