Два файла могут иметь одинаковое имя и размер, но разное содержимое. Чтобы проверить файл относительно заранее известного образца, можно сравнить SHA-256. В этой инструкции n8n посчитает хэш учебного отчёта, сверит его с фиксированным эталоном и остановится, если байты изменились.
Результат инструкции
Соберём ручной workflow из пяти узлов. Code создаст текстовый файл, Crypto рассчитает SHA-256 его binary-данных, последний Code сравнит результат с заранее заданным значением. Для исходного файла получим status verified и matches_expected true. Изменим одну цифру при том же размере файла — получим ошибку file_sha256_mismatch.
Это проверка совпадения с эталоном, не шифрование, электронная подпись или антивирус. Хэш сам по себе не подтверждает автора документа и правильность его содержания. AI-модель, API-ключ и внешние сервисы здесь не нужны. Файлы никому не отправляются.
Что понадобится
- Работающий n8n и доступ к новому учебному workflow. Проверено на n8n 2.42.4, Crypto версии 2, binary-режим filesystem.
- Code на JavaScript. В примере используется только маленький вымышленный отчёт, без чтения личных папок.
- Для дополнительной проверки скачанного файла — PowerShell на Windows. Основной workflow работает без этой проверки.
Установить n8n локально через Docker
Шаг 1. Импортируйте workflow
Скачать n8n-file-sha256-check.json
Создайте отдельный workflow. В меню редактора выберите Import from File и загрузите JSON. После импорта должно быть пять узлов:
Manual Trigger → Sample File → Check File → File SHA256 → Compare SHA256
File SHA256 — штатный Crypto. Sample File, Check File и Compare SHA256 — Code. Сохраните имена при ручной сборке: итоговый Code обращается к Check File. Workflow неактивен, credentials и ID чужой схемы не содержит. Для действия Hash создавать Crypto credentials не требуется.
Шаг 2. Создайте учебный файл
В Sample File выберите Mode: Run Once for All Items, Language: JavaScript. Вставьте:
const text = `Учебный отчёт ezGPT
Заказы: 2
Сумма: 150000 копеек
`;
const expected_sha256 = 'bb17d9a5af47d968e26ffdab09cb3fb642f67ca0a76cee6d8cd99099731565ec';
const file = await this.helpers.prepareBinaryData(
Buffer.from(text, 'utf8'), 'n8n-sha256-demo.txt', 'text/plain',
);
return [{ json: { file_id: 'hash-demo-001', expected_sha256 }, binary: { document: file } }];
Запустите от Manual Trigger. В Output ожидается один item с file_id hash-demo-001 и expected_sha256. Во вкладке Binary должно быть поле document с файлом n8n-sha256-demo.txt. Его содержимое занимает 80 байт UTF-8: кириллица занимает больше одного байта на букву.
Поле document — имя binary-поля, n8n-sha256-demo.txt — имя файла. В настройку Crypto будем вводить document, а не имя файла и не путь к нему. prepareBinaryData создаёт файловые данные в хранилище n8n; это не сохранение отчёта в вашу рабочую папку.
Шаг 3. Зафиксируйте эталон
Для точных байтов исходного примера ожидается такой SHA-256 в нижнем регистре:
bb17d9a5af47d968e26ffdab09cb3fb642f67ca0a76cee6d8cd99099731565ec
Значение уже записано в expected_sha256 узла Sample File. Не пересчитывайте его автоматически из проверяемого файла в том же запуске: тогда вы сравните новый файл с его же новым хэшем и потеряете смысл проверки изменения.
В реальной задаче эталон получают из доверенного исходника или надёжного канала и хранят с контролем изменений. Если отправитель или посторонний может одновременно заменить файл и ожидаемый хэш, одно сравнение SHA-256 не защитит от такой подмены.
Шаг 4. Проверьте вход и размер
В Check File задайте Run Once for All Items, JavaScript и вставьте:
const items = $input.all();
if (items.length !== 1) throw new Error('one_file_required');
const item = items[0];
if (item.json.file_id !== 'hash-demo-001') throw new Error('file_id_invalid');
if (typeof item.json.expected_sha256 !== 'string' || !/^[a-f0-9]{64}$/.test(item.json.expected_sha256)) {
throw new Error('expected_sha256_invalid');
}
if (Object.keys(item.binary || {}).join('|') !== 'document') throw new Error('document_binary_required');
const file = item.binary.document;
if (file.fileName !== 'n8n-sha256-demo.txt') throw new Error('file_name_invalid');
const buffer = await this.helpers.getBinaryDataBuffer(0, 'document');
if (!buffer.length || buffer.length > 16384) throw new Error('file_size_invalid');
return [{ json: {
file_id: item.json.file_id,
file_name: file.fileName,
bytes: buffer.length,
expected_sha256: item.json.expected_sha256,
}, binary: item.binary }];
Пример требует один item, заданный ID, строковый эталон из 64 символов a–f и 0–9, только одно binary-поле document и точное имя файла. Пустой файл или содержимое больше 16384 байт отклоняются. Это выбранный договор учебной схемы, а не предел SHA-256 и не утверждение, что пустой файл нельзя хэшировать.
Размер читается через getBinaryDataBuffer. Не считайте хэш строки binary.document.data: в файловом режиме там может находиться служебная ссылка вместо содержимого. Сам Crypto получит исходное binary-поле, а не текст этой ссылки.
В Settings всех узлов оставьте On Error: Stop Workflow. Continue On Fail, Retry On Fail, Always Output Data и Execute Once не включайте. Повторный расчёт не вернёт изменённый файл к эталону.
Шаг 5. Настройте Crypto
В File SHA256 задайте следующие значения:
| Настройка | Значение | Что проверяет пример |
|---|---|---|
| Action | Hash | Не Encrypt, Hmac или Sign |
| Type | SHA256 | Не SHA3-256 и не MD5 |
| Binary File | On | Хэшируются байты файла |
| Binary Property Name | document | Имя входного binary-поля |
| Property Name | sha256 | Поле для вычисленного хэша |
| Encoding | HEX | 64 шестнадцатеричных символа |
Выполните узел. В JSON появится sha256 рядом с expected_sha256. Для исходника значения должны совпасть. Не записывайте результат в expected_sha256: вычисленный и ожидаемый хэши должны оставаться разными полями. Вложенный путь result.sha256 в этой схеме не используется.
В проверенной версии Crypto при хэшировании binary-файла не переносит binary в свой выход: после узла остаётся JSON. Это не удаление исходного файла из всей истории выполнения. Если файл нужен для дальнейшего действия, заранее продумайте отдельную ветку и корректное соединение результатов; данная схема возвращает только отчёт проверки.
Шаг 6. Сравните хэш с эталоном
В Compare SHA256 выберите Run Once for All Items, JavaScript и вставьте:
const items = $input.all();
if (items.length !== 1) throw new Error('one_hash_result_required');
const row = items[0].json;
if (Object.keys(row).sort().join('|') !== 'bytes|expected_sha256|file_id|file_name|sha256') {
throw new Error('hash_fields_mismatch');
}
const original = $('Check File').first().json;
for (const key of ['file_id', 'file_name', 'bytes', 'expected_sha256']) {
if (row[key] !== original[key]) throw new Error('file_metadata_changed');
}
if (typeof row.sha256 !== 'string' || !/^[a-f0-9]{64}$/.test(row.sha256)) {
throw new Error('sha256_format_invalid');
}
if (row.sha256 !== row.expected_sha256) throw new Error('file_sha256_mismatch');
return [{ json: {
file_id: row.file_id,
file_name: row.file_name,
bytes: row.bytes,
algorithm: 'SHA256',
sha256: row.sha256,
matches_expected: true,
status: 'verified',
action_performed: false,
} }];
Сначала проверяются поля и сохранность метаданных из Check File, затем формат вычисленного хэша и точное совпадение с эталоном. При несовпадении выполнение заканчивается ошибкой, а не объектом с verified. В этом учебном варианте ожидается нижний регистр; верхний регистр строки эталона специально не нормализуется автоматически.
Поле algorithm в отчёте описывает настроенный нами сценарий. По одной длине строки нельзя определить алгоритм: SHA3-256 тоже может дать 64 символа, но это другой расчёт. Поэтому выбирайте именно SHA256 и сравнивайте с эталоном того же алгоритма.
Шаг 7. Выполните всю цепочку
Нажмите Execute Workflow. Каждый узел должен обработать один item. Итоговый JSON:
{
"file_id": "hash-demo-001",
"file_name": "n8n-sha256-demo.txt",
"bytes": 80,
"algorithm": "SHA256",
"sha256": "bb17d9a5af47d968e26ffdab09cb3fb642f67ca0a76cee6d8cd99099731565ec",
"matches_expected": true,
"status": "verified",
"action_performed": false
}
Сверьте 80 байт, правильное имя файла, точный хэш, matches_expected true и status verified. action_performed false означает отсутствие отправки или других внешних действий. Сам файл и его хэш внутри n8n действительно создавались.
verified означает только прохождение этой проверки относительно данного эталона. Это не разрешение на публикацию, оплату, подписание, открытие вложения или исполнение его содержимого.
Шаг 8. Измените цифру без изменения размера
В Sample File замените в тексте 150000 на 150001. expected_sha256 оставьте прежним. Запустите всю цепочку. В Check File размер по-прежнему будет 80 байт, в File SHA256 получится другой хэш, а Compare SHA256 даст file_sha256_mismatch. Успешного отчёта verified быть не должно.
Верните 150000 и повторите запуск: ожидается исходный результат. Этот тест показывает, почему проверка одного лишь размера недостаточна. Замена имени или расширения сама по себе не меняет байты, но наша отдельная проверка имени вправе отклонить такой вход.
Шаг 9. Учтите переносы и кодировку
Для воспроизводимого теста в Sample File временно замените только вызов Buffer.from(text, 'utf8') на Buffer.from(text.replaceAll('\n', '\r\n'), 'utf8'). Это превратит LF в CRLF. Эталон оставьте прежним: ожидается file_sha256_mismatch. Затем верните исходный Buffer.from.
Внешне текст может выглядеть прежним, но хэш зависит от байтов, а не от того, как редактор показывает строки. В наших проверках следующие изменения также дали несовпадение:
| Изменение | Что изменилось | Результат |
|---|---|---|
| LF → CRLF | Байты переносов строк | file_sha256_mismatch |
| Убран последний перенос | Конец файла | file_sha256_mismatch |
| Добавлен UTF-8 BOM | Три начальных байта | file_sha256_mismatch |
Не удаляйте пробелы, не меняйте кодировку и не пересохраняйте файл перед проверкой, если нужно сверить именно полученные байты. Нормализация текста и проверка исходного файла — разные задачи.
Шаг 10. Проверьте неверные настройки
В File SHA256 временно смените Encoding на BASE64. Ожидается sha256_format_invalid: результат больше не соответствует нашему договору HEX. Верните HEX.
Теперь выберите Type SHA3-256. Строка может остаться длиной 64 символа, но Compare SHA256 должен дать file_sha256_mismatch. Верните SHA256. Если указать Binary Property Name data, ошибка возникнет в File SHA256: такого binary-поля в примере нет. Верните document.
Выключение Binary File означает другой режим. Если в Value написать document или n8n-sha256-demo.txt, будут хэшироваться эти буквальные строки, а не содержимое файла. Для нашей задачи Binary File должен быть включён.
Шаг 11. Сверьте скачанный файл через PowerShell
Скачать исходный n8n-sha256-demo.txt
Скачайте файл без открытия и пересохранения в редакторе. В PowerShell задайте его фактический путь. Если он находится в стандартной папке Downloads, команда такая:
$file = Join-Path $HOME 'Downloads\n8n-sha256-demo.txt'
(Get-FileHash -LiteralPath $file -Algorithm SHA256).Hash.ToLowerInvariant()
Путь замените, если браузер сохранил файл в другую папку или добавил к имени номер. Команда только читает файл. Результат должен совпасть с шагом 3. Нижний регистр нужен для удобного сравнения с нашим эталоном; сам математический хэш от регистра его текстовой записи не меняется.
Эта дополнительная проверка относится к скачанному файлу на Windows, не к произвольному файлу в контейнере. Совпадение здесь подтверждает, что опубликованный образец и созданные в n8n учебные байты дают один и тот же ожидаемый результат.
Шаг 12. Восстановите рабочий вариант
Верните исходный текст, UTF-8 без BOM, LF и завершающий перенос строки. В Crypto должны быть Hash, SHA256, Binary File On, document, sha256, HEX. Сохраните workflow, выполните его заново и сверьте результат с шагом 7.
Для другого файла сначала получите доверенный эталон отдельно, затем осознанно обновите имя, ID и ограничения примера. Не вычисляйте новый expected_sha256 из неизвестного входа ради устранения ошибки. Неверный хэш должен останавливать дальнейшее действие, пока причина не разобрана человеком.
Если результат отличается
| Ошибка | Причина | Что проверить |
|---|---|---|
| document_binary_required | Отсутствует нужное binary-поле | Output Sample File |
| expected_sha256_invalid | Эталон не соответствует формату | 64 символа HEX в нижнем регистре |
| hash_fields_mismatch | Результат записан не в то поле | Property Name sha256 |
| sha256_format_invalid | Не HEX SHA256 или неверный тип | Type и Encoding |
| file_sha256_mismatch | Вычисленный хэш не совпал | Байты, алгоритм и доверенный эталон |
Не считайте любую ошибку доказательством атаки: причиной может быть неверный путь, случайное пересохранение, BOM или другой алгоритм. И наоборот, успешное сравнение не проверяет содержание на вредоносность и не подтверждает отправителя.
Что нельзя поручать одному хэшу
SHA-256 не скрывает содержимое и не является секретным ключом. В этой схеме нет электронной подписи, проверки автора, антивируса и контроля доступа к эталону. Для важных документов эти задачи решают отдельно. Если злоумышленник заменил и документ, и ожидаемый хэш, простое сравнение может выглядеть успешным.
Не загружайте сюда реальные клиентские документы без понимания хранения выполнений n8n. Пример проверен на 80-байтовом файле; чтение буфера в Code не является схемой потоковой обработки больших файлов. Cloud, очереди workers и другие binary-режимы нужно тестировать отдельно.
Создать ZIP и проверить распакованные байты
Прочитать CSV с проверкой данных
Остановить workflow при неверном входе
Что проверено редакцией
16 октября 2026 года workflow проверен на n8n 2.42.4 в отдельном Docker-экземпляре с binary-режимом filesystem ручными запусками API. Успешно пройдена 31 проверка: исходный файл, лишнее JSON-поле и MIME, изменения текста и байтов, тот же размер, переносы, BOM, входные поля и размеры, эталон, режимы Crypto, алгоритмы, Encoding, имя результата и метаданные. Основной запуск использует точный скачиваемый workflow. SHA-256 исходных 80 байт совпал с независимыми Node.js createHash и PowerShell Get-FileHash. Подтверждено отсутствие binary на выходе Crypto в проверенном Hash-режиме. При ошибках успешного отчёта нет. Настройки Crypto 2 сверены с официальной документацией и кодом узла. Редакторские клики, Cloud, другие binary-режимы, большие и реальные файлы, подписи, шифрование и полный аудит безопасности не тестировались. Учебный контейнер остановлен, существующие workflows не менялись. Обложка — редакционная AI-иллюстрация.
Частые вопросы
Почему файл того же размера не прошёл проверку?
Размер показывает только число байт. Если изменить 150000 на 150001, длина останется прежней, но вычисленный SHA-256 в нашем тесте изменится.
Можно пересчитать эталон прямо из проверяемого файла?
Не для обнаружения изменения относительно старого образца. Эталон должен быть известен заранее и получен доверенным способом. Иначе вы подтвердите только совпадение файла с самим собой.
Почему после Crypto исчезла вкладка Binary?
В проверенной версии действие Hash для binary-файла возвращает JSON без переноса binary. Если файл нужен дальше, проектируйте отдельную ветку, а не считайте поле sha256 самим файлом.
Совпавший SHA-256 доказывает, кто прислал файл?
Нет. Он проверяет совпадение относительно эталона, но не подтверждает отправителя и не заменяет подпись, проверку доверенного канала или антивирус.
Почему PowerShell показывает заглавные буквы?
Это другой регистр записи HEX, а не другой хэш. Команда из инструкции приводит строку к нижнему регистру, чтобы её можно было напрямую сравнить с нашим примером.