Browse Source

Fixed encrypted data not being sent to server.

Still having issues with the encryption and subsequent conversions.
tags/2.0.3
Teknikode 4 years ago
parent
commit
59e213690e

+ 3
- 13
Teknik/Areas/Upload/Controllers/UploadController.cs View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Teknik.Areas.Upload.Models;
using Teknik.Areas.Upload.ViewModels;
using Teknik.Controllers;

@@ -28,20 +29,9 @@ namespace Teknik.Areas.Upload.Controllers
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Upload(string iv)
public ActionResult Upload(string fileType, string iv, HttpPostedFileWrapper data)
{
Models.Upload upload = null;
foreach (string fileName in Request.Files)
{
HttpPostedFileBase file = Request.Files[fileName];
//Save file content goes here
string fName = file.FileName;
if (file != null && file.ContentLength > 0)
{
upload = Uploader.SaveFile(file, iv);
break;
}
}
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");

+ 20
- 0
Teknik/Areas/Upload/Models/FileModel.cs View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Teknik.Areas.Upload.Models
{
public class FileModel
{
public string FileName { get; set; }

public string FileType { get; set; }

public string IV { get; set; }

public string ContentAsBase64String { get; set; }
}

}

+ 47
- 4
Teknik/Areas/Upload/Scripts/EncryptionWorker.js View File

@@ -4,12 +4,21 @@

switch (data.cmd) {
case 'encrypt':
var wordArray = CryptoJS.lib.WordArray.create(new Uint8Array(data.file))

//var dataStr = ab2str(data.file);

// encrypt the passed in file data
var encrypted = CryptoJS.AES.encrypt(data.file, data.key, { iv: data.iv });
var encrypted = CryptoJS.AES.encrypt(wordArray, data.key, { iv: data.iv });
var encByteArray = wordToByteArray(encrypted);

var cipherText = encrypted.toString();
// patch it all back together for the trip home
var objData =
{
encrypted: encByteArray.buffer
};

self.postMessage(cipherText);
self.postMessage(objData, [objData.encrypted]);
break;
case 'decrypt':
// decrypt the passed in file data
@@ -20,4 +29,38 @@
self.postMessage(fileText);
break;
}
}, false);
}, 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 _base64ToArrayBuffer(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;
}

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 Uint8Array(buf);
for (var i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}

+ 51
- 47
Teknik/Areas/Upload/Scripts/Upload.js View File

