Перейти к содержимому
Назад в Академию

PII и SHA-256: как хешировать email и телефон для Meta, Google и TikTok

13.07Server-side и API-интеграции
Содержание статьи

Интернет-магазин кофе из урока про Conversions API отправляет оплаченные заказы в Meta с сервера. Для заказа O42 на 15 000 ₸ в user_data уходят хеши email aigerim@example.com и телефона 77011234567 (магазин и цифры в уроке условные). Теперь владелец хочет видеть те же покупки в Google Ads и TikTok, и разработчик подключает к двум новым отправкам готовую функцию из интеграции с Meta. Запросы проходят без ошибок. Но Google и TikTok ждут телефон с плюсом, +77011234567, а SHA-256 от строки без плюса - совсем другие 64 символа. В этих двух системах телефон не совпадёт ни с одним аккаунтом, и сообщения об ошибке не будет: по хешу платформа не может понять, правильно ли вы подготовили номер.

Один телефон, два разных хеша

  • Meta

    Цифры с кодом страны, без плюса

    77011234567

    Начало хеша: 7c1dc35860507e0f

  • Google Ads и TikTok

    E.164 с плюсом

    +77011234567

    Начало хеша: c87ea5d396b7f324

Хеш номера без плюса не совпадёт в Google и TikTok, и ошибки платформа не покажет.

Meta ждёт номер 77011234567, Google и TikTok ждут +77011234567, и SHA-256 у этих строк разный; показано только начало каждого хеша.

Что делает SHA-256

SHA-256 превращает любую строку в 256 бит, в шестнадцатеричной записи это 64 символа. Одна и та же строка всегда даёт один и тот же хеш, а строка, которая отличается хоть одним символом, даёт совсем другой. Алгоритм описан в стандарте NIST FIPS 180-4.

Ключа, которым хеш «расшифровывают» обратно, нет. Зато любой может захешировать догадку и сравнить. На этом и держится сопоставление: платформа хеширует контакты своих пользователей тем же способом и ищет совпадение с вашей строкой. Для телефонов перебор и того проще. Казахстанских мобильных номеров вида +7 7XX XXX XX XX не больше миллиарда: ноутбук переберёт их все за минуты, видеокарта - за доли секунды.

Поэтому хеширование - это псевдонимизация, а не анонимизация. Британский регулятор ICO пишет, что псевдонимизированные данные остаются персональными для того, у кого есть дополнительные сведения, и среди атак называет перебор и поиск по словарю (разбор псевдонимизации; руководство сейчас пересматривают после принятия Data (Use and Access) Act). Хеш, по которому рекламная платформа находит человека, анонимным не становится. Разъяснений казахстанского регулятора о хешах мы не нашли, а закон определяет анонимизацию как необратимое преобразование, после которого нельзя установить, чьи это данные (статья 1, подпункт 2-5). Поэтому относитесь к хешу как к персональным данным, а можно ли его передавать, решайте с юристом клиента, как и для самого номера (подробнее в уроке про privacy и consent mode).

Нормализация: одна строка на один контакт

Посмотрите, как меняется начало хеша от мелочей:

Строка на входе SHA-256Начало хеша
Aigerim@Example.com0cc7ad510621a3cb
aigerim@example.com882a7adc5f92074a
87011234567f88e23205f5ab683
770112345677c1dc35860507e0f
+77011234567c87ea5d396b7f324

Для человека тут один адрес и один телефон, для платформы - пять разных людей. Поэтому перед хешированием контакт приводят к одному виду, и делают это по правилам той платформы, куда он уходит.

С email все три платформы согласны: пробелы по краям убрать, все буквы перевести в нижний регистр. Для адресов gmail.com и googlemail.com у Google есть своё правило: в справке по тегу Google сказано убрать точки в имени до «@», а документация Google Ads API велит убрать ещё и первый «+» со всем, что стоит после него до «@» (нормализация в Google Ads API). К другим доменам и другим платформам это не относится.

С телефоном начинаются различия. Meta просит только цифры с кодом страны, без плюса: 77011234567. Google и TikTok ждут формат E.164 с плюсом: +77011234567. Ловушка для Казахстана - восьмёрка. Если из 8 (701) 123-45-67 просто выбросить всё, кроме цифр, получится 87011234567: восьмёрка в начале - междугородний префикс, а не код страны, и это уже другой номер. Заменять 8 на 7 можно, только когда вы знаете, что номер казахстанский: например, в форме стоит маска «+7» или поле выбора страны. Гадать с иностранными номерами нельзя. TikTok в документации советует для разбора номеров библиотеку libphonenumber-js.

Правила трёх платформ

MetaGoogle AdsTikTok
EmailПробелы по краям убрать, нижний регистрТо же, плюс правило для gmail.com и googlemail.comПробелы по краям убрать, нижний регистр
ТелефонЦифры с кодом страны: 77011234567E.164 с плюсом: +77011234567E.164 с плюсом: +77011234567
Кто хешируетВы или ваш серверный шаблонТег Google умеет сам, при загрузке через API - выВы или ваш серверный шаблон
Не хешируютfbp, fbc, IP, user agentСтрану, область, город, индексttclid, ttp, IP, user agent

Источники: параметры клиента в Conversions API, нормализация в Google Ads API, настройка улучшенных конверсий для сайта через тег Google, параметры Events API в TikTok. Обратите внимание на адрес: город и страну Meta хеширует, а Google просит передавать открытым текстом.

