/** * * @name node-sodium * @author bmf * @date 11/11/13 * @version $ */ var assert = require('assert'); var sodium = require('../lib/sodium'); describe("Box", function () { it("Example of sending an encrypted message ", function (done) { // Generate random keys for alice and bob var alice = new sodium.Key.Box(); var bob = new sodium.Key.Box(); // Create a signature Alice's side using her secret key and Bob's public key var aliceBox = new sodium.Box(bob.pk(), alice.sk()); var cipherText = aliceBox.encrypt("super secret message", "utf8"); // Alice sends message to Bob, and he decrypts it var bobBox = new sodium.Box(alice.pk(), bob.sk()); var plainText = aliceBox.decrypt(cipherText, "utf8"); assert.equal(plainText, 'super secret message'); done(); }); }); describe("Sign", function () { it("Example of signing a message ", function (done) { // Alice's side // Generate random signing keys for alice var aliceKey = new sodium.Key.Sign(); // Alice signs the message var aliceSign = new sodium.Sign(aliceKey); var signature = aliceSign.sign("important signed message", "utf8"); // Alice sends signed message to bob // Bob's side // Bob receives signature and tries to verify it. // As the var signature includes Alice's public key Bob can simply call verify // Please note that in this simple form Bob can only be sure that the message // was signed with the secret key that is paired with the public key inside // signature. Bob cannot be certain that the public key is indeed Alice's public key // Using public keys directly, ie, without a digital certificate is open to // impersonation using 'man-in-the-middle' attacks. var bobMsg = new sodium.Sign.verify(signature); assert.ok(bobMsg); // Bob checks the message extracted from the signature assert.equal(bobMsg.toString('utf8'), 'important signed message'); done(); }); }); describe("Auth", function () { it("Using authentication tokens ", function (done) { /** * User Side * * The user will use its key ID and secret key to authenticate a message that she * is sending to the server. * The Key ID allows the server to later retrieve the secret key from its database */ var restKeyID = '123123'; var restAPIKey = 'afcd09812fe556aac311de3faade13afcd09812fe556aac311de3faade13ade3'; // User's request to the server var request = 'http://api.example.domain/query?keyid=' + restKeyID; // Create authentication object var auth = new sodium.Auth(restAPIKey); // Generate authentication token for the request var authToken = auth.generate(request, 'utf8'); // Append the authToken to the request var token = authToken.toString('base64'); request += "&token=" + token; // Send request to server. /** * Server Side * * HTTP Server processes the query string and extracts the token and key Id * To keep the example simple we just reuse the token, restAPIKey and restKeyId * variables. * * After extracting the token and key ID from the query string the server can * retrieve the corresponding secret key from a database, and use it to validate * the authentication token. */ var serverAuth = new sodium.Auth(restAPIKey); // In this simulation we just recreate the original query before token was appended request = 'http://api.example.domain/query?keyid=' + restKeyID; // Convert the token to a buffer var tBuffer = sodium.Utils.toBuffer(token, 'base64'); /** * If validate returns true then the token could only have been generated by * the user that has the same secret key as identified by key Id. * The keys and key Ids are usually generated by an administrator when the user * signs up for the service. */ assert.ok(serverAuth.validate(tBuffer, request, 'utf8')); done(); }); }); describe("OneTimeAuth", function () { it("Using one time authentication tokens ", function (done) { /** * User Side * * The user will use its key ID and secret key to authenticate a message that she * is sending to the server. * The Key ID allows the server to later retrieve the secret key from its database * * As the name implies this authentication scheme should only be used one time, * for one message, using the same key. So you should change keys after each * message. */ var restKeyID = '123123'; var restAPIKey = 'afcd09812fe556aac311de3faade13afcd09812fe556aac311de3faade13ade3'; // User's request to the server var request = 'http://api.example.domain/query?keyid=' + restKeyID; // Create authentication object var auth = new sodium.OneTimeAuth(restAPIKey); // Generate authentication token for the request var authToken = auth.generate(request, 'utf8'); // Append the authToken to the request var token = authToken.toString('base64'); request += "&token=" + token; // Send request to server. /** * Server Side * * HTTP Server processes the query string and extracts the token and key Id * To keep the example simple we just reuse the token, restAPIKey and restKeyId * variables. * * After extracting the token and key ID from the query string the server can * retrieve the corresponding secret key from a database, and use it to validate * the authentication token. */ var serverAuth = new sodium.OneTimeAuth(restAPIKey); // In this simulation we just recreate the original query before token was appended request = 'http://api.example.domain/query?keyid=' + restKeyID; // Convert the token to a buffer var tBuffer = sodium.Utils.toBuffer(token, 'base64'); /** * If validate returns true then the token could only have been generated by * the user that has the same secret key as identified by key Id. * The keys and key Ids are usually generated by an administrator when the user * signs up for the service. */ assert.ok(serverAuth.validate(tBuffer, request, 'utf8')); done(); }); }); describe("SecretBox", function () { it("Example of sending an encrypted message ", function (done) { // Alice and Bob both agree on a secret key that they have // shared in some secure way // Alice's Side var aliceKey = Buffer.from("fcd09812fe556aac311de3faade13afa"); var aliceBox = new sodium.SecretBox(aliceKey); // Create a signature Alice's side using her secret key and Bob's public key var cipherText = aliceBox.encrypt("super secret message", "utf8"); // Alice sends message to Bob, and he decrypts it // Bob's Side // Bob uses the same scret key as Alice var bobKey = Buffer.from("fcd09812fe556aac311de3faade13afa"); var bobBox = new sodium.SecretBox(bobKey); var plainText = bobBox.decrypt(cipherText, "utf8"); assert.equal(plainText, 'super secret message'); done(); }); }); describe("ECDH", function () { it("should calculate the same secret", function (done) { var bob = new sodium.Key.ECDH(); var alice = new sodium.Key.ECDH(); var aliceDH = new sodium.ECDH(bob.pk(), alice.sk()); var bobDH = new sodium.ECDH(alice.pk(), bob.sk()); var bobSecret = bobDH.secret(); var aliceSecret = aliceDH.secret(); assert.deepEqual(bobSecret, aliceSecret); done(); }); it("should calculate the same session key", function (done) { var bob = new sodium.Key.ECDH(); var alice = new sodium.Key.ECDH(); var aliceDH = new sodium.ECDH(bob.pk().get(), alice.sk().get()); var bobDH = new sodium.ECDH(alice.pk().get(), bob.sk().get()); var bobSecret = bobDH.sessionKey(); var aliceSecret = aliceDH.sessionKey(); assert.deepEqual(bobSecret, aliceSecret); done(); }); });