243 lines
8.4 KiB
JavaScript
Executable file
243 lines
8.4 KiB
JavaScript
Executable file
/**
|
|
*
|
|
* @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();
|
|
});
|
|
});
|