Я пытаюсь помочь мобильному разработчику зашифровать изображение и загрузить его в хранилище BLOB-объектов Azure. Мобильное приложение использует expo и crypto js. Я не очень хорошо знаком с мобильным разработчиком или выставкой, но похоже, что выставка дает вам доступ к версии изображения в кодировке base64.
Моя цель — зашифровать эти данные изображения с помощью криптографии js и загрузить их в хранилище BLOB-объектов Azure.
Специфика выставки или Azure на самом деле не так важна для моего вопроса, но я полагаю, что о них стоит упомянуть. Я думаю, что важно то, что я использую crypto js для шифрования данных изображения с помощью AES.
Я начинаю со строки данных изображения base64, поэтому я использую crypto js для анализа, как показано ниже...
const words = CryptoES.enc.Base64.parse(data);
Я думаю, что это дает мне WordArray
представление данных изображения (из строки base64, которую дает мне мобильный API).
Затем я могу зашифровать эти данные изображения вот так...
const encrypted = CryptoES.AES.encrypt(words, AES_KEY, { iv: AES_IV });
Теперь, когда у меня есть зашифрованные данные, я хотел бы записать их в файл только в двоичном шестнадцатеричном формате или в каком-то другом. Я не хочу, чтобы в файле был текст base64, и я не хочу, чтобы в файле была шестнадцатеричная строка - я бы хотел, чтобы она содержала буквальные зашифрованные данные байт за байтом.
Я не уверен, как получить эти данные.
Я думаю, это просто «toString», но когда я это делаю, он говорит, что это недействительно utf8
. Это файл JPG, который обрабатывается.
Как я могу получить только фактические байтовые данные и записать их в файл с помощью crypto js?
CryptoJS.AES.encrypt()
возвращает объект CipherParams
, который инкапсулирует, среди прочего, зашифрованный текст как WordArray
. Одна из возможностей — преобразовать это WordArray
в Uint8Array
с помощью пользовательского метода. В следующем коде это преобразование выполняется с помощью convertWordArrayToUint8Array()
:
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;
}
var AES_KEY = CryptoJS.enc.Utf8.parse('0123456789012345');
var AES_IV = CryptoJS.enc.Utf8.parse('5432109876543210');
var plaintext = 'The quick brown fox jumps over the lazy dog';
var ciphertextCP = CryptoJS.AES.encrypt(plaintext, AES_KEY, { iv: AES_IV }); // CipherParams object
var ciphertextWA = ciphertextCP.ciphertext; // WordArray
var ciphertextArr = convertWordArrayToUint8Array(ciphertextWA); // Uint8Array
Этот Uint8Array
теперь можно сохранить в файле, например. с:
var fileName = "encdata.bin";
saveByteArray([ciphertextArr], fileName);
используя saveByteArray()
из здесь.
Другой подход — преобразовать WordArray
в двоичную строку с помощью Кодировщик Latin1:
var ciphertextBinStr = ciphertextWA.toString(CryptoJS.enc.Latin1);
который затем можно легко преобразовать в Uint8Array
, например. с:
function str2Uint8Array(str) {
const arr = new Uint8Array(new ArrayBuffer(str.length));
for (let i = 0, strLen = str.length; i < strLen; i++)
arr[i] = str.charCodeAt(i);
return arr;
}
var ciphertextArr = str2Uint8Array(ciphertextBinStr);