Created
September 22, 2011 18:08
-
-
Save lpgauth/1235525 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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