Gerege eID — идентификаторы (ETSI ID и регистрационный номер)¶
В системе есть два основных номера для идентификации человека или организации: ETSI-идентификатор (стандартный ключ в сертификате) и регистрационный номер (РД) (монгольский номер гражданина). Этот документ описывает их структуру и назначение.
1. ETSI-идентификатор — etsi_identifier¶
ETSI = European Telecommunications Standards Institute. Наш etsi_identifier — это
«semantics identifier» по стандарту ETSI EN 319 412-1, то есть
международный стандартный формат записи национального номера в сертификат. Он соответствует
eIDAS и совместим на уровне протокола с semanticsIdentifier эстонского Smart-ID (мы его адаптировали).
Формат¶
PNOMN-95103015
└┬┘└┬┘ └───┬──┘
│ │ └── сам номер (для физлица — civil_id, только цифры, не РД)
│ └── страна — ISO 3166-1 alpha-2 (MN = Монголия)
└── тип субъекта (3 символа)
| Префикс | Значение | Владелец | Пример |
|---|---|---|---|
| PNO | Person Number (национальный персональный номер) | физическое лицо (Natural Person) | PNOMN-95103015 |
| NTR | National Trade Register | организация (Legal Person) | NTRMN-1234567 |
Зачем¶
- Стабильный ключ: устройства / сертификаты / сессии каждого гражданина связываются именно этим ID
(
users.etsi_identifier— первичный ключ). - Соответствие стандартам: это принятый способ записи национального ID в квалифицированный eIDAS-сертификат; европейские RP его понимают.
- Тип зашит в префиксе:
PNO↔NTRразличают физлицо и организацию → используется для автоматического выбора выпускающего CA (domain.SubjectTypeForEtsi, Personal/Organization CA). - Внутреннее значение =
civil_id(только цифры), а не РД: поле сертификатаSERIALNUMBER— это X.509 PrintableString, поэтому оно не может содержать кириллический РД. Отсюда физлицо получаетPNOMN-<civil_id>(etsi = "PNOMN-" + civilID); РД — отдельный атрибут вusers, в сертификат он НЕ попадает.
В коде:
persistence.UserAccount.EtsiIdentifier,domain.SubjectTypeForEtsi, формирование ETSI вcrypto_wired.go("PNOMN-" + civilID).
2. Регистрационный номер (РД) — registration_number¶
Регистрационный номер гражданина Монголии: 2 буквы кириллицы + 8 цифр (например, УБ95103015).
Структура (номинально)¶
У Б 9 5 1 0 3 0 1 5
└┬┘ └──────┬──────┘
│ └── 8 цифр (номинально ГГММДД + порядковый номер)
└── первые буквы имени отца и собственного имени (2)
Дата рождения и пол — источник и вывод из РД¶
date_of_birth и gender в первую очередь приходят напрямую от поставщика KYC (DAN/eMongolia)
(service.KycResult.DateOfBirth, .Gender; из callback DAN через NormalizeGender).
Некоторые источники (G-Sign) их не возвращают — subject сертификата даёт только идентичность.
В этом случае система выводит их из РД (util.BirthAndGenderFromRegNo, gsign/kycverifier.go):
- Дата: первые 6 цифр = ГГММДД. Месяц 21..32 → после 2000 года (год 2000+ГГ, месяц ММ-20);
месяц 01..12 → до 2000 года (год 1900+ГГ). Некорректная календарная дата → nil.
- Пол: 2-я цифра с конца нечётная → "M", чётная → "F" (независимо от даты).
Если цифры отсутствуют или искажены, каждое значение остаётся пустым (nil/"") —
пустое лучше, чем неверная догадка.
3. Другие связанные номера¶
| Поле | Описание | Источник |
|---|---|---|
civil_id |
Номер удостоверения личности гражданина (может не совпадать с РД) | KYC (KycResult.CivilID) |
| Регистрационный номер организации | Государственная регистрация юрлица → etsi NTRMN-<...>, organizationIdentifier (OID 2.5.4.97) |
KYC (KycResult.OrgRegister) |
document_number |
Уникальный UUID каждого устройства (не содержит РД — приватность). Это documentNumber из Smart-ID | генерируется сервером |
certificates.serial_number |
Серийный номер X.509 (десятичный); в OCSP/CRL — шестнадцатеричный | CA |
Принцип: атрибуты идентичности гражданина/организации (civil_id, регистр организации, имя) всегда приходят от поставщика KYC (DAN/eMongolia) — их не выводят и не выдумывают из номеров. Если источник ничего не дал, значение остаётся пустым. (Дата рождения и пол обычно приходят из KYC, но если источник их не возвращает — выводятся из РД, см. §2.)
Итог¶
- ETSI-идентификатор = «стандартный формат записи национального номера в сертификат»
(
PNOMN-…— физлицо,NTRMN-…— организация). Название непривычное, но смысл простой. - РД = номер гражданина вида «2 буквы + 8 цифр». Дата рождения и пол обычно приходят
напрямую из источника KYC; иначе выводятся из РД (
util.BirthAndGenderFromRegNo).
§Case — ПРАВИЛО регистра для текста идентичности¶
Правило: каноническая форма текста идентичности в БД — НИЖНИЙ РЕГИСТР; любой поиск, фильтрация и сравнение выполняются в нижнем регистре; отображение — в стандартной форме. Пользователь может вводить регистрационный номер в любом регистре.
Охваченные поля (текст идентичности, введённый человеком или полученный из KYC):
users.registration_number (РД), civil_id, given_name, surname, full_name.
| Действие | Правило | Реализация |
|---|---|---|
| Сохранение | trim + lower (каноническая форма в нижнем регистре) | util.NormalizeIdentity; recordUserAndCert; KYC normalizeRegNo=lower |
| Поиск / выборка / сравнение | привести ввод к нижнему регистру, затем сравнивать (без учёта регистра) | pg FindByIdentifier/Search reg_no → lower; inmem уже в lower; сопоставление в callback DAN lower-lower |
| Отображение | РД → ВЕРХНИЙ РЕГИСТР (util.DisplayRegNo); имя на кириллице → Title Case (util.TitleCaseName) |
PersonBlock, PersonSummary, admin userView, предпросмотр KYC |
НЕ охвачено (имеет собственную каноническую форму протокола/PKI — не трогать):
- etsi_identifier — канон ETSI EN 319 412-1 (PNOMN-…/NTRMN-…); выборка/сравнение в ВЕРХНЕМ РЕГИСТРЕ.
- SERIALNUMBER / subject DN сертификата, given_name_latin/surname_latin — ICAO/eIDAS ВЕРХНИЙ РЕГИСТР.
- document_number (UUID), хеш API-ключа, org_register организации (цифры), name организации (имя собственное).
Почему: каждый источник KYC возвращает свой регистр (DAN «ЭРДЭНЭБАТ», G-Sign «баярсайхан»), а пользователь пишет РД как «УБ…» или «уб…». С единой канонической формой (нижний регистр) выборка и дедупликация работают последовательно; для отображения значение приводится к стандартной форме. У латиницы / etsi / сертификата собственный канон, поэтому это правило на них не распространяется.