Строку «Не хешируют» легко пропустить. fbp, fbc, ttclid, ttp, IP и user agent - не контакты, а идентификаторы браузера и клика и данные запроса, и платформы сравнивают их в исходном виде. Поэтому весь user_data через одну функцию SHA-256 не прогоняют. IP при этом передают покупателя, а не вашего сервера, и где его взять, описано в разделе что хешировать, а что нет.

Вот как выглядят оба варианта для покупательницы заказа O42. Код можно запустить в Node.js и сверить с ним свою функцию: для тех же входных строк хеши должны совпасть до символа.

const { createHash } = require("node:crypto");
const sha256 = (value) => createHash("sha256").update(value, "utf8").digest("hex");
const email = " Aigerim@Example.com ".trim().toLowerCase();
const phoneMeta = "+7 701 123-45-67".replace(/\D/g, "");
const phoneE164 = "+" + phoneMeta;
console.log(email, sha256(email));
// aigerim@example.com 882a7adc5f92074a7721b6e396112855a0d57cdff5586ecac743995ad252dbcc
console.log(phoneMeta, sha256(phoneMeta));
// 77011234567 7c1dc35860507e0fee0dee49def2433f25534035de81deb1bbc6f4c006e4c90a
console.log(phoneE164, sha256(phoneE164));
// +77011234567 c87ea5d396b7f3244ee926b250483c2eb3e5345c14eb18eaa874ed2edbf903af

Где хешировать и сколько раз

Контакт проходит через форму, CRM, скрипт, серверный контейнер и шаблон тега. Хешировать его нужно ровно в одном месте. Если CRM уже хранит хеш, а шаблон в sGTM хеширует ещё раз, наружу уйдёт хеш от хеша, и он ни с чем не совпадёт. Перед подключением прочитайте документацию своего шаблона: одни ждут открытый контакт и хешируют сами, другие ждут готовый хеш. Тег Google, например, принимает и то и другое.

Соль (случайная добавка к строке перед хешированием) нужна для внутренней псевдонимизации: ICO советует хешировать именно с такой добавкой. Но в рекламную платформу хеш с солью отправлять бессмысленно: у платформы этой соли нет, и совпадений не будет.

Хеширование не отменяет согласия: при отказе в ad_user_data тег Google хешированные контакты не отправит (consent mode). Meta пишет прямо: через Conversions API не передавайте события людей, которые не дали согласия (требования Meta к конфиденциальности).

PII в GA4 не отправляют

В GA4 контакты не нужны ни открытыми, ни хешированными. Google запрещает передавать в Analytics данные, по которым он может узнать человека, и называет среди них email и номер телефона. Запрет касается и адреса страницы с его параметрами, и заголовков страниц (правила Google Analytics о PII). Утекает так: форма после отправки открывает /thanks?email=..., разработчик кладёт телефон в параметр generate_lead, user_id равен email. Чтобы этого не было, контакты не кладут в те события dataLayer, из которых теги берут параметры для аналитики.

Хешированный email в параметре события отчётам ничего не даёт. Для улучшенных конверсий контакты передают тегу Google отдельно, в момент конверсии и только при ad_user_data = granted, а в параметры событий GA4 их не кладут. Если клиенту нужно, чтобы Google сопоставлял пользователей GA4 по контактам, для этого есть отдельная функция «Сбор данных, предоставленных пользователями», со своими правилами, которые принимают в настройках ресурса (о сборе данных, предоставленных пользователями).

Проверка на тестовых значениях

Проверяйте на значениях из примера выше, а не на контактах реальных клиентов. И не вставляйте настоящие email и телефоны в онлайн-калькуляторы хешей: строка уходит на чужой сервер.

  • Meta: отправьте событие с test_event_code и найдите его во вкладке «Тестирование событий» в Events Manager.
  • Google: в запросе тега Google при конверсии найдите параметр em. Его значение начинается с tv.1~em, а дальше идёт длинная строка. Если после tv.1~em ничего нет, параметр уходит пустым: в момент конверсии на странице не было данных (настройка улучшенных конверсий для сайта через тег Google).
  • TikTok: отправьте тестовое событие и сверьте хеши в теле запроса со своим логом.

В рабочих логах держите ID событий и коды ответов. Открытым контактам там не место: лог читает больше людей, чем CRM.

Задание: контакты в своей интеграции

На тестовом магазине или у клиента:

Выполнено 0 из 5

И вопрос, который возникнет на первой же выгрузке. В CRM магазина телефоны записаны по-разному: +7 701 123 45 67, 8 (701) 123-45-67 и 701 123 45 67. Что хешировать для Meta и что для Google?

Если магазин доставляет только по Казахстану и иностранных номеров среди клиентов нет, это один номер. Для Meta его приводят к 77011234567, для Google и TikTok к +77011234567. Восьмёрку меняют на семёрку, а к десяти цифрам дописывают 7 потому, что страна известна. Если среди клиентов бывают иностранцы, а номер набран в свободном поле, такую запись лучше не отправлять вовсе, чем отправить чужой номер. А форму стоит переделать: маска с кодом страны решает задачу раньше, чем номер попадёт в CRM.

Видео: как устроено хеширование

Хеширование и SHA-256. Простыми словами и с примерами!

Объяснение хеш-функции на русском. Правила подготовки контактов для каждой платформы - в документации, на которую ссылается урок.

Нужна помощь с аналитикой вашего проекта?