mirror of
https://git.teknik.io/Teknikode/Teknik.git
synced 2023-08-02 14:16:22 +02:00
Fixed encrypted data not being sent to server.
Still having issues with the encryption and subsequent conversions.
This commit is contained in:
parent
c1f2707c51
commit
59e213690e
@ -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
Teknik/Areas/Upload/Models/FileModel.cs
Normal file
20
Teknik/Areas/Upload/Models/FileModel.cs
Normal 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; }
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
|
||||
|
62
Teknik/Scripts/Crypto-js/lib-typedarrays.js
Normal file
62
Teknik/Scripts/Crypto-js/lib-typedarrays.js
Normal 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;
|
||||
}());
|
Binary file not shown.
@ -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…
Reference in New Issue
Block a user