В расширении браузера 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;
}

Вот и все.