Skip to content

Instantly share code, notes, and snippets.

@lpgauth
Created September 22, 2011 18:08
Show Gist options
  • Save lpgauth/1235525 to your computer and use it in GitHub Desktop.
Save lpgauth/1235525 to your computer and use it in GitHub Desktop.
(function ($) {
var Encrypt = {
getTime: function (millis) {
var secs = Encrypt.varToByteArray(millis / 1000);
var micros = Encrypt.varToByteArray((millis - (secs * 1000)) * 1000);
var ret = new Array(8);
for (var i = 0; i < 8; i++) {
ret[i] = (i < 4) ? secs[i] : micros[i - 4];
}
return ret;
},
varToByteArray: function (v) {
var ret = new Array(4);
ret[0] = (v >> 24) & 255;
ret[1] = (v >> 16) & 255;
ret[2] = (v >> 8) & 255;
ret[3] = v & 255;
return ret;
},
byteArrayToInt: function (ar) {
return (ar[0] << 24) + ((ar[1] & 255) << 16) + ((ar[2] & 255) << 8) + (ar[3] & 255);
},
eub64: function (binArray) {
var b64 = Crypto.util.bytesToBase64(binArray);
return b64.replace("+", "-").replace("/", "_").replace("=", "").replace("==", "");
},
dub64: function (ub64) {
var r = ub64.length % 4;
var pad = "";
if (r == 2) {
pad = "==";
} else if (r == 3) {
pad = "=";
}
return Crypto.util.base64ToBytes(ub64.replace("-", "+").replace("_", "/") + pad);
},
getCryptTime: function (cipher) {
var ar = Encrypt.dub64(cipher);
var secondBytes = new Array(4);
var microsBytes = new Array(4);
for (var i = 0; i < 8; i++) {
if (i < 4) {
secondBytes[i] = ar[i];
} else {
microsBytes[i - 4] = ar[i];
}
}
var seconds = Encrypt.byteArrayToInt(secondBytes);
var micros = Encrypt.byteArrayToInt(microsBytes);
return new Date((seconds * 1000) + (micros / 1000));
},
decrypt: function (encKey, intKey, value) {
var valueBytes = Encrypt.dub64(value);
var iv = new Array(16);
var encValue = new Array(8);
var sig = new Array(4);
for (var i = 0; i < 16; i++) {
iv[i] = valueBytes[i];
}
for (var i = 16; i < 24; i++) {
encValue[i - 16] = valueBytes[i];
}
for (var i = 24; i < 28; i++) {
sig[i - 24] = valueBytes[i];
}
var hmacBytes = Crypto.HMAC(Crypto.SHA1, iv, encKey, {
asBytes: true
});
var decValue = new Array(8);
for (var i = 0; i < 8; i++) {
decValue[i] = encValue[i] ^ hmacBytes[i];
}
var sigBytes = new Array(24);
for (var i = 0; i < 8; i++) {
sigBytes[i] = decValue[i];
}
for (var i = 8; i < 24; i++) {
sigBytes[i] = iv[i - 8];
}
var sigHmac = Crypto.HMAC(Crypto.SHA1, sigBytes, intKey, {
asBytes: true
});
for (var i = 0; i < 4; i++) {
if (sigHmac[i] != sig[i]) {
throw "Invalid signature ";
}
}
var strippedValue = [];
for (var i = 0; i < decValue.length; i++) {
if (decValue[i] != 0) {
strippedValue.push(decValue[i]);
}
}
return Crypto.charenc.Binary.bytesToString(strippedValue);
},
encrypt: function (encKey, intKey, value) {
var iv = new Array(16);
var time = Encrypt.getTime(new Date().getTime());
for (var i = 0; i < 8; i++) {
iv[i] = time[i];
}
for (var i = 8; i < 16; i++) {
iv[i] = Math.floor(Math.random() * 255);
}
var hmacBytes = Crypto.HMAC(Crypto.SHA1, iv, encKey, {
asBytes: true
});
var valueBytes = Crypto.charenc.Binary.stringToBytes(value);
var encValue = new Array(8);
for (var i = 0; i < 8; i++) {
encValue[i] = (hmacBytes[i] ^ valueBytes[i]);
}
var doc = new Array(24);
for (var i = 0; i < 8; i++) {
doc[i] = valueBytes[i];
}
for (var i = 8; i < 24; i++) {
doc[i] = iv[i - 8];
}
var sigBytes = Crypto.HMAC(Crypto.SHA1, doc, intKey, {
asBytes: true
});
var ret = new Array(28);
for (var i = 0; i < 16; i++) {
ret[i] = iv[i];
}
for (var i = 16; i < 24; i++) {
ret[i] = encValue[i - 16];
}
for (var i = 24; i < 28; i++) {
ret[i] = sigBytes[i - 24];
}
return Encrypt.eub64(ret);
}
}
$(function () {
var getElValue = function (elName) {
return $(".encTest input[name='" + elName + "']").attr("value");
}
$(".encTest :button[value='Encrypt']").click(function () {
try {
var enc = Encrypt.encrypt(getElValue("encKey"), getElValue("intKey"), getElValue("encStr"));
$(".encTest .encResult").html(getElValue("encStr") + " encrypted to: <b>" + enc + "</b>");
} catch (e) {
$(".encTest .encResult").html("Error:" + e);
}
});
$(".encTest :button[value='Decrypt']").click(function () {
try {
var dec = Encrypt.decrypt(getElValue("encKey"), getElValue("intKey"), getElValue("decStr"));
$(".encTest .decResult").html(getElValue("decStr") + " Decrypts to: <b><pre style='font-size:large'>'" + dec + "'</pre></b><br/> encrypted on " + Encrypt.getCryptTime(getElValue("decStr")));
} catch (e) {
$(".encTest .decResult").html("Error:" + e);
throw e;
}
});
});
})(jQuery.noConflict(true));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment