-
Notifications
You must be signed in to change notification settings - Fork 790
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How we can code a simple Alice to Bob conversation? I'm needing help to fill some empty spaces... #274
Comments
For now I receive the following error: How we can complete the code? I didn't find a way until now using the docs. |
I recommend AES over 3DES, but that aside... You could just base64-encode the encrypted symmetric keys and IVs and transmit the data using your own custom format (eg: a JSON container). If you're looking for something standard, PKCS#7 will get close to what you want but perhaps not all the way. "Secure Messaging" is being worked on as a JSON-LD format to do pretty much exactly what you want here: |
The private key's Then you can base64 encode the signature for transport. |
Note that "Secure Messaging" has changed slightly to just be about Linked Data signatures and key management: https://web-payments.org/specs/source/ld-signatures/ |
I suggest update the readme to be more clear. I don't know about the others but I had difficulties to understand what should be done next. |
Forge provides JS-based components for working with crypto systems, it doesn't specify what systems to use or how to put them together. In fact, the security of complete systems is more complicated to analyze than component parts on their own. So we don't necessarily want to say "This is how you build a full, secure, message system with forge." That being said, showing an example for how to put an extremely naive system together may be ok, but we must provide appropriate disclaimers. Anyway, here's some refactoring of your code for you to explore further: var forge = require('node-forge');
// 1. Alice generates her key pair.
var alice = {
passphrase: 'Alice passphrase'
};
generateKeyPair(alice);
// 2. Bob generates his key pair.
var bob = {
passphrase: 'Bob passphrase'
};
generateKeyPair(bob);
// 3. Alice sends her PEM public key to Bob via the Internet.
bob.friend = {
publicKey: alice.publicKey
};
// 4. Bob sends his PEM public key to Alice via the Internet.
alice.friend = {
publicKey: bob.publicKey
};
// 5. Alice sends a secret message to Bob via the Internet as JSON.
var encryptedMessage = encryptMessage(alice, 'How are you?');
var json = JSON.stringify(encryptedMessage, null, 2);
console.log('Alice sends: ' + json);
// 6. Bob parses and decrypts the secret message.
encryptedMessage = JSON.parse(json);
var message = decryptMessage(bob, encryptedMessage);
console.log('Bob sees that Alice says: ', message);
// 7. Bob sends a secret response to Alice via the Internet.
encryptedMessage = encryptMessage(bob, 'Doing well.');
json = JSON.stringify(encryptedMessage, null, 2);
console.log('Bob sends: ' + json);
// 8. Alice parses and decrypts the secret message.
encryptedMessage = JSON.parse(json);
var message = decryptMessage(alice, encryptedMessage);
console.log('Alice sees that Bob says: ', message);
function generateKeyPair(person) {
var pair = forge.rsa.generateKeyPair({bits: 2048, e: 0x10001});
person.publicKey = forge.pki.publicKeyToPem(pair.publicKey);
person.privateKey = forge.pki.encryptRsaPrivateKey(
pair.privateKey, person.passphrase);
}
function encryptMessage(person, message) {
// 1. Generate symmetric key and IV.
var key = forge.random.getBytesSync(16);
var iv = forge.random.getBytesSync(16);
// 2. Symmetric-encrypt the message.
var cipher = forge.cipher.createCipher('AES-CBC', key);
cipher.start({iv: iv});
cipher.update(forge.util.createBuffer(message, 'utf8'));
cipher.finish();
var encryptedMessage = cipher.output.getBytes();
// 3. Sign the encrypted message.
var privateKey = forge.pki.decryptRsaPrivateKey(
person.privateKey, person.passphrase);
var md = forge.md.sha256.create();
md.update(encryptedMessage);
var signature = privateKey.sign(md);
// 4. Encrypt symmetric key w/friend's public key.
var publicKey = forge.pki.publicKeyFromPem(
person.friend.publicKey);
var encryptedKey = publicKey.encrypt(key);
// 5. Bundle the encrypted message, iv, and signature.
return {
encryptedMessage: forge.util.encode64(encryptedMessage),
encryptedKey: forge.util.encode64(encryptedKey),
iv: forge.util.encode64(iv),
signature: forge.util.encode64(signature)
};
}
function decryptMessage(person, bundle) {
// 1. Verify the signature on the encrypted message.
var encryptedMessage = forge.util.decode64(bundle.encryptedMessage);
var publicKey = forge.pki.publicKeyFromPem(person.friend.publicKey);
var signature = forge.util.decode64(bundle.signature);
var md = forge.md.sha256.create();
md.update(encryptedMessage);
var verified = publicKey.verify(md.digest().getBytes(), signature);
if(!verified) {
throw new Error('Unverified message.');
}
// 2. Decrypt the symmetric key using the private key.
var encryptedKey = forge.util.decode64(bundle.encryptedKey);
var privateKey = forge.pki.decryptRsaPrivateKey(
person.privateKey, person.passphrase);
var key = privateKey.decrypt(encryptedKey);
// 3. Symmetric-decrypt the message.
var iv = forge.util.decode64(bundle.iv);
var cipher = forge.cipher.createDecipher('AES-CBC', key);
cipher.start({iv: iv});
cipher.update(forge.util.createBuffer(encryptedMessage));
if(!cipher.finish()) {
throw new Error('Decryption failed.');
}
// 4. Return the decrypted message.
return cipher.output.getBytes();
} |
An example of a flaw with this approach is that an adversary can potentially capture and replay the messages sent at a later time (a MiTM attack). So, for example, if Bob and Alice are communicating in the clear and their conversation looks like this:
Then an adversary can capture Bob's response and wait to replay it...
|
The text was updated successfully, but these errors were encountered: