跳转至

Gerege eID —— 标识符(ETSI ID 与登记号)

系统中有两个用于标识个人 / 组织的主要号码:ETSI 标识符(证书中的标准键) 与登记号(РД)(蒙古国公民号)。本文说明二者的结构与含义。


1. ETSI 标识符 —— etsi_identifier

ETSI = European Telecommunications Standards Institute(欧洲电信标准协会)。我们的 etsi_identifierETSI EN 319 412-1 标准中的 “semantics identifier”, 也就是将国家号码写入证书的国际标准格式。它符合 eIDAS,并与爱沙尼亚 Smart-ID 的 semanticsIdentifier 在协议层兼容(我们在其基础上做了适配)。

格式

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 能够识别。
  • 类型内嵌于前缀: PNONTR 区分自然人与组织 → 用于自动选择签发 CA (domain.SubjectTypeForEtsi,Personal/Organization CA)。
  • 内部取值为 civil_id(仅数字)而非 РД: 证书的 SERIALNUMBER 字段是 X.509 PrintableString,无法容纳西里尔字母的 РД。因此自然人取 PNOMN-<civil_id>etsi = "PNOMN-" + civilID);РД 是 users 表中的独立属性,不会写入证书。

代码位置:persistence.UserAccount.EtsiIdentifierdomain.SubjectTypeForEtsicrypto_wired.go 中的 ETSI 构造("PNOMN-" + civilID)。


2. 登记号(РД)—— registration_number

蒙古国公民的登记号2 个西里尔字母 + 8 位数字(例如 УБ95103015)。

结构(名义上)

У Б 9 5 1 0 3 0 1 5
└┬┘ └──────┬──────┘
 │         └── 8 位数字(名义上为 YYMMDD + 顺序号)
 └── 父名与本名的首字母(2 个)

出生日期 / 性别 —— 来源与从 РД 推导

date_of_birthgender 首先直接来自 KYC 核验方(DAN/eMongolia)service.KycResult.DateOfBirth.Gender;经 DAN 回调通过 NormalizeGender 处理)。

部分来源(G-Sign)不会返回这些字段 —— 证书 subject 只提供身份信息。这种情况下, 系统会从 РД 推导util.BirthAndGenderFromRegNogsign/kycverifier.go): - 日期: 前 6 位数字 = YYMMDD。月份为 21..32 → 2000 年之后(年份 2000+YY,月份 MM-20); 月份为 01..12 → 2000 年之前(年份 1900+YY)。若为无效日历日期 → nil。 - 性别: 倒数第 2 位为奇数 → "M",偶数 → "F"(与日期无关)。

若数字缺失或格式错误,则各自留空(nil/"")—— 留空胜过错误的猜测。


3. 其他相关号码

字段 说明 来源
civil_id 公民身份证号(不必与 РД 一致) KYCKycResult.CivilID
组织登记号 法人的国家登记 → etsi NTRMN-<...>organizationIdentifier(OID 2.5.4.97) KYCKycResult.OrgRegister
document_number 每台设备的唯一 UUID(不含 РД —— 保护隐私)。即 Smart-ID 的 documentNumber 由服务端生成
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_idgiven_namesurnamefull_name

操作 规则 实现
存储 trim + lower(小写规范形式) util.NormalizeIdentity;recordUserAndCert;KYC normalizeRegNo=lower
检索 / 查找 / 比较 先将输入规范化为小写再比较(不区分大小写) pg FindByIdentifier/Search reg_no → lower;inmem 已为小写;DAN 回调匹配为 lower-lower
展示 РД → 大写util.DisplayRegNo);西里尔姓名 → Title Caseutil.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 / 证书拥有各自的规范形式,因此不受本规则约束。