Browse Source

Fixed encryption of files, modified UI some more.

tags/2.0.3
Teknikode 4 years ago
parent
commit
fbed5b2ba5

+ 11
- 2
Teknik/Areas/Upload/Controllers/UploadController.cs View File

@@ -18,7 +18,8 @@ namespace Teknik.Areas.Upload.Controllers
{
return View(new UploadViewModel());
}
// GET: Upload/Upload

// User did not supply key
[HttpGet]
[AllowAnonymous]
public ActionResult Download(string url)
@@ -26,6 +27,14 @@ namespace Teknik.Areas.Upload.Controllers
return View(new UploadViewModel());
}

// User supplied key
[HttpGet]
[AllowAnonymous]
public ActionResult Download(string url, string key)
{
return View(new UploadViewModel());
}

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
@@ -34,7 +43,7 @@ namespace Teknik.Areas.Upload.Controllers
Models.Upload upload = Uploader.SaveFile(data, fileType, iv);
if (upload != null)
{
return Json(new { result = new { name = upload.Url, url = Url.SubRouteUrl("upload", "Upload.Download", new { file = upload.Url }) } }, "text/plain");
return Json(new { result = new { name = upload.Url, url = Url.SubRouteUrl("upload", "Upload.Download.Key", new { file = upload.Url, key = "{key}" }), keyVar = "{key}" } }, "text/plain");
}
return Json(new { error = "Unable to upload file" });
}

+ 68
- 57
Teknik/Areas/Upload/Scripts/EncryptionWorker.js View File

