Во многих случаях, особенно при передаче ID пользователя в URL или JavaScript, нежелательно раскрывать внутренние значения из базы данных. Простой числовой идентификатор, например 123, может позволить злоумышленнику перебором найти другие записи, что открывает дверь для атаки по перебору (IDOR – Insecure Direct Object Reference).

Чтобы избежать этого, можно применить шифрование ID с помощью симметричного алгоритма, например AES. Это не просто "маскировка", а полноценное преобразование, которое нельзя расшифровать без ключа.

Принцип работы

  1. ID пользователя (или массива ID) превращается в строку.
  2. Она шифруется с использованием алгоритма AES-256-CBC.
  3. В качестве дополнительной защиты используется случайный вектор инициализации (IV), который объединяется с зашифрованными данными.
  4. Полученная строка кодируется в base64 для безопасной передачи в URL.

На выходе мы получаем токен, который невозможно расшифровать без знания ключа и алгоритма.

Реализация: метод encryptId()


public static function encryptId($ids)
{
    $key = self::KEY;

    // 1. Подготовка данных: если массив — объединить через запятую
    $data = is_array($ids) ? implode(',', $ids) : (string)$ids;

    // 2. Генерация случайного IV (16 байт для AES-256-CBC)
    $iv = random_bytes(16);

    // 3. Шифрование данных
    $encrypted = openssl_encrypt($data, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);

    // 4. Склейка IV + шифртекст и кодирование в base64
    return base64_encode($iv . $encrypted);
}

Каждый вызов создаёт разный токен, даже для одного и того же ID, за счёт случайного IV.

Расшифровка: метод decryptToken()


public static function decryptToken($token)
{
    $key = self::KEY;

    // Декодируем GET-строку и base64
    $token = urldecode($token);
    $token = str_replace(' ', '+', $token);
    $raw = base64_decode($token, true);

    if ($raw === false || strlen($raw) < 17) {
        return null;
    }

    // Извлечение IV и зашифрованного текста
    $iv = substr($raw, 0, 16);
    $encrypted = substr($raw, 16);

    // Расшифровка
    $decrypted = openssl_decrypt($encrypted, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);

    if ($decrypted === false) {
        return null;
    }

    // Разделение обратно в массив или число
    $ids = array_map('intval', explode(',', $decrypted));
    return count($ids) === 1 ? $ids[0] : $ids;
}

Этот метод «понимает», была ли изначально передана одна ID или массив, и возвращает корректный тип.

Применение


// Зашифровать ID
$token = MyHelper::encryptId(123); // → безопасный токен

// Использовать токен в URL
echo '<a href="/user/view/?id=' . urlencode($token) . '">Открыть профиль</a>';

// При загрузке страницы
$id = MyHelper::decryptToken($_GET['id']);

Безопасность

  • Используется AES-256-CBC, один из самых безопасных симметричных алгоритмов.
  • IV генерируется случайно каждый раз, что исключает повторяемость результата.
  • Без ключа (KEY) расшифровка невозможна.
  • Ключ должен быть надёжным (32 байта) и храниться безопасно (например, в .env или wa-config).

Вывод

Шифрование ID — это простое, но эффективное средство защиты от перебора и утечки внутренней структуры базы данных. Использование encryptId() и decryptToken() позволяет надёжно скрыть реальные идентификаторы пользователей при передаче данных через URL, JavaScript и API.