Estoy tratando de ayudar a un desarrollador móvil a cifrar una imagen y cargarla en el almacenamiento de blobs de Azure. La aplicación móvil usa expo y crypto js. No estoy muy familiarizado con el desarrollo móvil o la exposición, pero parece que la exposición te da acceso a una versión codificada en base64 de la imagen.
Mi objetivo es cifrar los datos de esa imagen, usando crypto js, y cargarlos en el almacenamiento de blobs de Azure.
Los detalles de expo o Azure no son realmente tan importantes para mi pregunta, pero creo que vale la pena mencionarlos. Creo que lo importante es que estoy usando crypto js para cifrar AES los datos de la imagen.
Estoy comenzando con una cadena base64 de datos de imagen, por lo que uso crypto js para analizarlo de la siguiente manera...
const words = CryptoES.enc.Base64.parse(data); Esto me da un WordArray representa los datos de la imagen, creo (de la cadena base64 que me da la API móvil).
A continuación, puedo cifrar los datos de esa imagen así...
const encrypted = CryptoES.AES.encrypt(words, AES_KEY, { iv: AES_IV });Ahora que tengo los datos cifrados, me gustaría escribirlos en un archivo en formato hexadecimal binario o lo que sea. No quiero texto base64 en el archivo y no quiero una cadena hexadecimal en el archivo; me gustaría que contenga byte por byte de datos cifrados literales.
No estoy seguro de cómo obtener estos datos.
Supongo que es solo "toString", pero cuando lo hago dice invalid utf8 . Este es un archivo JPG que se está tratando.
¿Cómo puedo obtener solo los datos de bytes reales y escribirlos en un archivo con crypto js?
CryptoJS.AES.encrypt() devuelve un objeto CipherParams que encapsula, entre otros, el texto cifrado como WordArray . Una posibilidad es convertir este WordArray en un Uint8Array con un método personalizado. En el siguiente código, esta conversión se realiza mediante 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 Este Uint8Array ahora se puede almacenar en un archivo, por ejemplo, con:
var fileName = "encdata.bin"; saveByteArray([ciphertextArr], fileName); usando saveByteArray() desde aquí .
Otro enfoque es convertir WordArray en una cadena binaria usando el codificador Latin1 :
var ciphertextBinStr = ciphertextWA.toString(CryptoJS.enc.Latin1); que luego se puede convertir fácilmente en un Uint8Array , por ejemplo, con:
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);