В расширении браузера Chrome я хочу зашифровать и загрузить файл изображения в IPFS, а затем загрузить тот же файл и расшифровать его. Расширение браузера - это среда javascript на стороне клиента. Для этого мне нужно использовать библиотеку nodejs. Чтобы получить доступ к библиотеке nodejs, я создам исходный файл nodejs. Затем я просматриваю исходный файл nodejs, чтобы к исходному файлу nodejs можно было получить доступ в javascript. Используемые библиотеки nodejs: crypto-js для шифрования, ipfs-api для доступа ipfs и file-saver для сохранения файла. У меня будет один файл javascript и один файл nodejs.
Сначала прочтите файл образа с локального диска. Я использую javascript FileReader.
//read file from the html input, such as <input type=”file” id=”image-file”> file = document.getElementById(‘image-file’).files[0]; let fr = new FileReader(); fr.onload = function(e) { textread = e.target.result; enctext = UU.callEncrypt(textread); } fr.readAsArrayBuffer(file);
Содержимое файла читается как ArrayBuffer.
Второй шаг - выполнить шифрование. Функция шифрования библиотеки crypto-js ожидает ввода строки. Я конвертирую ArrayBuffer в WordArray и в строку. Функция callEncrypt определяется следующим образом.
const CryptoJS = require("crypto-js"); function callEncrypt(argument) { const wordArray = CryptoJS.lib.WordArray.create(argument); const str = CryptoJS.enc.Hex.stringify(wordArray); ct = CryptoJS.AES.encrypt(str, key); ctstr = ct.toString(); return ctstr; }
Третий шаг, выполните загрузку в IPFS. Я создаю буфер из зашифрованной строки и отправляю буфер в IPFS. После этого возвращаю хеш ipfs.
const ipfsAPI = require('ipfs-api'); const ipfs = ipfsAPI(‘ipfs.infura.io’, ‘5001’, {protocol: ‘https’}); let testBuffer = new Buffer(ctstr); ipfs.files.add(testBuffer, function (err, file) { if (err) { console.log(err); } return(file[0].hash); })
В-четвертых, я хочу загрузить файл изображения, используя полученный хеш ipfs. Я передаю хэш и получаю содержимое файла ipfs.
const ipfs = ipfsAPI(‘ipfs.infura.io’, ‘5001’, {protocol: ‘https’}); ipfs.files.get(hash, function (err, files) { files.forEach((file) => { return(file.content); }) })
Пятый шаг, я передаю загруженный контент (который зашифрован) для функции дешифрования. Загруженный контент находится в массиве uint. Я пишу функцию для преобразования uint в строку, а затем передаю строку в функцию дешифрования nodejs. После расшифровки я получил массив слов. Я преобразовываю массив слов в строку. Затем я формирую новый массив слов. Массив слов отличается от предыдущего массива слов. Затем я конвертирую массив слов в массив байтов (для перехода к следующему шагу).
var str = uintToString(enctext) const decrypted = CryptoJS.AES.decrypt(str, key); str = decrypted.toString(CryptoJS.enc.Utf8); const wordArray = CryptoJS.enc.Hex.parse(str); BaText = wordArrayToByteArray(wordArray, wordArray.length); return(BaText);
Наконец, мы сохраняем контент в локальный файл. Я формирую новый массив uint8 из возвращенного байтового массива. Затем создается Blob. Я должен использовать тип mime image / jpeg для сохранения файла jpeg.
const FileSaver = require('file-saver'); var arrayBufferView = new Uint8Array(argument); var blob = new Blob( [ arrayBufferView ], { type: “image/jpeg” } ); FileSaver.saveAs(blob,”filename.jpg”);
Используемые служебные функции показаны ниже:
function toString(words){ return CryptoJS.enc.Utf8.stringify(words); } function uintToString(uintArray) { var decodedStr = new TextDecoder("utf-8").decode(uintArray); return decodedStr; } function wordToByteArray(word, length) { var ba = [],i,xFF = 0xFF; if (length > 0) ba.push(word >>> 24); if (length > 1) ba.push((word >>> 16) & xFF); if (length > 2) ba.push((word >>> 8) & xFF); if (length > 3) ba.push(word & xFF); return ba; }
Вот и все.