Permalink
Browse files

Added encryption and rudimentary random number generation interface (…

…not working yet)
  • Loading branch information...
1 parent 6d3e637 commit 31af41b962b67ddfd7aa8c8693ccdaf8124877d4 @sschaetz committed Aug 18, 2011
Showing with 268 additions and 16 deletions.
  1. +140 −11 client/crypto.js
  2. +28 −0 client/libs/json2.min.js
  3. +5 −0 client/starbase.js
  4. +95 −5 client/unit/crypto.html
View
@@ -6,8 +6,8 @@ starbase.crypto.dh = function()
{
};
-starbase.crypto.dh = {
-
+starbase.crypto.dh =
+{
// p and g are taken from http://tools.ietf.org/html/rfc5114#section-2.3
p: str2bigInt(
"87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F2" +
@@ -35,12 +35,18 @@ starbase.crypto.dh = {
"184B523D1DB246C32F63078490F00EF8D647D148D4795451" +
"5E2327CFEF98C582664B4C0F6CC41659", 16, 2048),
+ /**
+ * @brief generate the public key from a user secret
+ */
generate_publickey: function(secret)
{
var a = str2bigInt(secret, 16, 2048);
return bigInt2str(powMod(this.g, a, this.p), 16);
},
+ /**
+ * @brief generate the sharedsecret from the user secret and remote public key
+ */
generate_sharedsecret: function(secret, remote_publickey)
{
var a = str2bigInt(secret, 16, 2048);
@@ -50,26 +56,149 @@ starbase.crypto.dh = {
};
+
/**
* derivate keys from password and salt
*/
starbase.crypto.derivation = function()
{
};
-starbase.crypto.derivation = {
+starbase.crypto.derivation =
+{
+ // privatekey and authkey derivation differ in the number of iterations
+
+ /**
+ * @brief generate the privatekey
+ *
+ * This function generates the privatekey.
+ *
+ * @param password password from which privatekey should be derived
+ * @param salt salt that should be used (optional)
+ * @param count number of iterations that should be used (optional)
+ * @param length size of the expected privatekey in bits (optional)
+ */
+ generate_privatekey: function(password, salt, count, length)
+ {
+ salt = typeof(salt) !== 'undefined' ? salt : "j1t22tKUAjs1huwgFULp";
+ count = typeof(count) !== 'undefined' ? count : 2000;
+ if(typeof(length) != 'undefined')
+ return sjcl.misc.pbkdf2(password,
+ sjcl.codec.utf8String.toBits(salt), count, length);
+ else
+ return sjcl.misc.pbkdf2(password,
+ sjcl.codec.utf8String.toBits(salt), count);
+ },
+
+ /**
+ * @brief generate the authkey
+ *
+ * This function generates the authkey.
+ *
+ * @param password password from which authkey should be derived
+ * @param salt salt that should be used (optional)
+ * @param count number of iterations that should be used (optional)
+ * @param length size of the expected privatekey in bits (optional)
+ */
+ generate_authkey: function(password, salt, count, length)
+ {
+ salt = typeof(salt) !== 'undefined' ? salt : "Tj2a3kbixcDU1XHS10Aw";
+ count = typeof(count) !== 'undefined' ? count : 1000;
+ if(typeof(length) !== 'undefined')
+ return sjcl.misc.pbkdf2(password,
+ sjcl.codec.utf8String.toBits(salt), count, length);
+ else
+ return sjcl.misc.pbkdf2(password,
+ sjcl.codec.utf8String.toBits(salt), count);
+ }
+};
+
- generate_privatekey: function(password, salt, count)
+
+/**
+ * encryption and decryption with AES algorithm
+ */
+starbase.crypto.aes = function()
+{
+};
+
+starbase.crypto.aes =
+{
+ /**
+ * @brief encrypts object (through JSON), key derived from password and salt
+ */
+ encrypt_object: function(password, object, salt)
{
- salt = typeof(salt) != 'undefined' ? salt : "2321db5305b388e2373e54d";
- count = typeof(count) != 'undefined' ? count : 2000;
- return sjcl.misc.pbkdf2(password, sjcl.codec.hex.toBits(salt), count, 160);
+ var key = starbase.crypto.derivation.generate_privatekey(password, salt);
+ return sjcl.json.encrypt(key, JSON.stringify(object));
},
- generate_authkey: function(password, salt, count)
+ /**
+ * @brief encrypts object (through JSON), key derived from password and salt
+ */
+ decrypt_json: function(password, jsonstring, salt)
{
- salt = typeof(salt) != 'undefined' ? salt : "19ec222a13efb1d70008141";
- count = typeof(count) != 'undefined' ? count : 1000;
- return sjcl.misc.pbkdf2(password, sjcl.codec.hex.toBits(salt), count);
+ var key = starbase.crypto.derivation.generate_privatekey(password, salt);
+ return JSON.parse(sjcl.json.decrypt(key, jsonstring));
}
};
+
+starbase.crypto.encrypt_object = starbase.crypto.aes.encrypt_object;
+starbase.crypto.decrypt_json = starbase.crypto.aes.decrypt_json;
+
+
+
+/**
+ * random number handling
+ */
+starbase.crypto.random = function()
+{
+};
+
+starbase.crypto.random = {
+
+ counter_: 0,
+
+ start_wait_entropy: function()
+ { console.log("start_wait_entropy original"); },
+
+ wait_entropy: function(progress)
+ {console.log("wait_entropy original " + progress); },
+
+ stop_wait_entropy: function()
+ { console.log("stop_wait_entropy original"); },
+
+ register_callbacks: function(start, wait, stop)
+ {
+ this.start_wait_entropy = start;
+ this.wait_entropy = wait;
+ this.stop_wait_entropy = stop;
+ },
+
+
+ check_entropy()
+ {
+ if(this.counter_ < 5)
+ {
+ this.counter_++;
+ this.wait_entropy(this.counter_);
+ setTimeout("starbase.crypto.random.check_entropy()", 100);
+ }
+ else
+ {
+ this.stop_wait_entropy();
+ this.counter_ = 0;
+ }
+ },
+
+ get: function(num)
+ {
+ if(counter_ < 5)
+ {
+ this.start_wait_entropy();
+ this.check_entropy();
+ }
+ return counter_;
+ }
+
+};
View

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
View
@@ -1,4 +1,9 @@
+"use strict";
+/*jslint indent: 2, bitwise: false, nomen: false, plusplus: false */
+/*white: false, regexp: false, global document, window, escape, unescape */
+
+
/**
* @namespace starbase javascript library
*/
View
@@ -8,6 +8,7 @@
type="text/css" media="screen" />
<script src="http://code.jquery.com/qunit/git/qunit.js"></script>
+<script src="../libs/json2.min.js"></script>
<script src="../libs/sjcl-0.8.min.js"></script>
<script src="../libs/bigint-5.4.min.js"></script>
<script src="../starbase.js"></script>
@@ -117,16 +118,105 @@
test("key derivation", function()
{
- expect(2);
- var P = "password";
- var S = "salt";
- var c = 4096;
+ expect(5);
+
+ var P1 = "password";
+ var S1 = "salt";
+ var c1 = 1;
+ var DK1 = "120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b"
+
+ var P2 = "password";
+ var S2 = "salt";
+ var c2 = 2;
+ var DK2 = "ae4d0c95af6b46d32d0adff928f06dd02a303f8ef3c251dfd6e2d85a95474c43"
+
+ var P3 = "password";
+ var S3 = "salt";
+ var c3 = 4096;
+ var DK3 = "c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a"
+
+ var P4 = "password";
+ var S4 = "salt";
+ var c4 = 16777216;
+ var DK4 = "cf81c66fe8cfc04d1f31ecb65dab4089f7f179e89b3b0bcb17ad10e3ac6eba46"
+
+ var P5 = "passwordPASSWORDpassword";
+ var S5 = "saltSALTsaltSALTsaltSALTsaltSALTsalt";
+ var c5 = 4096;
+ var dklen5 = 40*8;
+ var DK5 = "348c89dbcbd32b2f32d814b8116e84cf2b17347e" +
+ "bc1800181c4e2a1fb8dd53e1c635518c7dac47e9"
- alert(sjcl.codec.hex.fromBits(starbase.crypto.derivation.generate_privatekey(P, S, c)));
+ var P6 = "pass\u0000word";
+ var S6 = "sa\u0000lt";
+ var c6 = 4096;
+ var dklen6 = 16*8;
+ var DK6 = "89b69d0516f829893c696226650a8687"
+
+ equal(
+ sjcl.codec.hex.fromBits(
+ starbase.crypto.derivation.generate_privatekey(P1, S1, c1)
+ ), DK1, "1st example ok");
+
+ equal(
+ sjcl.codec.hex.fromBits(
+ starbase.crypto.derivation.generate_privatekey(P2, S2, c2)
+ ), DK2, "2nd example ok");
+
+ equal(
+ sjcl.codec.hex.fromBits(
+ starbase.crypto.derivation.generate_privatekey(P3, S3, c3)
+ ), DK3, "3rd example ok");
+
+ // this test takes a very long time, we don't usually run it
+ //equal(
+ // sjcl.codec.hex.fromBits(
+ // starbase.crypto.derivation.generate_privatekey(P4, S4, c4)
+ // ), DK4, "4th example ok");
+
+ equal(
+ sjcl.codec.hex.fromBits(
+ starbase.crypto.derivation.generate_privatekey(P5, S5, c5, dklen5)
+ ), DK5, "5th example ok");
+
+ equal(
+ sjcl.codec.hex.fromBits(
+ starbase.crypto.derivation.generate_privatekey(P6, S6, c6, dklen6)
+ ), DK6, "6th example ok");
+
+
+});
+
+
+
+
+module("encryption and decryption");
+
+test("encryption and decryption", function()
+{
+ expect(3);
+ var testdata = ['e', {pluribus: 'unum'}]
+
+ deepEqual(testdata, testdata, "equal operator");
+
+ enc = starbase.crypto.encrypt_object("ey4Tk271mPZpjZEUVGdO", testdata);
+ dec = starbase.crypto.decrypt_json("ey4Tk271mPZpjZEUVGdO", enc);
+
+ deepEqual(dec, testdata, "encryption -> decryption");
+
+ enc = starbase.crypto.encrypt_object("ey4Tk271mPZpjZEUVGdO",
+ testdata, "0FTWLpnX9SGZUcwoTVoF");
+ dec = starbase.crypto.decrypt_json("ey4Tk271mPZpjZEUVGdO",
+ enc, "0FTWLpnX9SGZUcwoTVoF");
+
+ deepEqual(dec, testdata, "encryption -> decryption with salt");
+
});
+
+
});
</script>

0 comments on commit 31af41b

Please sign in to comment.