NodeJs / Javascript AES 128 EBC шифрование не соответствует iOS AES 128 EBC шифрование - PullRequest
0 голосов
/ 04 января 2019

В нашем проекте Angular нам необходимо расшифровать текст / файл, зашифрованный iOS.

Команда iOS использует 128-битное шифрование AES с алгоритмом режима ECB.

Я пробовалиспользуя CryptoJS, aes-js и непосредственно используя класс Crypto из NodeJs.

Результат зашифрованного текста или дешифрованной строки UTF8 из iOS не совпадает.Мы получаем разные значения.

Команда iOS использует библиотеку aes-commoncrypto

Перед вызовом общей библиотеки шифрования мы конвертируем строку в данные iOS (Dataatype), т. Е. Буфер байтов и кодировкус UTF8

Шифрование -

let fileUrl = URL(fileURLWithPath: folderPath)
                    try? Utils.aes128Encryption(forData: 
textAnnotationText.data(using: .utf8))?.write(to: fileUrl)

Расшифровка -

 let _fileURL = documentsDirectory.appendingPathComponent( path)

do {
        if let decryptedData = Utils.aes128Decryption(forData: try Data(contentsOf: _fileURL)) {
                                            message = String(decoding: decryptedData, as: UTF8.self)
                                   }
}

CCCrypt(operation,
                  kCCAlgorithmAES128,
                  kCCOptionPKCS7Padding | kCCOptionECBMode,
                  keyPtr,
                  kCCBlockSizeAES128,
                  ivPtr,
                  [self bytes],
                  dataLength,
                  buffer,
                  bufferSize,
                  &numBytesEncrypted)

Согласно пониманию из приведенного выше кода, команда iOS использует алгоритм режима ECB.Вывод: строка UTF8, и мы запишем ее в файл каталога документов.

Решение 1: С CryptoJS:

let key = CryptoJS.enc.Utf8.parse(TESTKEY);
let iv = CryptoJS.lib.WordArray.create([0, 0]);
const encrypted = CryptoJS.AES.encrypt(message, key, {
        keysize: 256 / 8,
        iv: iv.toString(),
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
    });

const encrypted64 = encrypted.ciphertext.toString ();

Вывод: строка в кодировке Base64.(Не совпадает с зашифрованным текстом iOS)

Решение 2: С AES Js:

let aesEcb = new aesjs.ModeOfOperation.ecb(Buffer.from(key, 'utf8'));
let textBytes = aesjs.utils.utf8.toBytes(str);
let encryptedBytes = aesEcb.encrypt(textBytes);

Вывод: Мы получаем ошибку "неверный размер открытого текста (должен быть кратен 16 байтам)"

Решение 3. Использование криптографического расшифровщика

fs.readFile('./sample_text.html', 'utf-8', function (err, data) {
    if (err) throw err;
    console.log(data);
    const d = crypto.createDecipheriv('aes-128-ecb', convertCryptKey(key), '')
    let ret = ''
    d.setAutoPadding(false);
    console.log(Buffer.from(data, 'utf8'));
    ret = d.update(data, 'binary', 'utf8')

    console.log(ret);
    decoded = Buffer.concat([ ret, d.final() ]);
    console.log(decoded);
});

function convertCryptKey(strKey) {
   const newKey = new Buffer([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
   strKey = new Buffer(strKey)
   for (let i = 0; i < strKey.length; i++) newKey[i % 16] ^= strKey[i]
   return newKey
}

Вывод: не совпадает с зашифрованной строкой или файлом iOS

...