Key Exchange¶
Class Name | KeyExchange |
---|---|
Extends | Logger |
Source | keyExchange.ts |
Examples | keyExchange.spec.ts |
The KeyExchange
module is used to exchange communication keys between two parties, assuming that both have created a profile and have a public facing partial Diffie Hellman key part (the combination of their own secret and the shared secret). The key exchange consists of three steps:
- create a new communication key, that will be used by both parties for en- and decryption and store it on the initiators side
- look up the other parties partial Diffie Hellman key part and combine it with the own private key to create the exchange key
- use the exchange key to encrypt the communication key and send it via bmail (blockchain mail) to other party
Basic Usage¶
Starting the Key Exchange Process¶
This example retrieves public facing partial Diffie Hellman key part from a second party and sends an invitation mail to it:
// identity, that initiates the invitation
const identity1 = '0x0000000000000000000000000000000000000001';
// identity, that will receive the invitation
const identity2 = '0x0000000000000000000000000000000000000002';
// profile from user, that initiates key exchange
const profile1 = {};
await profile1.loadForAccount();
// profile from user, that is going to receive the invitation
const profile2 = {};
await profile2.loadForAccount();
// key exchange instance for identity1
const keyExchange1 = {};
// key exchange instance for identity2
const keyExchange2 = {};
const foreignPubkey = await profile2.getPublicKey();
const commKey = await keyExchange1.generateCommKey();
await keyExchange1.sendInvite(identity2, foreignPubkey, commKey, {
fromAlias: 'Bob', // initiating user states, that his name is 'Bob'
});
await profile1.addContactKey(identity2, 'commKey', commKey);
await profile1.storeForAccount(profile1.treeLabels.addressBook);
Finishing the Key Exchange Process¶
Let’s assume that the communication key from the last example has been successfully sent to the other party and continue at there end from here. To keep the roles from the last example, the variables profile1, profile2 will belong to the same identites:
const encryptedCommKey = '...'; // key sent by identity1
const profile1 = await profile1.getPublicKey();
const commSecret = keyExchange2.computeSecretKey(profile1);
const commKey = await keyExchange2.decryptCommKey(encryptedCommKey, commSecret.toString('hex'));
constructor¶
new KeyExchange(options);
Creates a new KeyExchange instance.
Parameters¶
options
-KeyExchangeOptions
: options for KeyExchange constructor.account
-string
: address of identity or account, that will perform actionscryptoProvider
-CryptoProvider
:CryptoProvider
instancedefaultCryptoAlgo
-string
: default encryption algorithmkeyProvider
-KeyProviderInterface
:KeyProviderInterface
instancemailbox
-Mailbox
:Mailbox
instancelog
-Function
(optional): function to use for logging:(message, level) => {...}
logLevel
-LogLevel
(optional): messages with this level will be logged withlog
logLog
-LogLogInterface
(optional): container for collecting log messageslogLogLevel
-LogLevel
(optional): messages with this level will be pushed tologLog
privateKey
-object
(optional): private key for key exchange, ifprivateKey
orpublicKey
is omitted, new keys are generatedpublicKey
-object
(optional): public key for key exchange, ifprivateKey
orpublicKey
is omitted, new keys are generated
Returns¶
KeyExchange
instance
Example¶
const keyExchange = new KeyExchange({
mailbox,
cryptoProvider,
defaultCryptoAlgo: 'aes',
account: identities[0],
keyProvider,
});
computeSecretKey¶
keyExchange.computeSecretKey(partialKey);
Combines given partial key from another profile with own private key.
Parameters¶
partialKey
-string
: The options used for calling
Returns¶
string
combined exchange key
Example¶
// encrypted communication key sent from identity 1 to identity 2
const encryptedKey = '...'
// (profile 1 belongs to identity 1, keyExchange 2 to identity 2)
const publicKeyProfile1 = await profile1.getPublicKey();
const commSecret = keyExchange2.computeSecretKey(publicKeyProfile1);
commKey = await keyExchange2.decryptCommKey(encryptedKey, commSecret.toString('hex'));
decryptCommKey¶
keyExchange.decryptCommKey(encryptedCommKey, exchangeKey);
Decrypts a given communication key with an exchange key.
Parameters¶
encryptedCommKey
-string
: encrypted communications key received from another identity or accountexchangeKey
-string
: Diffie Hellman exchange key from computeSecretKey
Returns¶
Promise
returns Buffer
: commKey as a buffer
Example¶
// encrypted communication key sent from identity 1 to identity 2
const encryptedKey = '...'
// (profile 1 belongs to identity 1, keyExchange 2 to identity 2)
const publicKeyProfile1 = await profile1.getPublicKey();
const commSecret = keyExchange2.computeSecretKey(publicKeyProfile1);
commKey = await keyExchange2.decryptCommKey(encryptedKey, commSecret.toString('hex'));
getDiffieHellmanKeys¶
keyExchange.getDiffieHellmanKeys();
Returns the public and private key from the diffieHellman.
Parameters¶
(void)
Returns¶
Promise
returns any
: object with public and private keys
Example¶
console.dir(await keyExchange.getDiffieHellmanKeys());
// Output:
// {
// private: '...',
// public: '...',
// }
generateCommKey¶
keyExchange.generateCommKey();
Generates a new communication key end returns the hex string.
Parameters¶
(none)
Returns¶
Promise
returns string
: comm key as string
Example¶
console.dir(await keyExchange.generateCommKey());
// Output:
// '1c967697c192235680efbb24b980981b4778c8058b5e0864f1471fc1d941499d'
getExchangeMail¶
keyExchange.getExchangeMail(from, mailContent[, encryptionCommKey]);
Creates a bmail for exchanging comm keys.
Parameters¶
from
-string
: sender identity or accountmailContent
-any
: bmail metadataencryptedCommKey
-string
(optional): comm key, that should be exchanged
Returns¶
Promise
returns Mail
: mail for key exchange
Example¶
const commKey = '1c967697c192235680efbb24b980981b4778c8058b5e0864f1471fc1d941499d';
const mail = keyExchange.getExchangeMail(
'0x0000000000000000000000000000000000000001',
{ fromAlias: 'user 1', fromMail: 'user1@example.com', title:'sample', body:'sample', }
);
console.log(mail);
// Output:
// { content:
// { from: '0x0000000000000000000000000000000000000001',
// fromAlias: 'user 1',
// fromMail: 'user1@example.com',
// title: 'sample',
// body: 'sample',
// attachments: [ [Object] ] } }
sendInvite¶
keyExchange.sendInvite(receiver, receiverPublicKey, commKey, mailContent);
Sends a mailbox mail to the target with the partial key for the key exchange.
Parameters¶
string
-receiver
: receiver of the invitationstring
-receiverPublicKey
: public key of the receiverstring
-commKey
: communication key between sender and receiverany
-mailContent
: mail to send
Returns¶
Promise
returns void
: resolved when done
Example¶
const foreignPubkey = await profile2.getPublicKey();
const commKey = await keyExchange1.generateCommKey();
await keyExchange1.sendInvite(identities[1], foreignPubkey, commKey, { fromAlias: 'Bob', });
await profile.addContactKey(identities[1], 'commKey', commKey);
await profile.storeForAccount(profile.treeLabels.addressBook);
setPublicKey¶
keyExchange.setPublicKey(publicKey, privateKey);
Set the private and public key on the current diffieHellman object.
Parameters¶
publicKey
-string
: public Diffie Hellman keyprivateKey
-string
: private Diffie Hellman key
Returns¶
(no return value)
Example¶
keyExchange.setPublicKey('...', '...');