# Tutorial: Encrypt and sign a message
With ethereum-keys you cannot only interact with the blockchain, but also use them to send messages over mutual untrusted channels in a secure way. In this tutorial we will use ethereum-identities to send messages like you would do in a decentralized chat-app.
## Prerequisites
First we create two identities, `Alice` and `Bob` . In our case `Alice` wants to send the message `My name is Satoshi Buterin` to `Bob` .
```javascript
const EthCrypto = require('eth-crypto');
const alice = EthCrypto.createIdentity();
const bob = EthCrypto.createIdentity();
const secretMessage = 'My name is Satoshi Buterin';
```
## Encrypt and sign the message
Before we send the message from `Alice` to `Bob` , we want to ensure that
- Only `Bob` can read the message
- `Bob` can be sure that the message really comes from `Alice`
To do this, we first sign the message with alice's privateKey and then encrypt the message and the signature with bob's publicKey.
```javascript
const signature = EthCrypto.sign(
alice.privateKey,
EthCrypto.hash.keccak256(secretMessage)
);
const payload = {
message: secretMessage,
signature
};
const encrypted = await EthCrypto.encryptWithPublicKey(
bob.publicKey, // by encrypting with bobs publicKey, only bob can decrypt the payload with his privateKey
JSON.stringify(payload) // we have to stringify the payload before we can encrypt it
);
/* { iv: 'c66fbc24cc7ef520a7...',
ephemPublicKey: '048e34ce5cca0b69d4e1f5...',
ciphertext: '27b91fe986e3ab030...',
mac: 'dd7b78c16e462c42876745c7...'
}
*/
// we convert the object into a smaller string-representation
const encryptedString = EthCrypto.cipher.stringify(encrypted);
// > '812ee676cf06ba72316862fd3dabe7e403c7395bda62243b7b0eea5eb..'
// now we send the encrypted string to bob over the internet.. *bieb, bieb, blob*
```
## Decrypt and verify the payload
When bob receives the message, he starts with decrypting it with his privateKey and then verifies the signature.
```javascript
// we parse the string into the object again
const encryptedObject = EthCrypto.cipher.parse(encryptedString);
const decrypted = await EthCrypto.decryptWithPrivateKey(
bob.privateKey,
encryptedObject
);
const decryptedPayload = JSON.parse(decrypted);
// check signature
const senderAddress = EthCrypto.recover(
decryptedPayload.signature,
EthCrypto.hash.keccak256(decryptedPayload.message)
);
console.log(
'Got message from ' +
senderAddress +
': ' +
decryptedPayload.message
);
// > 'Got message from 0x19C24B2d99FB91C5...: "My name is Satoshi Buterin" Buterin'
```
## Creating an answer
Now that `Bob` got the message, he can also answer back to alice.
To do this he has to recover the publicKey of alice with `recoverPublicKey()` .
```javascript
const answerMessage = 'And I am Bob Kelso';
const answerSignature = EthCrypto.sign(
bob.privateKey,
EthCrypto.hash.keccak256(answerMessage)
);
const answerPayload = {
message: answerMessage,
signature: answerSignature
};
const alicePublicKey = EthCrypto.recoverPublicKey(
decryptedPayload.signature,
EthCrypto.hash.keccak256(payload.message)
);
const encryptedAnswer = await EthCrypto.encryptWithPublicKey(
alicePublicKey,
JSON.stringify(answerPayload)
);
// now we send the encryptedAnswer to alice over the internet.. *bieb, bieb, blob*
```