@@ -34,40 +34,21 @@ Dropzone.options.TeknikUpload = {
addRemoveLinks: true,
autoProcessQueue: false,
clickable: true,
accept: function (file, done) {
encryptFile(file, done);
},
init: function() {
this.on("sending", function (file, xhr, formData) {
var data = new FormData();
data.append('file-content', file.data);
data.append('file-iv', file.iv);
formData = data;
});
this.on("success", function (file, response) {
obj = JSON.parse(response);
var name = obj.result.name;
var fullName = obj.result.url;
this.on("addedfile", function (file, responseText) {
// Create the UI element for the new item
var short_name = file.name.split(".")[0].hashCode();
$("#upload-links").css('display', 'inline', 'important');
$("#upload-links").prepend(' \
<div class="row link_'+short_name+'"> \
<div class="col-sm-6"> \
'+file.name+' \
</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-'+short_name+'" id="'+name+'">Generate Deletion URL</button> \
</div> \
<div class="col-sm-12 text-center"> \
'+file.name+' \
</div> \
<div class="progress col-sm-12"> \
<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> \
</div> \
');
linkUploadDelete('.generate-delete-link-'+short_name+'');
});
this.on("addedfile", function (file, responseText) {

// We will be handling encryption and uploading here

// Encrypt the file
encryptFile(file, uploadFile);
@@ -97,18 +78,21 @@ Dropzone.options.TeknikUpload = {
}
};

function uploadFile(data, key, iv)
function uploadFile(data, key, iv, filetype, filename)
{
$("#key").val(key);
$("#iv").val(iv);
var blob = new Blob([data]);
// Now we need to upload the file
var fd = new FormData();
fd.append('data', data);
fd.append('fileType', filetype);
fd.append('iv', iv);
fd.append('content-type', document.getElementById('file').files[0].type);
fd.append('data', blob);
fd.append('__RequestVerificationToken', $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val());

var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", uploadProgress, false);
xhr.addEventListener("load", uploadComplete, false);
xhr.addEventListener("load", uploadComplete.bind(null, filename), false);
xhr.addEventListener("error", uploadFailed, false);
xhr.addEventListener("abort", uploadCanceled, false);
xhr.open("POST", uploadFileURL);
@@ -119,16 +103,33 @@ function uploadProgress(evt) {
if (evt.lengthComputable) {
var percentComplete = Math.round(evt.loaded * 100 / evt.total);
$(".progress").children('.progress-bar').css('width', (percentComplete * (3 / 5)) + 40 + '%');
$(".progress").children('.progress-bar').html(progress.toFixed(2) + '% Uploaded');
$(".progress").children('.progress-bar').html(percentComplete + '% Uploaded');
}
else {
document.getElementById('progressNumber').innerHTML = 'unable to compute';
}
}

function uploadComplete(evt) {
/* This event is raised when the server send back a response */
alert(evt.target.responseText);
function uploadComplete(filename, evt) {
obj = JSON.parse(evt.target.responseText);
var name = obj.result.name;
var fullName = obj.result.url;
var short_name = filename.split(".")[0].hashCode();
$("#upload-links").css('display', 'inline', 'important');
$("#upload-links").prepend(' \
<div class="row link_'+ short_name + '"> \
<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> \
</div> \
</div> \
');
linkUploadDelete('.generate-delete-link-' + name + '');
}

function uploadFailed(evt) {
@@ -139,9 +140,11 @@ function uploadCanceled(evt) {
alert("The upload has been canceled by the user or the browser dropped the connection.");
}


// 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;

// Start the file reader
var reader = new FileReader();

@@ -163,19 +166,20 @@ function encryptFile(file, callback) {
worker.addEventListener('message', function (e) {
if (callback != null) {
// Finish
callback(e.data, keyStr, ivStr);
callback(e.data.encrypted, keyStr, ivStr, filetype, filename);
}
});

// Execute worker with data
worker.postMessage({
cmd: 'encrypt',
script: aesScriptSrc,
key: key,
iv: iv,
file: e.target.result,
chunkSize: 1024
});
var objData =
{
cmd: 'encrypt',
script: aesScriptSrc,
key: key,
iv: iv,
file: e.target.result
};
worker.postMessage(objData, [objData.file]);
};
})(callback);

@@ -190,5 +194,5 @@ function encryptFile(file, callback) {

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

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

@@ -105,11 +105,13 @@ namespace Teknik.Areas.Upload
"~/Scripts/Dropzone/dropzone.js",
"~/Areas/Upload/Scripts/Upload.js",
"~/Scripts/bootbox/bootbox.min.js",
"~/Areas/Upload/Scripts/aes.js"));
"~/Scripts/Crypto-js/aes.js",
"~/Scripts/Crypto-js/lib-typedarray.js"));
BundleTable.Bundles.Add(new ScriptBundle("~/bundles/cryptoWorker").Include(
"~/Areas/Upload/Scripts/EncryptionWorker.js"));
BundleTable.Bundles.Add(new ScriptBundle("~/bundles/crypto").Include(
"~/Areas/Upload/Scripts/aes.js"));
"~/Scripts/Crypto-js/aes.js",
"~/Scripts/Crypto-js/lib-typedarray.js"));

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

+ 8
- 7
Teknik/Areas/Upload/Uploader.cs View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using Teknik.Configuration;
using Teknik.Models;

@@ -9,17 +10,17 @@ namespace Teknik.Areas.Upload
{
public static class Uploader
{
public static Models.Upload SaveFile(HttpPostedFileBase file)
public static Models.Upload SaveFile(HttpPostedFileWrapper file, string contentType)
{
return SaveFile(file, null, null);
return SaveFile(file, contentType, null, null);
}

public static Models.Upload SaveFile(HttpPostedFileBase file, string iv)
public static Models.Upload SaveFile(HttpPostedFileWrapper file, string contentType, string iv)
{
return SaveFile(file, iv, null);
return SaveFile(file, contentType, iv, null);
}

public static Models.Upload SaveFile(HttpPostedFileBase file, string iv, string key)
public static Models.Upload SaveFile(HttpPostedFileWrapper file, string contentType, string iv, string key)
{
Config config = Config.Load();
TeknikEntities db = new TeknikEntities();
@@ -31,7 +32,7 @@ namespace Teknik.Areas.Upload
file.SaveAs(fileName);

// Generate a unique url
string extension = (config.UploadConfig.IncludeExtension) ? Utility.GetDefaultExtension(file.ContentType) : string.Empty;
string extension = (config.UploadConfig.IncludeExtension) ? Utility.GetDefaultExtension(contentType) : string.Empty;
string url = Utility.RandomString(config.UploadConfig.UrlLength) + extension;
while (db.Uploads.Where(u => u.Url == url).FirstOrDefault() != null)
{
@@ -44,7 +45,7 @@ namespace Teknik.Areas.Upload
upload.Url = url;
upload.FileName = fileName;
upload.ContentLength = file.ContentLength;
upload.ContentType = file.ContentType;
upload.ContentType = contentType;
upload.Key = key;
upload.IV = iv;


Teknik/Areas/Upload/Scripts/aes.js → Teknik/Scripts/Crypto-js/aes.js View File


+ 62
- 0
Teknik/Scripts/Crypto-js/lib-typedarrays.js View File

@@ -0,0 +1,62 @@
/*
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 () {
// Check if typed arrays are supported
if (typeof ArrayBuffer != 'function') {
return;
}

// Shortcuts
var C = CryptoJS;
var C_lib = C.lib;
var WordArray = C_lib.WordArray;

// Reference original init
var superInit = WordArray.init;

// Augment WordArray.init to handle typed arrays
var subInit = WordArray.init = function (typedArray) {
// Convert buffers to uint8
if (typedArray instanceof ArrayBuffer) {
typedArray = new Uint8Array(typedArray);
}

// Convert other array views to uint8
if (
typedArray instanceof Int8Array ||
typedArray instanceof Uint8ClampedArray ||
typedArray instanceof Int16Array ||
typedArray instanceof Uint16Array ||
typedArray instanceof Int32Array ||
typedArray instanceof Uint32Array ||
typedArray instanceof Float32Array ||
typedArray instanceof Float64Array
) {
typedArray = new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength);
}

// Handle Uint8Array
if (typedArray instanceof Uint8Array) {
// Shortcut
var typedArrayByteLength = typedArray.byteLength;

// Extract bytes
var words = [];
for (var i = 0; i < typedArrayByteLength; i++) {
words[i >>> 2] |= typedArray[i] << (24 - (i % 4) * 8);
}

// Initialize this word array
superInit.call(this, words, typedArrayByteLength);
} else {
// Else call normal init
superInit.apply(this, arguments);
}
};

subInit.prototype = WordArray;
}());

BIN
Teknik/Scripts/_references.js View File


+ 3
- 1
Teknik/Teknik.csproj View File

@@ -166,6 +166,7 @@
<Compile Include="Areas\Profile\ProfileAreaRegistration.cs" />
<Compile Include="Areas\Profile\ViewModels\ProfileViewModel.cs" />
<Compile Include="Areas\Upload\Controllers\UploadController.cs" />
<Compile Include="Areas\Upload\Models\FileModel.cs" />
<Compile Include="Areas\Upload\Models\Upload.cs" />
<Compile Include="Areas\Upload\UploadAreaRegistration.cs" />
<Compile Include="Areas\Upload\Uploader.cs" />
@@ -208,7 +209,7 @@
<Content Include="Areas\Home\Content\Home.css" />
<Content Include="Areas\Home\Scripts\Home.js" />
<Content Include="Areas\Profile\Scripts\Profile.js" />
<Content Include="Areas\Upload\Scripts\aes.js" />
<Content Include="Scripts\Crypto-js\aes.js" />
<Content Include="Areas\Upload\Scripts\EncryptionWorker.js" />
<Content Include="Areas\Upload\Scripts\Upload.js" />
<Content Include="Content\bootstrap-markdown.min.css" />
@@ -288,6 +289,7 @@
<Content Include="Scripts\bootstrap.js" />
<Content Include="Scripts\bootstrap.min.js" />
<Content Include="Scripts\common.js" />
<Content Include="Scripts\Crypto-js\lib-typedarrays.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