
Research
Security News
Malicious PyPI Package Exploits Deezer API for Coordinated Music Piracy
Socket researchers uncovered a malicious PyPI package exploiting Deezer’s API to enable coordinated music piracy through API abuse and C2 server control.
@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.
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-nativefriends
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
The crypto library contains useful primitives for sending e2e encrypted messages through public channels:
const { createReceiver } = setup(sodium)
You can create a new communication channel by creating a new receiver:
const receiver = await createReceiver()
receiver.receiveKey // allows decryption of messages
receiver.sender.sendKey // encryption key for sending messages
receiver.sender.annonymous.id // public channel id - can be shared with other people - also used to verify if a message was properly sent.
receiver.sender.id // shortcut on the sender for the channel id
receiver.id // shortcut on the receiver for the channel id
A Receiver
> Sender
> Annonymous
and there are methods to create a receiver/annonymous
instance out of a sender instance:
const { createReceiver } = setup(sodium)
const receiver = await createReceiver()
you can also destruct each instance:
const { receiver, sender, annonymous } = await createReceiver()
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)
The default created Sender/Receiver/Annonymous instances can be serialized/deserialized using common JSON structs:
const { Receiver } = setup(sodium)
const receiverJson = receiver.toJSON()
const restoredReceiver = new Receiver(json)
crypto
also holds primitives for a decentralized handshake mechanism.
const { initHandshake, acceptHandshake } = setup(sodium)
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 = await 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 = await 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
:
await bob.sender.encrypt(bob.acceptMessage)
Alice has to receive the acception message and can generate the channels out of it.
const decryptedAcceptMessage = (await alice.receiver.decryptMessage(acceptMessage)).body
const package = await 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:
await aliceToBobSender.encrypt(finalMessage)
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!
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
} = await 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 = await decryptBlob(blob.secretKey, encrypted)
Blob information is serializable with toJSON
and deserializable using toEncryptedBlob
.
const { encryptBlob, decryptBlob, toEncryptedBlob } = setup(sodium)
const { blob } = await 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 } = await encryptBlob('Hello Secret!')
const sameBlob = await toEncryptedBlob(blob.secretKey)
FAQs
Crypto functionality used in Consento
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.
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.
Security News
Newly introduced telemetry in devenv 1.4 sparked a backlash over privacy concerns, leading to the removal of its AI-powered feature after strong community pushback.