Шифрование картинок с помощью CryptoJS?
Стоит задача написать программу на JS (клиент онли), которая шифрует содержимое произвольных файлов (их может быть очень много и большого размера) с помощью введенного юзером пароля по стандартному криптостойкому алгоритму. После исследования требований выбрал алгоритм RC4 и его реализацию из библиотеки CryptoJS.
Сейчас имею такой код: https://jsfiddle.net/alexander_js_developer/nuevwrp0/.
Вводите пароль, хеш пароля - это ключ при шифровке и расшифровке файла.
Текстовые файлы обрабатывает отлично (.txt, .js). А вот, например, картинки ломает нещадно. Я так понимаю, мне нужно конвертировать изображения в поток битов и шифровать уже его? Или есть другое, более правильное/быстрое решение?
Спасибо!
Ответы (1 шт):
Для работы с base64 понадобятся 2 функции
const fileToBase64 = file => new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
const base64ToFile = (url, filename, mimeType) => {
return (fetch(url)
.then(function(res){return res.arrayBuffer();})
.then(function(buf){return new File([buf], filename,{type:mimeType});})
);
}
( ссылки на исходный код fileToBase64, base64ToFile )
Существующие функции нужно будет подправить следующим образом, внедрив в них шаг кодирования и декодирования base64:
encryptNode.addEventListener('click', () => {
if (!passNode.value) return alert('Password input is empty! Aborting.');
const pass = CryptoJS.SHA3(passNode.value);
pickAFile(false).then(async(file) => {
const data = await fileToBase64(file)
const encrypted = CryptoJS.RC4.encrypt(data, pass).toString();
download(encrypted, `encrypted-${file.name}`, file.type);
});
});
decryptNode.addEventListener('click', () => {
if (!passNode.value) return alert('Password input is empty! Aborting.');
const pass = CryptoJS.SHA3(passNode.value);
pickAFile(false).then((file) => {
const reader = new FileReader();
reader.onload = async(e) => {
try {
const decrypted = CryptoJS.RC4.decrypt(e.target.result, pass);
const typedArray = convertWordArrayToUint8Array(decrypted);
const data = await base64ToFile(new TextDecoder().decode(typedArray),
`decrypted-${file.name}`, file.type)
download(data, `decrypted-${file.name}`, file.type);
} catch (error) {
console.log('wrong password!', error);
}
};
reader.readAsText(file);
});
});