javascript - 如何使用 crypto-js 将加密输出的二进制数据保存到文件中?

标签 javascript expo cryptojs

我正在尝试帮助移动开发人员加密图像并将其上传到 Azure Blob 存储。移动应用程序使用 expo 和 crypto js。我对移动开发或 expo 不太熟悉,但看起来 expo 可以让您访问图像的 base64 编码版本。

我的目标是使用 crypto js 加密该图像数据,并将其上传到 Azure blob 存储。

世博会或 Azure 的具体细节对我的问题来说并不是那么重要,但我认为它们值得一提。我认为重要的是我使用 crypto js 来 AES 加密该图像数据。

我从图像数据的 Base64 字符串开始,因此我使用 crypto js 来解析它,如下所示......

const words = CryptoES.enc.Base64.parse(data);

这给了我一个代表图像数据的 WordArray,我认为(来自移动 API 给我的 base64 字符串)。

接下来我可以像这样加密图像数据......

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);

使用 here 中的 saveByteArray()


另一种方法是使用 Latin1 encoderWordArray 转换为二进制字符串:

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);

关于javascript - 如何使用 crypto-js 将加密输出的二进制数据保存到文件中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71567222/

相关文章:

javascript - 是否存在从 HTML 属性名称到 DOM 属性名称的映射?

JavaScript JSON 组合和数据 Anylish

javascript - 如何在 Alert 函数 [React-Native] 上从 onPress 调用方法

npm - Expo Error 启动隧道无法全局安装@expo/ngrok@^2.4.3

react-native - 如何从 Expo SQLite API 获取 sql 错误的原因?

javascript - 如何从 JMeter 调用外部 JavaScript 文件方法

javascript - Node JS 回调函数

android - 无法从 React Native 移动应用程序向本地主机后端发送 HTTP 请求

javascript - C - tiny-aes-c 和 Javascript CryptoJS 互操作性

node.js - 将 xml-crypto 与 PSHA1 结合使用