@@ -1,58 +1,82 @@
self.addEventListener('message', function (e) {
var data = e.data;
importScripts(data.script);
importScripts(e.data.script);

switch (data.cmd) {
switch (e.data.cmd) {
case 'encrypt':
//var startByte = 0;
//var endByte = 0;
//var prog = [];
var bytes = new Uint8Array(e.data.file);

//var bytes = new Uint8Array(data.file);
var startByte = 0;
var endByte = 0;
var prog = [];

//// Create aes encryptor object
//var aesEncryptor = CryptoJS.algo.AES.createEncryptor(data.key, { iv: data.iv });
var key = CryptoJS.enc.Utf8.parse(e.data.key);
var iv = CryptoJS.enc.Utf8.parse(e.data.iv);
// Create aes encryptor object
var aesEncryptor = CryptoJS.algo.AES.createEncryptor(key, { iv: iv, mode: CryptoJS.mode.CTR, padding: CryptoJS.pad.NoPadding });

//while (startByte <= (bytes.length - 1)) {
// // Set the end byte
// endByte = startByte + data.chunkSize;
// if (endByte > bytes.length - 1)
// {
// endByte = bytes.length - 1;
// }
while (startByte <= (bytes.length - 1)) {
// Set the end byte
endByte = startByte + e.data.chunkSize;
if (endByte > bytes.length - 1)
{
endByte = bytes.length - 1;
}

// Grab current set of bytes
var curBytes = bytes.subarray(startByte, endByte);
//var b64encoded = btoa(String.fromCharCode.apply(null, curBytes));
var wordArray = CryptoJS.lib.WordArray.create(curBytes)

// encrypt the passed in file data
var enc = aesEncryptor.process(wordArray);

// Convert and add to current array buffer
var encStr = enc.toString(CryptoJS.enc.Base64); // to string
prog.pushArray(_base64ToArray(encStr));

// // Grab current set of bytes
// var curBytes = bytes.subarray(startByte, endByte);
// var wordArray = CryptoJS.lib.WordArray.create(curBytes)
// Send an update on progress
var objData =
{
cmd: 'progress',
processed: endByte,
total: bytes.length - 1
};

// // encrypt the passed in file data and add it to bits[]
// prog.push(aesEncryptor.process(wordArray));
self.postMessage(objData);

// // Set the next start as the current end
// startByte = endByte + 1;
//}//then finalize
//prog.push(aesEncryptor.finalize());
// Set the next start as the current end
startByte = endByte + 1;
}

//throw JSON.stringify({ data: prog, start: startByte, end: endByte, len: bytes.length })
var wordArray = CryptoJS.lib.WordArray.create(new Uint8Array(data.file));
//then finalize
var encFinal = aesEncryptor.finalize();
var finalStr = encFinal.toString(CryptoJS.enc.Base64); // to final string
prog.pushArray(_base64ToArray(finalStr));

var objData =
{
cmd: 'progress',
processed: bytes.length - 1,
total: bytes.length - 1
};

var encWords = CryptoJS.AES.encrypt(wordArray, data.key, { iv: data.iv, mode: CryptoJS.mode.CBC });
// convert array to ArrayBuffer
var arBuf = _arrayToArrayBuffer(prog);

//throw JSON.stringify({ data: wordArray });
//throw JSON.stringify({ dataLength: prog.length, len: bytes.length, finalLength: arBuf.byteLength })

var dcBase64String = encWords.toString(); // to Base64-String
//var encByteArray = wordToByteArray(encWords.words);
// patch it all back together for the trip home
// Now package it into a mesage to send home
var objData =
{
encrypted: str2ab(dcBase64String)
cmd: 'finish',
encrypted: arBuf
};

self.postMessage(objData, [objData.encrypted]);
break;
case 'decrypt':
// decrypt the passed in file data
var decrypted = CryptoJS.AES.decrypt(data.file, data.key, { iv: data.iv });
var decrypted = CryptoJS.AES.decrypt(e.data.file, e.data.key, { iv: e.data.iv });

var fileText = decrypted.toString();

@@ -61,36 +85,23 @@
}
}, false);

function wordToByteArray(wordArray) {
var byteArray = [], word, i, j;
for (i = 0; i < wordArray.length; ++i) {
word = wordArray[i];
for (j = 3; j >= 0; --j) {
byteArray.push((word >> 8 * j) & 0xFF);
}
}
return byteArray;
function _arrayToArrayBuffer(array) {
var len = array.length;
var bytes = new Uint8Array(len);
bytes.set(array, 0);
return bytes.buffer;
}

function _base64ToArrayBuffer(base64) {
function _base64ToArray(base64) {
var binary_string = atob(base64);
var len = binary_string.length;
var bytes = new Uint8Array(len);
for (var i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
return bytes.buffer;
return bytes;
}

function ab2str(buf) {
return String.fromCharCode.apply(null, new Uint16Array(buf));
}

function str2ab(str) {
var buf = new ArrayBuffer(str.length); // 2 bytes for each char
var bufView = new Uint16Array(buf);
for (var i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
Array.prototype.pushArray = function (arr) {
this.push.apply(this, arr);
};

+ 121
- 87
Teknik/Areas/Upload/Scripts/Upload.js View File

@@ -3,13 +3,31 @@
$("#upload-links").html('');
});

function linkUploadDelete(selector) {
function linkSaveKey(selector, uploadID, key, fileID) {
$(selector).click(function () {
$.ajax({
type: "POST",
url: saveKeyToServerURL,
data: AddAntiForgeryToken({ uploadID: uploadID, key: key }),
success: function (html) {
if (html.result) {
}
else {
$("#top_msg").css('display', 'inline', 'important');
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>' + html.error + '</div>');
}
}
});
return false;
});
}

function linkUploadDelete(selector, uploadID) {
$(selector).click(function () {
ID = encodeURIComponent($(this).attr('id'));
$.ajax({
type: "POST",
url: generateDeleteKeyURL,
data: AddAntiForgeryToken({ uploadID: ID }),
data: AddAntiForgeryToken({ uploadID: uploadID }),
success: function (html) {
if (html.result) {
bootbox.dialog({
@@ -28,6 +46,15 @@ function linkUploadDelete(selector) {
});
}

function linkRemove(selector, fileID) {
$(selector).click(function () {
$('#link-' + fileID).remove();
return false;
});
}

var fileCount = 0;

Dropzone.options.TeknikUpload = {
paramName: "file", // The name that will be used to transfer the file
maxFilesize: maxUploadSize, // MB
@@ -37,53 +64,39 @@ Dropzone.options.TeknikUpload = {
previewTemplate: function () { },
addedfile: function (file) {
// Create the UI element for the new item
var short_name = file.name.hashCode();
var fileID = fileCount;
fileCount++;
// save ID to the file object
file.ID = fileID;
$("#upload-links").css('display', 'inline', 'important');
$("#upload-links").prepend(' \
<div class="row link-' + short_name + '" id="link-' + short_name + '"> \
<div class="col-sm-12 text-center"> \
'+ file.name + ' \
</div> \
<div class="progress-' + short_name + '"> \
<div class="progress-bar progress-bar-success" id="progressBar-' + short_name + '" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 0%">0%</div> \
<div class="panel panel-default" id="link-' + fileID + '"> \
<div class="panel-heading text-center" id="link-header-' + fileID + '">'+ file.name + '</div> \
<div class="panel-body" id="link-panel-' + fileID + '"> \
<div class="row"> \
<div class="col-sm-12 text-center" id="upload-link-' + fileID + '"></div> \
</div> \
<div class="row"> \
<div class="col-sm-12 text-center"> \
<div class="progress" id="progress-' + fileID + '"> \
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 0%">0%</div> \
</div> \
</div> \
</div> \
</div> \
</div> \
');

// Encrypt the file
encryptFile(file, uploadFile);
$("#upload_message").css('display', 'none', 'important');
},
init: function() {
this.on("removedfile", function(file) {
var name = file.name.hashCode();
$('.link-'+name).remove();
});
this.on("reset", function(file, responseText) {
$("#upload_message").css('display', 'inline', 'important');
$(".progress").children('.progress-bar').css('width', '0%');
$(".progress").children('.progress-bar').html('0%');
});
this.on("error", function(file, errorMessage) {
this.removeFile(file);
$("#top_msg").css('display', 'inline', 'important');
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>'+errorMessage+'</div>');
});
this.on("totaluploadprogress", function(progress, totalBytes, totalBytesSent) {
$(".progress").children('.progress-bar').css('width', (progress.toFixed(2) * (3/5)) + 40 +'%');
$(".progress").children('.progress-bar').html(progress.toFixed(2)+'% Uploaded');
});
this.on("queuecomplete", function() {
$(".progress").children('.progress-bar').html('Complete');
});
this.removeFile(file);
}
};

// Function to encrypt a file, overide the file's data attribute with the encrypted value, and then call a callback function if supplied
function encryptFile(file, callback) {
var filetype = file.type;
var filename = file.name;
var shortName = file.name.hashCode();
var fileID = file.ID;

// Start the file reader
var reader = new FileReader();
@@ -92,30 +105,34 @@ function encryptFile(file, callback) {
reader.onload = (function (callback) {
return function (e) {
// Create random key and iv
var keyStr = randomString(16, '#aA');
var ivStr = randomString(16, '#aA');
var key = CryptoJS.enc.Utf8.parse(keyStr);
var iv = CryptoJS.enc.Utf8.parse(ivStr);

// Display encryption message
$(".progress-" + shortName).children('.progress-bar').css('width', '20%');
$(".progress-" + shortName).children('.progress-bar').html('Encrypting...');
var keyStr = randomString(24, '#aA');
var ivStr = randomString(24, '#aA');

var worker = new Worker(encScriptSrc);

worker.addEventListener('message', function (e) {
if (callback != null) {
// Finish
callback(e.data.encrypted, keyStr, ivStr, filetype, filename);
switch (e.data.cmd)
{
case 'progress':
var percentComplete = Math.round(e.data.processed * 100 / e.data.total);
$("#progress-" + fileID).children('.progress-bar').css('width', (percentComplete * (2 / 5)) + 20 + '%');
$("#progress-" + fileID).children('.progress-bar').html(percentComplete + '% Encrypted');
break;
case 'finish':
if (callback != null) {
// Finish
callback(e.data.encrypted, keyStr, ivStr, filetype, fileID);
}
break;
}
});

worker.onerror = function (err) {
alert(err);

// An error occured
$(".progress-" + shortName).children('.progress-bar').css('width', '100%');
$(".progress-" + shortName).children('.progress-bar').html('Error Occured');
$("#progress-" + fileID).children('.progress-bar').css('width', '100%');
$("#progress-" + fileID).children('.progress-bar').removeClass('progress-bar-success');
$("#progress-" + fileID).children('.progress-bar').addClass('progress-bar-danger');
$("#progress-" + fileID).children('.progress-bar').html('Error Occured');
}

// Execute worker with data
@@ -123,24 +140,31 @@ function encryptFile(file, callback) {
{
cmd: 'encrypt',
script: aesScriptSrc,
key: key,
iv: iv,
chunkSize: 1024,
key: keyStr,
iv: ivStr,
chunkSize: chunkSize,
file: e.target.result
};
worker.postMessage(objData, [objData.file]);
};
})(callback);

reader.onprogress = function (data) {
if (data.lengthComputable) {
var progress = parseInt(((data.loaded / data.total) * 100), 10);
$('#progress-' + fileID).children('.progress-bar').css('width', (progress / 5) + '%');
$('#progress-' + fileID).children('.progress-bar').html(progress + '% Loaded');
}
}

// Start async read
var blob = file.slice(0, file.size);
reader.readAsArrayBuffer(blob);
}

function uploadFile(data, key, iv, filetype, filename)
function uploadFile(data, key, iv, filetype, fileID)
{
$("#key").val(key);
$("#iv").val(iv);
$('#key-' + fileID).val(key);
var blob = new Blob([data]);
// Now we need to upload the file
var fd = new FormData();
@@ -150,51 +174,61 @@ function uploadFile(data, key, iv, filetype, filename)
fd.append('__RequestVerificationToken', $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val());

var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", uploadProgress.bind(null, filename), false);
xhr.addEventListener("load", uploadComplete.bind(null, filename), false);
xhr.addEventListener("error", uploadFailed, false);
xhr.addEventListener("abort", uploadCanceled, false);
xhr.upload.addEventListener("progress", uploadProgress.bind(null, fileID), false);
xhr.addEventListener("load", uploadComplete.bind(null, fileID, key), false);
xhr.addEventListener("error", uploadFailed.bind(null, fileID), false);
xhr.addEventListener("abort", uploadCanceled.bind(null, fileID), false);
xhr.open("POST", uploadFileURL);
xhr.send(fd);
}

function uploadProgress(filename, evt) {
var shortName = filename.hashCode();
function uploadProgress(fileID, evt) {
if (evt.lengthComputable) {
var percentComplete = Math.round(evt.loaded * 100 / evt.total);
$(".progress-" + shortName).children('.progress-bar').css('width', (percentComplete * (3 / 5)) + 40 + '%');
$(".progress-" + shortName).children('.progress-bar').html(percentComplete + '% Uploaded');
}
else {
document.getElementById('progressNumber').innerHTML = 'unable to compute';
$('#progress-' + fileID).children('.progress-bar').css('width', (percentComplete * (2 / 5)) + 60 + '%');
$('#progress-' + fileID).children('.progress-bar').html(percentComplete + '% Uploaded');
}
}

function uploadComplete(filename, evt) {
function uploadComplete(fileID, key, evt) {
obj = JSON.parse(evt.target.responseText);
var name = obj.result.name;
var fullName = obj.result.url;
var shortName = filename.hashCode();
$('.progress-' + shortName).children('.progress-bar').css('width', '100%');
$('.progress-' + shortName).children('.progress-bar').html('Complete');
$('.links-' + shortName).append(' \
<div class="col-sm-6"> \
' + filename + ' \
</div> \
<div class="col-sm-3"> \
<a href="' + fullName + '" target="_blank" class="alert-link">' + fullName + '</a> \
</div> \
<div class="col-sm-3"> \
<button type="button" class="btn btn-default btn-xs generate-delete-link-' + name + '" id="' + name + '">Generate Deletion URL</button> \
var fullName = decodeURIComponent(obj.result.url);
var keyVar = decodeURIComponent(obj.result.keyVar);
fullName = fullName.replace(keyVar, key);
$('#progress-' + fileID).children('.progress-bar').css('width', '100%');
$('#progress-' + fileID).children('.progress-bar').html('Complete');
$('#upload-link-' + fileID).html('<p><a href="' + fullName + '" target="_blank" class="alert-link">' + fullName + '</a></p>');
$('#link-' + fileID).append(' \
<div class="panel-footer"> \
<div class="row"> \
<div class="col-sm-4 text-center"> \
<button type="button" class="btn btn-default btn-sm" id="save-key-link-' + fileID + '">Save Key On Server</button> \
</div> \
<div class="col-sm-4 text-center"> \
<button type="button" class="btn btn-default btn-sm" id="generate-delete-link-' + fileID + '">Generate Deletion URL</button> \
</div> \
<div class="col-sm-4 text-center"> \
<button type="button" class="btn btn-default btn-sm" id="remove-link-' + fileID + '">Remove</button> \
</div> \
</div> \
</div> \
');
linkUploadDelete('.generate-delete-link-' + name + '');
linkSaveKey('#save-key-link-' + fileID + '', name, key, fileID);
linkUploadDelete('#generate-delete-link-' + fileID + '', name);
linkRemove('#remove-link-' + fileID + '', fileID);
}

function uploadFailed(evt) {
alert("There was an error attempting to upload the file.");
function uploadFailed(fileID, evt) {
$('#progress-' + fileID).children('.progress-bar').css('width', '100%');
$("#progress-" + fileID).children('.progress-bar').removeClass('progress-bar-success');
$("#progress-" + fileID).children('.progress-bar').addClass('progress-bar-danger');
$('#progress-' + fileID).children('.progress-bar').html('Upload Failed');
}

function uploadCanceled(evt) {
alert("The upload has been canceled by the user or the browser dropped the connection.");
function uploadCanceled(fileID, evt) {
$('#progress-' + fileID).children('.progress-bar').css('width', '100%');
$("#progress-" + fileID).children('.progress-bar').removeClass('progress-bar-success');
$("#progress-" + fileID).children('.progress-bar').addClass('progress-bar-warning');
$('#progress-' + fileID).children('.progress-bar').html('Upload Canceled');
}

+ 13
- 4
Teknik/Areas/Upload/UploadAreaRegistration.cs View File

@@ -29,10 +29,17 @@ namespace Teknik.Areas.Upload
new { controller = "Upload", action = "Download", url = string.Empty },
new[] { typeof(Controllers.UploadController).Namespace }
);
context.MapSubdomainRoute(
"Upload.Download.Key",
"dev",
"Upload/{file}/{key}",
new { controller = "Upload", action = "Download", url = string.Empty },
new[] { typeof(Controllers.UploadController).Namespace }
);
context.MapSubdomainRoute(
"Upload.Delete",
"dev",
"Upload/{url}/{deleteKey}",
"Upload/{file}/{key}",
new { controller = "Upload", action = "Delete", url = string.Empty, deleteKey = string.Empty },
new[] { typeof(Controllers.UploadController).Namespace }
);
@@ -105,13 +112,15 @@ namespace Teknik.Areas.Upload
"~/Scripts/Dropzone/dropzone.js",
"~/Areas/Upload/Scripts/Upload.js",
"~/Scripts/bootbox/bootbox.min.js",
"~/Scripts/Crypto-js/aes.js",
"~/Scripts/Crypto-js/lib-typedarray.js"));
"~/Scripts/Crypto-js/aes.js"));
BundleTable.Bundles.Add(new ScriptBundle("~/bundles/cryptoWorker").Include(
"~/Areas/Upload/Scripts/EncryptionWorker.js"));
BundleTable.Bundles.Add(new ScriptBundle("~/bundles/crypto").Include(
"~/Scripts/Crypto-js/aes.js",
"~/Scripts/Crypto-js/lib-typedarray.js"));
"~/Scripts/Crypto-js/enc-base64.js",
"~/Scripts/Crypto-js/mode-ctr.js",
"~/Scripts/Crypto-js/lib-typedarrays.js",
"~/Scripts/Crypto-js/pad-nopadding.js"));

// Register Style Bundles
BundleTable.Bundles.Add(new StyleBundle("~/Content/upload").Include(

+ 2
- 3
Teknik/Areas/Upload/Views/Upload/Index.cshtml View File

@@ -4,9 +4,10 @@
var encScriptSrc = '@Scripts.Url("~/bundles/cryptoWorker")';
var aesScriptSrc = '@Scripts.Url("~/bundles/crypto")';
var generateDeleteKeyURL = '@Url.SubRouteUrl("upload", "Upload.Action", new { action= "GenerateDeleteKey" })';
var saveKeyToServerURL = '@Url.SubRouteUrl("upload", "Upload.Action", new { action= "SaveFileKey" })';
var uploadFileURL = '@Url.SubRouteUrl("upload", "Upload.Action", new { action = "Upload" })';
var uploadURL = '@Url.SubRouteUrl("upload", "Upload.Download")';
var maxUploadSize = @(Model.Config.UploadConfig.MaxUploadSize / 100000);
var chunkSize = @(Model.Config.UploadConfig.ChunkSize);
</script>

@Styles.Render("~/Content/upload")
@@ -15,8 +16,6 @@
<div class="row text-center">
<form action="@Url.SubRouteUrl("upload", "Upload.Action", new { action = "Upload" })" class="dropzone" id="TeknikUpload" name="TeknikUpload" enctype="multipart/form-data">
@Html.AntiForgeryToken()
<input name="key" id="key" type="hidden" />
<input name="iv" id="iv" type="hidden" />
<div class="dz-message text-center" id="upload_message">
<div class="row">
<div class="col-sm-12">

+ 3
- 0
Teknik/Configuration/UploadConfig.cs View File

@@ -15,6 +15,8 @@ namespace Teknik.Configuration
public string FileExtension { get; set; }
public int UrlLength { get; set; }
public bool IncludeExtension { get; set; }
// The size of the chunk that the file will be encrypted/decrypted in (bytes)
public int ChunkSize { get; set; }

public UploadConfig()
{
@@ -28,6 +30,7 @@ namespace Teknik.Configuration
FileExtension = "enc";
UrlLength = 6;
IncludeExtension = true;
ChunkSize = 1024;
}
}
}

+ 109
- 0
Teknik/Scripts/Crypto-js/enc-base64.js View File

@@ -0,0 +1,109 @@
/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
(function () {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var WordArray = C_lib.WordArray;
var C_enc = C.enc;

/**
* Base64 encoding strategy.
*/
var Base64 = C_enc.Base64 = {
/**
* Converts a word array to a Base64 string.
*
* @param {WordArray} wordArray The word array.
*
* @return {string} The Base64 string.
*
* @static
*
* @example
*
* var base64String = CryptoJS.enc.Base64.stringify(wordArray);
*/
stringify: function (wordArray) {
// Shortcuts
var words = wordArray.words;
var sigBytes = wordArray.sigBytes;
var map = this._map;

// Clamp excess bits
wordArray.clamp();

// Convert
var base64Chars = [];
for (var i = 0; i < sigBytes; i += 3) {
var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff;
var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff;

var triplet = (byte1 << 16) | (byte2 << 8) | byte3;

for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) {
base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f));
}
}

// Add padding
var paddingChar = map.charAt(64);
if (paddingChar) {
while (base64Chars.length % 4) {
base64Chars.push(paddingChar);
}
}

return base64Chars.join('');
},

/**
* Converts a Base64 string to a word array.
*
* @param {string} base64Str The Base64 string.
*
* @return {WordArray} The word array.
*
* @static
*
* @example
*
* var wordArray = CryptoJS.enc.Base64.parse(base64String);
*/
parse: function (base64Str) {
// Shortcuts
var base64StrLength = base64Str.length;
var map = this._map;

// Ignore padding
var paddingChar = map.charAt(64);
if (paddingChar) {
var paddingIndex = base64Str.indexOf(paddingChar);
if (paddingIndex != -1) {
base64StrLength = paddingIndex;
}
}

// Convert
var words = [];
var nBytes = 0;
for (var i = 0; i < base64StrLength; i++) {
if (i % 4) {
var bits1 = map.indexOf(base64Str.charAt(i - 1)) << ((i % 4) * 2);
var bits2 = map.indexOf(base64Str.charAt(i)) >>> (6 - (i % 4) * 2);
words[nBytes >>> 2] |= (bits1 | bits2) << (24 - (nBytes % 4) * 8);
nBytes++;
}
}

return WordArray.create(words, nBytes);
},

_map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
};
}());

+ 135
- 0
Teknik/Scripts/Crypto-js/enc-utf16.js View File

@@ -0,0 +1,135 @@
/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
(function () {
// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var WordArray = C_lib.WordArray;
var C_enc = C.enc;

/**
* UTF-16 BE encoding strategy.
*/
var Utf16BE = C_enc.Utf16 = C_enc.Utf16BE = {
/**
* Converts a word array to a UTF-16 BE string.
*
* @param {WordArray} wordArray The word array.
*
* @return {string} The UTF-16 BE string.
*
* @static
*
* @example
*
* var utf16String = CryptoJS.enc.Utf16.stringify(wordArray);
*/
stringify: function (wordArray) {
// Shortcuts
var words = wordArray.words;
var sigBytes = wordArray.sigBytes;

// Convert
var utf16Chars = [];
for (var i = 0; i < sigBytes; i += 2) {
var codePoint = (words[i >>> 2] >>> (16 - (i % 4) * 8)) & 0xffff;
utf16Chars.push(String.fromCharCode(codePoint));
}

return utf16Chars.join('');
},

/**
* Converts a UTF-16 BE string to a word array.
*
* @param {string} utf16Str The UTF-16 BE string.
*
* @return {WordArray} The word array.
*
* @static
*
* @example
*
* var wordArray = CryptoJS.enc.Utf16.parse(utf16String);
*/
parse: function (utf16Str) {
// Shortcut
var utf16StrLength = utf16Str.length;

// Convert
var words = [];
for (var i = 0; i < utf16StrLength; i++) {
words[i >>> 1] |= utf16Str.charCodeAt(i) << (16 - (i % 2) * 16);
}

return WordArray.create(words, utf16StrLength * 2);
}
};

/**
* UTF-16 LE encoding strategy.
*/
C_enc.Utf16LE = {
/**
* Converts a word array to a UTF-16 LE string.
*
* @param {WordArray} wordArray The word array.
*
* @return {string} The UTF-16 LE string.
*
* @static
*
* @example
*
* var utf16Str = CryptoJS.enc.Utf16LE.stringify(wordArray);
*/
stringify: function (wordArray) {
// Shortcuts
var words = wordArray.words;
var sigBytes = wordArray.sigBytes;

// Convert
var utf16Chars = [];
for (var i = 0; i < sigBytes; i += 2) {
var codePoint = swapEndian((words[i >>> 2] >>> (16 - (i % 4) * 8)) & 0xffff);
utf16Chars.push(String.fromCharCode(codePoint));
}

return utf16Chars.join('');
},

/**
* Converts a UTF-16 LE string to a word array.
*
* @param {string} utf16Str The UTF-16 LE string.
*
* @return {WordArray} The word array.
*
* @static
*
* @example
*
* var wordArray = CryptoJS.enc.Utf16LE.parse(utf16Str);
*/
parse: function (utf16Str) {
// Shortcut
var utf16StrLength = utf16Str.length;

// Convert
var words = [];
for (var i = 0; i < utf16StrLength; i++) {
words[i >>> 1] |= swapEndian(utf16Str.charCodeAt(i) << (16 - (i % 2) * 16));
}

return WordArray.create(words, utf16StrLength * 2);
}
};

function swapEndian(word) {
return ((word << 8) & 0xff00ff00) | ((word >>> 8) & 0x00ff00ff);
}
}());

+ 44
- 0
Teknik/Scripts/Crypto-js/mode-ctr.js View File

@@ -0,0 +1,44 @@
/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
/**
* Counter block mode.
*/
CryptoJS.mode.CTR = (function () {
var CTR = CryptoJS.lib.BlockCipherMode.extend();

var Encryptor = CTR.Encryptor = CTR.extend({
processBlock: function (words, offset) {
// Shortcuts
var cipher = this._cipher
var blockSize = cipher.blockSize;
var iv = this._iv;
var counter = this._counter;

// Generate keystream
if (iv) {
counter = this._counter = iv.slice(0);

// Remove IV for subsequent blocks
this._iv = undefined;
}
var keystream = counter.slice(0);
cipher.encryptBlock(keystream, 0);

// Increment counter
counter[blockSize - 1] = (counter[blockSize - 1] + 1) | 0

// Encrypt
for (var i = 0; i < blockSize; i++) {
words[offset + i] ^= keystream[i];
}
}
});

CTR.Decryptor = Encryptor;

return CTR;
}());

+ 16
- 0
Teknik/Scripts/Crypto-js/pad-nopadding.js View File

@@ -0,0 +1,16 @@
/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
/**
* A noop padding strategy.
*/
CryptoJS.pad.NoPadding = {
pad: function () {
},

unpad: function () {
}
};

BIN
Teknik/Scripts/_references.js View File


+ 4
- 0
Teknik/Teknik.csproj View File

@@ -289,7 +289,11 @@
<Content Include="Scripts\bootstrap.js" />
<Content Include="Scripts\bootstrap.min.js" />
<Content Include="Scripts\common.js" />
<Content Include="Scripts\Crypto-js\enc-base64.js" />
<Content Include="Scripts\Crypto-js\enc-utf16.js" />
<Content Include="Scripts\Crypto-js\lib-typedarrays.js" />
<Content Include="Scripts\Crypto-js\mode-ctr.js" />
<Content Include="Scripts\Crypto-js\pad-nopadding.js" />
<Content Include="Scripts\Dropzone\dropzone.js" />
<Content Include="Scripts\jquery-2.1.4.js" />
<Content Include="Scripts\jquery-2.1.4.min.js" />

Loading…
Cancel
Save