У sendfilesencrypted.com мы клапоцімся пра бяспеку вашых файлаў і хочам, каб ваш досвед абмену файламі ў Інтэрнэце быў у бяспецы.
Менавіта таму мы ўкаранілі бясплатную функцыю шыфравання файлаў.
Усе файлы, якімі вы абагульваеце ў Sendfilesencrypted.com, шыфруюцца перад загрузкай на нашы серверы, што дадае ўзровень бяспекі кожнаму файлу, які вы абагульваеце, прадухіляючы доступ да іх любым асобам або пагрозам.
Такім жа чынам усе вашы файлы расшыфроўваюцца ў вашым браўзеры з дапамогай пароля, які вы ўказалі пры іх загрузцы, гэта гарантуе, што калі зламыснік атрымае доступ да вашых файлаў, яны будуць цалкам зашыфраваныя.
Вось як мы шыфруем вашы файлы перад загрузкай і захаваннем на нашых серверах.
Код разбівае вашы файлы на некалькі невялікіх файлаў, кожны фрагмент зашыфраваны з дапамогай пароля, які вы выкарыстоўвалі для іх загрузкі, і унікальнага кода для кожнай групы файлаў, што дае яшчэ большую бяспеку вашым файлам. Пасля гэтага працэсу кожны кавалак зашыфраванага файла загружаецца і захоўваецца на нашым серверы. Гэта гарантуе, што нават мы, распрацоўшчыкі, не зможам атрымаць доступ да вашых файлаў.
/* | |
In this code you will find how I encrypt files (using CryptoJS) before uploading to the server, this is the steps I follow: | |
1. Calculate the size of all the files I want to upload, I will use this number to stop my recursive function | |
2. I slice every file in chunks of max 5MB, if the final value of chunkEnd is equals to the current file size then I jump to the next file passing the new index as indexFile + 1 | |
3. I read the file slice using FileReader, then I start the encryption of the arrayBuffer content, passing the password the user provide. | |
4. I create a new Blob using the encrypted string and pass it to my custom Ajax function to upload it to the server, once the encrypted chunk is stored I call the recursive function again. | |
*/ | |
var chunkStart = 0; | |
var chunkEnd = 0; | |
var chunkCounter = 0; | |
var files = $(this)[0].files; | |
var totalSize = files.map( | |
function (item) { | |
return item.size | |
} | |
).reduce( | |
function (a, b) { | |
return a + b | |
} | |
); | |
uploadChunk(totalSize, 0, chunkStart, chunkEnd, chunkCounter); | |
// I will use this function to encrypt and upload every file slice | |
function uploadChunk(totalSize, fileIndex, chunkStart, chunkEnd, chunkCounter) { | |
if (fileIndex >= files.length) { | |
return; | |
} | |
var currentFile = files[fileIndex]; | |
var chunkSize = 6000000; | |
var fileSize = currentFile.size; | |
if (chunkEnd >= fileSize) { | |
return uploadChunk(totalSize, fileIndex + 1, 0, 0, 0); | |
} | |
chunkEnd = Math.min(chunkStart + chunkSize, fileSize); | |
var reader = new FileReader(); | |
reader.onload = function () { | |
var secret_key = CryptoJS.PBKDF2( | |
password, | |
CryptoJS.enc.Hex.parse(`${file_key}`), | |
{ | |
keySize: 512 / 32, | |
iterations: 20000 | |
} | |
); | |
var ivString = generateRandom(chars=120); | |
var iv = CryptoJS.enc.Hex.parse(`${ivString}`); | |
var wordArray = CryptoJS.lib.WordArray.create(reader.result); | |
var encrypted = CryptoJS.AES.encrypt(wordArray, secret_key, { | |
iv: iv | |
}).toString(); | |
var encryptedFile = new Blob([`${ivString}:${encrypted}`]); | |
// PromiseRequestFunction is a custom function I use to make ajax requests, I'm passing the blob files as parameter | |
var p = PromiseRequestFunction( | |
... | |
[encryptedFile] | |
); | |
p.then( | |
function () { | |
chunkStart += chunkSize; | |
chunkCounter += 1; | |
uploadChunk(totalSize, fileIndex, chunkStart, chunkEnd, chunkCounter); | |
}, | |
function () { | |
} | |
); | |
} | |
reader.readAsArrayBuffer(currentFile.slice(chunkStart, chunkEnd)); | |
} |
Зараз я пакажу вам, як мы расшыфроўваем вашыя файлы.
Памятайце, што кожны арыгінальны файл ператвараўся ў мноства зашыфраваных файлаў, якія захоўваюцца на нашым серверы. Кожны фрагмент загружаецца ў браўзер, а затым уведзены вамі пароль і унікальны код блока файла выкарыстоўваюцца для расшыфроўкі кожнага фрагмента, які будзе злучаны з многімі іншымі расшыфраванымі часткамі вашага арыгінальнага файла, а затым стварыць і загрузіць арыгінальны файл.
/* | |
In this code you will find how I decrypt blob files (using CryptoJS) | |
1. I need the filename and get the blobURLs (for this example I will be using a hardcoded blobURLs, but in my case I'm getting that info from a previous ajax call) | |
// I start the recursive function. Note the the first paramater will contains the decrypted blobs. | |
2. I check if the index is greated than my blobURLs length, so I can know when to stop the recursive function and create the download link. | |
3. I get the blob file using XMLHttpRequest and passing the blobURL. | |
4. I read the blob content using FileReader, note that I'm using reader.readAsText because I'm getting a base64 text. | |
5. I decrypt the blob text content, using the password passed by the user. | |
6. I parse the wordArray and create a new Blob with the result that is stored in the blobs array and I call the recursive function again. | |
*/ | |
var filename = 'my_awesome_picture.png'; | |
var blobURLS = ['https://sfo.to/blob_1', 'https://sfo.to/blob_2', ...] | |
getBlob([], blobURLs, 0, filename); | |
function getBlob(blobs, urls, index, filename) { | |
if (index >= urls.length) { | |
var blob = new Blob(blobs); | |
var url = window.URL.createObjectURL(blob); | |
var a = document.createElement('a'); | |
a.href = url; | |
a.download = filename; | |
a.click(); | |
} else { | |
var xhr = new XMLHttpRequest(); | |
xhr.onreadystatechange = function () { | |
if (this.readyState === 4 && this.status === 200) { | |
var reader = new FileReader(); | |
reader.onload = function () { | |
var secret_key = secret_key = CryptoJS.PBKDF2( | |
password, | |
CryptoJS.enc.Hex.parse(`${file_key}`), | |
{ | |
keySize: 512 / 32, | |
iterations: 20000 | |
} | |
); | |
var encryptedParts = reader.result.split(':'); | |
var iv = CryptoJS.enc.Hex.parse(`${encryptedParts[0]}`); | |
encryptedParts.shift(); | |
var decrypted = CryptoJS.AES.decrypt(encryptedParts.join(), secret_key, { | |
iv: iv | |
}); | |
var typedArray = convertWordArrayToUint8Array(decrypted); | |
blobs.push(new Blob([typedArray])); | |
getBlob(blobs, urls, index + 1, filename); | |
}; | |
reader.readAsText(this.response); | |
} | |
} | |
xhr.open('POST', `${urls[index]}`); | |
xhr.responseType = 'blob'; | |
xhr.send(); | |
} | |
} | |
function convertWordArrayToUint8Array(wordArray) { | |
var arrayOfWords = wordArray.hasOwnProperty("words") ? wordArray.words : []; | |
var length = wordArray.hasOwnProperty("sigBytes") ? wordArray.sigBytes : arrayOfWords.length * 4; | |
var uInt8Array = new Uint8Array(length), index = 0, word, i; | |
for (i = 0; i < length; i++) { | |
word = arrayOfWords[i]; | |
uInt8Array[index++] = word >> 24; | |
uInt8Array[index++] = (word >> 16) & 0xff; | |
uInt8Array[index++] = (word >> 8) & 0xff; | |
uInt8Array[index++] = word & 0xff; | |
} | |
return uInt8Array; | |
} |
Падабаецца тое, што вы прачыталі? Адпраўце файлы зашыфраваныя зараз