
Security News
vlt Launches "reproduce": A New Tool Challenging the Limits of Package Provenance
vlt's new "reproduce" tool verifies npm packages against their source code, outperforming traditional provenance adoption in the JavaScript ecosystem.
@consento/crypto
Advanced tools
@consento/crypto
is a set of crypto primitives useful for the communication within the
consento workflow.
There are several crypto implementations out there, some work well on the server others work in the browser, however due to asynchronisity issue in the libraries (some are sync, some async) they don't work on either system. This library simplifies existing API's to a distilled version that will work easily on server and mobile phones.
The implementation offered is as synchronous as possible, offering serialization (toJSON/Classes) for all data types.
Channel
- an e2e encrypted setup consisting of one Reader
and one Writer
Writer
- an object containing the keys that allow to encrypt data - it can write on that Channel - it can not read the data!Reader
- an object containing the keys that allow to decrypt data - it can read on that Channel - it can not write to it!Verifier
- an object describing an the capability to verify if a message is part of a Channel
without being able to read it.Connection
- an e2e encrypted setup consisting of the Receiver
of one channel and the Sender
of another.Blob
- a self-contained piece of data, like an image or pdf.Handshake
- the process to connect two separate processes/devices resulting in a Connection
for each process.The crypto library contains useful primitives for sending e2e encrypted messages through public channels.
const { createChannel } = require('@consento/crypto')
const { writer, reader } = createChannel()
const encrypted = writer.encrypt('hello world')
const decrypted = reader.decrypt(encrypted)
decrypted.body === 'hello world'
You can create a new communication channel with the simple createChannel
method.
const channel = createChannel()
const { reader } = channel // Can decrypt messages; _could_ encrypt messages, but these would not be signed and rejected!
const { writer } = channel // Can only encrypt messages.
const { verifier } = channel // Object that can verify messages but not de-/encrypt messages.
reader.readerKey // To backup/restore the receiver
writer.senderKey // To backup/restore the sender
reader.channelKeyBase64 === writer.channelKeyBase64 === verifier.channelKeyBase64
// The lookup id is same here, the channelKey may be used to verify the data, can also be used for the channel
writer.signKey // Allows the writer to sign messages, only privy to the writer
reader.decryptKey // Allows the reader to decrypt messages, only privy to the reader
writer.encryptKey.equals(receiver.encryptKey) // Key to encrypt messages, receiver _can_ write but not sign the message, thus it exists pro-forma
All objects create with createChannel
are well de-/serializable:
const { createChannel, Reader, Writer, Verifier } = require('@consento/crypto')
const { reader, writer, verifier } = createChannel()
new Reader(reader.toJSON())
new Writer(writer.toJSON())
new Verifier(verifier.toJSON())
Both the .sender
and the .receiver
object have a .annoymous
field
to retreive an annonymous instance for the sender/receiver.
const { writer, reader } = createChannel()
writer.verifier.verify(...)
reader.verifier.verify(...)
Encrypt and sign a given input with the sender key.
body
- what you like to encrypt, any serializable object is possibleconst encrypted = writer.encrypt('secret message')
encrypted.signature // Uint8Array
encrypted.body // Uint8Array
Only encrypt the body. This is only recommended in an environment where the signature needs to be created at a different time!
body
- what you like to encrypt, any serializable object is possibleconst encrypted = writer.encrypt('secret message')
encrypted // Uint8Array with an encrypted message
Signs a given data. This is only recommended in an environment where the data was encrypted at a different time!
data
- Uint8Array for which a signature is wantedconst signature = sender.sign(sender.encryptOnly('secret message'))
signature // Uint8Array with the signature of the encrypted message
Using the annonymous object we can verify a given data.
signature
- Uint8Array
with the signature for the body
body
- Uint8Array
with of the encrypted data.const encrypted = writer.encrypt('hello world')
const bool = verifier.verify(encrypted.signature, encrypted.body)
As a short-cut its also possible to just verify a message
message
- { signature: Uint8Array, body: Uint8Array }
const bool = verifier.verifyMessage(message)
Get the content of a once encrypted message.
encrypted
- { signature: Uint8Array, body: Uint8Array }
as created by writer.encrypt
or Uint8Array
created with writer.encryptOnly
const message = reader.decrypt(message:)
crypto
also holds primitives for a decentralized handshake mechanism.
const { initHandshake, acceptHandshake } = require('@consento/crypto')
initHandshake
is to be used by the first person - "Alice".
acceptHandshake
is to be used by the second person - "Bob".
How the handshake works:
Alice needs to create the initial message:
const alice = initHandshake()
const initMessage = alice.firstMessage
Alice needs to listen to the channel with the id alice.receiver.id
for answers that may come from Bob.
Alice needs to send hand the initial message to Bob using any means. (QR Code, Email,...)
Bob needs to receive the initial message
const bob = acceptHandshake(firstMessage)
Bob needs to listen to the channel with the id bob.receiver.id
for the final message from Alice.
Bob needs to send the message, encrypted to the channel with the id: bob.sender.id
:
bob.sender.encrypt(bob.acceptMessage)
Alice has to receive the acception message and can generate the channels out of it.
const decryptedAcceptMessage = alice.receiver.decryptMessage(acceptMessage).body
const package = confirmHandshake(alice, decryptedAcceptMessage)
const {
connection: {
sender: aliceToBobSender, // channel to send messages to Bob
receiver: bobToAliceReceiver, // channel to receive messages from Bob
},
finalMessage
} = package
Alice has to send the final message to bob:
aliceToBobSender.encrypt(finalMessage)
Bob can now finalize the handshake
const { sender: bobToAliceSender, receiver: aliceToBobReceiver } = bob.finalize(finalMessage)
Now Alice and Bob have each two channels: one to send data to, one to receive data from.
bobToAliceReceiver.decrypt(aliceToBobSender.encrypt('Hello Bob!')).body // Hello Bob!
aliceToBobReceiver.decrypt(bobToAliceSender.encrypt('Hello Alice!')).body // Hello Alice!
The crypto api also provides primitives for working with encrypted blobs:
const { encryptBlob, decryptBlob, isEncryptedBlob } = setup(sodium)
const {
blob, // Information about a blob: to pass around
encrypted // Encrypted data to be stored
} = encryptBlob('Hello Secret!')
blob.path // Path at which to store the encrypted data
blob.secretKey // Secretkey to decrypt this data
blob.size // Number of bytes of the encrypted blob (only available after encryption)
isEncryptedBlob(blob) // To verify if a set of data is a blob
const decrypted = decryptBlob(blob.secretKey, encrypted)
Blob information is serializable with toJSON
and deserializable using toEncryptedBlob
.
const { encryptBlob, decryptBlob, toEncryptedBlob } = setup(sodium)
const { blob } = encryptBlob('Hello Secret!')
const blobJSON = blob.toJSON()
const sameBlob = toEncryptedBlob(blobJSON)
It is possible to restore a blob from it's secretKey
but that requires async computation:
const { encryptBlob, decryptBlob, toEncryptedBlob } = setup(sodium)
const { blob } = encryptBlob('Hello Secret!')
const sameBlob = toEncryptedBlob(blob.secretKey)
FAQs
Crypto functionality used in Consento
The npm package @consento/crypto receives a total of 2 weekly downloads. As such, @consento/crypto popularity was classified as not popular.
We found that @consento/crypto demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
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.
Security News
vlt's new "reproduce" tool verifies npm packages against their source code, outperforming traditional provenance adoption in the JavaScript ecosystem.
Research
Security News
Socket researchers uncovered a malicious PyPI package exploiting Deezer’s API to enable coordinated music piracy through API abuse and C2 server control.
Research
The Socket Research Team discovered a malicious npm package, '@ton-wallet/create', stealing cryptocurrency wallet keys from developers and users in the TON ecosystem.