Browse Source

Fixed encrypted data not being sent to server.

Still having issues with the encryption and subsequent conversions.
master
Teknikode 7 years ago
parent
commit
59e213690e
  1. 16
      Teknik/Areas/Upload/Controllers/UploadController.cs
  2. 20
      Teknik/Areas/Upload/Models/FileModel.cs
  3. 51
      Teknik/Areas/Upload/Scripts/EncryptionWorker.js
  4. 98
      Teknik/Areas/Upload/Scripts/Upload.js
  5. 6
      Teknik/Areas/Upload/UploadAreaRegistration.cs
  6. 15
      Teknik/Areas/Upload/Uploader.cs
  7. 0
      Teknik/Scripts/Crypto-js/aes.js
  8. 62
      Teknik/Scripts/Crypto-js/lib-typedarrays.js
  9. BIN
      Teknik/Scripts/_references.js
  10. 4
      Teknik/Teknik.csproj

16
Teknik/Areas/Upload/Controllers/UploadController.cs

@ -3,6 +3,7 @@ using System.Collections.Generic; @@ -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 @@ -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
Teknik/Areas/Upload/Models/FileModel.cs

@ -0,0 +1,20 @@ @@ -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; }
}
}

51
Teknik/Areas/Upload/Scripts/EncryptionWorker.js

@ -4,12 +4,21 @@ @@ -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 @@ @@ -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;
}

98
Teknik/Areas/Upload/Scripts/Upload.js

@ -34,40 +34,21 @@ Dropzone.options.TeknikUpload = { @@ -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 = { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -190,5 +194,5 @@ function encryptFile(file, callback) {
// Start async read
var blob = file.slice(0, file.size);
reader.readAsDataURL(blob);
}
reader.readAsArrayBuffer(blob);
}

6
Teknik/Areas/Upload/UploadAreaRegistration.cs

@ -105,11 +105,13 @@ namespace Teknik.Areas.Upload @@ -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(

15
Teknik/Areas/Upload/Uploader.cs

@ -2,6 +2,7 @@ @@ -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 @@ -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 @@ -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 @@ -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;

0
Teknik/Areas/Upload/Scripts/aes.js → Teknik/Scripts/Crypto-js/aes.js

62
Teknik/Scripts/Crypto-js/lib-typedarrays.js

@ -0,0 +1,62 @@ @@ -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

Binary file not shown.

4
Teknik/Teknik.csproj

@ -166,6 +166,7 @@ @@ -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 @@ @@ -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 @@ @@ -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