Skip to content

API Верификации ПД

Добро пожаловать в документацию API верификации паспортных данных (ПД). В данном руководстве описаны порядок работы с API, процесс шифрования данных, структура запросов и примеры реализации на PHP.


Оглавление

  1. Шифрование данных
  2. Описание алгоритма шифрования
  3. Процесс шифрования
  4. Пример реализации шифрования на PHP
  5. Пример запроса
  6. Документация API Verify

Шифрование данных

В API верификации ПД используется комбинированное шифрование для защиты передаваемых данных.
Основной алгоритм для шифрования данных — AES-128-CBC, а симметричный ключ дополнительно шифруется с помощью асимметричного алгоритма RSA (с использованием публичного ключа, предоставленного поставщиком API).


Описание алгоритма шифрования

  • Шифрование данных:
    Данные (например, паспортные данные) зашифровываются симметричным алгоритмом AES-128-CBC. Для этого необходимо:
  • Сгенерировать 16-байтовый ключ.
  • Использовать вектор инициализации (IV).

  • Шифрование симметричного ключа:
    Сгенерированный симметричный ключ шифруется с помощью RSA с использованием публичного ключа (формат OpenSSH). Результат шифрования кодируется в base64 и передаётся в параметре secret.

  • Порядок действий:

  • Сгенерировать симметричный ключ (AES-128-CBC).
  • Зашифровать все передаваемые данные симметричным ключом.
  • Зашифровать симметричный ключ с помощью публичного RSA ключа.
  • Кодировать зашифрованный симметричный ключ (secret) в base64 и добавить его к остальным данным запроса.

Процесс шифрования

  1. Преобразование данных:
    Необходимые параметры (например, паспортные данные) преобразуются в строку.

  2. Шифрование данных:
    Строка шифруется симметричным алгоритмом AES-128-CBC с использованием сгенерированного ключа и вектора инициализации (IV).

  3. Шифрование ключа:
    Сгенерированный симметричный ключ шифруется с помощью RSA с использованием предоставленного публичного ключа.
    Результат шифрования кодируется в base64 и передаётся в параметре secret.

  4. Формирование запроса:
    Зашифрованные данные и ключ включаются в тело запроса в формате JSON.


Пример реализации шифрования на PHP

<?php
require_once('./vendor/autoload.php');

use phpseclib3\Crypt\RSA;
use phpseclib3\Crypt\RSA\PublicKey;

/**
 * Класс шифрования
 */
class Encrypter
{
    /**
     * Поддерживаемые шифры
     */
    public const SUPPORTED_CIPHERS = [
        'aes-128-cbc' => ['size' => 16, 'aead' => false],
    ];

    /**
     * @param string $key Симметричный ключ шифрования
     * @param string $cipher Используемый шифр
     *
     * @throws \Exception Вызывается если не поддерживается переданный шифр или не подходит ключ
     */
    public function __construct(
        private readonly string $key,
        private readonly string $cipher = 'aes-128-cbc'
    ) {
        if (!$this->checkSupportedCipher()) {
            $supportedCiphers = implode(', ', array_keys(self::SUPPORTED_CIPHERS));
            throw new \Exception(
                'Unsupported cipher or incorrect key length. Supported ciphers are: ' . $supportedCiphers
            );
        }
    }

    /**
     * Проверка на поддержку шифра и соответвии ему ключа
     *
     * @return bool true - поддерживает, false - не поддерживает
     */
    private function checkSupportedCipher(): bool
    {
        return (isset(self::SUPPORTED_CIPHERS[$this->cipher]))
            && mb_strlen($this->key, '8bit') === self::SUPPORTED_CIPHERS[strtolower($this->cipher)]['size'];
    }

    /**
     * Шифрует указаную строку используя ключ и шифр, указанные при создании объекта
     *
     * @param string $value
     * @return string Зашифрованная строка
     */
    public function encrypt(string $value): string
    {
        $iv = random_bytes(openssl_cipher_iv_length(strtolower($this->cipher)));
        $value = openssl_encrypt(
            $value,
            strtolower($this->cipher),
            $this->key,
            0,
            $iv,
            $tag
        );

        $iv = base64_encode($iv);
        $tag = base64_encode($tag ?? '');
        $mac = self::SUPPORTED_CIPHERS[strtolower($this->cipher)]['aead']
            ? ''
            : hash_hmac('sha256', $iv . $value, $this->key);

        $json = json_encode(compact('iv', 'value', 'mac', 'tag'), JSON_UNESCAPED_SLASHES);

        return base64_encode($json);
    }

    /**
     * Сгенерировать ключ для симметричного шифрования
     *
     * @param string $cipher Шифр
     * @return string Ключ
     */
    public static function generateKey(string $cipher): string
    {
        return random_bytes(self::SUPPORTED_CIPHERS[strtolower($cipher)]['size'] ?? 16);
    }
}

Пример запроса

URL:

https://verify.promotivation.ru/api/v1/verification/data/

Заголовки:

Authorization: Bearer {токен}
Content-Type: application/json

Тело запроса:

{
  "name": "Иван",
  "patronymic": "Иванович",
  "surname": "Иванов",
  "birthdate": "01.01.1991",
  "inn": "123456789012",
  "series": "1234",
  "number": "123456",
  "issueDate": "20.01.2011",
  "issuedWhom": "УФМС России по НСО",
  "registrationAddress": "г. Новосибирск, ул. Советская, д.15, кв.15",
  "file1": "base64_кодированное_изображение",
  "file2": "base64_кодированное_изображение",
  "consent": true,
  "secret": "Зашифрованный симметричный ключ в base64"
}