年龄检查已经从一个勾选框变成了一项工程任务。在英国,《2023 年网络安全法》(Online Safety Act)要求部分服务使用“高度有效”的年龄检查。在欧盟,欧盟委员会发布了一份蓝图,让用户无需交出任何其他信息即可证明自己已满 18 岁。两者都把身份证件列为途径之一。

这篇文章写给被要求“加上年龄核验”、想弄清证件扫描处于什么位置的开发者。它介绍英国和欧盟主管机构列出了哪些方法,扫描护照或身份证能证明什么、不能证明什么,如何把出生日期转换成“已满/未满”的结论,以及核验之后应该保留什么。下文所有引文都出自主管机构自己的页面,并在出现处附有链接;引文保留英文原文,后面附简短译文。

这里是 doc.cheap 的博客。doc.cheap 是一个护照与身份证 OCR API。阅读产品相关部分时请记住这一点。

英国:门槛是“高度有效”

这项义务规定在《2023 年网络安全法》第 12 条中。对于危害最大的几类内容,服务提供者必须 "use age verification or age estimation (or both) to prevent children of any age from encountering primary priority content that is harmful to children"(使用年龄验证或年龄估计,或两者兼用,防止任何年龄的儿童接触到对儿童有害的首要优先内容)。而且这项检查必须 "of such a kind, and used in such a way, that it is highly effective at correctly determining whether or not a particular user is a child."(其类型和使用方式能够高度有效地正确判断某个用户是否为儿童)。

第 230 条定义了这两个术语。年龄验证 "means any measure designed to verify the exact age of users"(指任何旨在验证用户确切年龄的措施),适用于受该法管辖的服务。年龄估计 "means any measure designed to estimate the age or age-range of users"(指任何旨在估计用户年龄或年龄段的措施)。它还堵住了最省事的捷径:"A measure which requires a user to self-declare their age (without more) is not to be regarded as age verification or age estimation."(仅要求用户自行申报年龄的措施,不视为年龄验证或年龄估计。)

英国通信监管机构 Ofcom 在其针对第 3 部分服务的高度有效年龄保证指南中解释了这一门槛(更新版的日期为 2025 年 4 月 24 日)。第 3 节给出了 "a non-exhaustive list"(一份非穷尽的清单),列出它认为能够做到高度有效的方法:

Ofcom 清单上的方法 是否涉及身份证件
开放银行 否
照片证件(photo-ID)比对 是,证件就是证据
人脸年龄估计 否
移动网络运营商年龄检查 否
信用卡检查 否
基于电子邮件的年龄估计 否
数字身份服务 常常涉及,在首次核验身份时

Ofcom 这样描述照片证件比对:它 "works by capturing relevant information from an uploaded photo-ID document and comparing it to an image of the user at the point of ID upload to verify that they are the same person."(从上传的照片证件中采集相关信息,并与上传证件时拍摄的用户图像进行比对,以确认二者是同一个人。)

同一节也列出了不合格的做法,其中包括 "asking a user to input their date of birth without further evidence to confirm this information"(要求用户输入出生日期,却没有进一步的证据加以确认)。手动输入的出生日期属于自行申报。从证件上读出的出生日期才是证据,而 Ofcom 指南的其余部分讲的就是这份证据需要达到什么水平。

欧盟:以年龄证明为基础的蓝图

在欧盟方面,欧盟委员会于 2025 年 7 月 14 日发布了年龄核验蓝图的第一版。用它自己的话说,该蓝图 "provides a method to enable users to prove they are over 18 when accessing restricted adult content, such as online pornography, without revealing any other personal information."(提供一种方法,让用户在访问受限成人内容(例如网络色情内容)时证明自己已满 18 岁,而不透露任何其他个人信息。)

这一设计把检查与使用分开。用户的 "age will be verified by the issuer using detailed personal data, like the date of birth. However, online services will only receive a proof that the user is over 18, without any other personal details."(年龄将由签发方利用出生日期等详细个人数据进行核验,但在线服务只会收到用户已满 18 岁的证明,不含任何其他个人信息。)

身份证件出现在第一步。欧盟委员会的蓝图说明页把年龄证明的来源列为 "national eIDs, passports and ID cards, pre-installed apps with age info, such as banking apps, or offline third-party activation, such as post office."(国家电子身份、护照和身份证、带有年龄信息的预装应用(例如银行应用),或线下第三方激活(例如邮局)。)它还补充道:"In October 2025, a second version of the blueprint was released with a passport and identity card method to generate a proof of age."(2025 年 10 月,蓝图发布了第二版,加入了用护照和身份证生成年龄证明的方法。)

所以在这两个地方,证件都是被认可的输入。但在任何一处,单独一张证件照片都不是完整的检查。

扫描能证明什么,不能证明什么

证件扫描能很好地回答一个问题:这份证件上写的是什么?它读出出生日期、有效期、证件类型和机读区(MRZ),还能告诉您机读区的校验位是否对得上。这就是 Ofcom 描述中“采集相关信息”的那一部分。

它回答不了年龄检查必须覆盖的其他问题:

  • 这个人是持证人吗? Ofcom 的稳健性一节点出了最直接的绕过方式:"a child user uploading an image of an ID that does not belong to them."(儿童用户上传一张不属于自己的证件图像。)它给出的对策是:"Requiring a photo of the user at the point of ID upload when photo-ID matching helps to verify that the photo ID belongs to that user."(在照片证件比对中,要求用户在上传证件时拍摄本人照片,有助于确认该照片证件属于该用户。)
  • 这个人在场吗? "Liveness detection provides further confidence that a child user has not uploaded a photo of an adult by ensuring that the user undergoing the age assurance process is present at the time the check is carried out."(活体检测通过确认接受年龄保证流程的用户在检查进行时确实在场,进一步确保儿童用户没有上传成年人的照片。)
  • 证件是真的吗? "A robust photo-ID check should not be capable of being easily circumvented, and as such, a photo-ID method should be able to detect falsified documentation or manipulation that a child could create or obtain."(稳健的照片证件检查不应被轻易绕过,因此照片证件方法应当能够发现儿童可能制作或获得的伪造证件或篡改。)

这些都不是 OCR。读取证件和核验证件是两项不同的工作,由不同的工具完成,而基于证件的年龄检查两者都需要。读取这一步给您关于证件的可靠数据;人脸比对、活体检测和真伪检查则告诉您能否信任这份证件和这个人。

从出生日期到“已满”或“未满”

读出出生日期之后,年龄计算虽然简单,却很容易出错。只把年份相减是不够的:2008 年 11 月 20 日出生的人,在 2026 年 11 月 10 日是 17 岁,而不是 18 岁。月份和日期也要比较。

from datetime import date


def age_on(birth_iso: str, on: date) -> int:
    """Whole years completed on the day `on`, from a YYYY-MM-DD date of birth."""
    born = date.fromisoformat(birth_iso)
    years = on.year - born.year
    if (on.month, on.day) < (born.month, born.day):
        years -= 1  # the birthday has not come yet this year
    return years


def is_over(birth_iso: str, threshold: int, on: date) -> bool:
    return age_on(birth_iso, on) >= threshold


print(age_on("2008-11-20", date(2026, 11, 10)))     # 17
print(is_over("2008-11-20", 18, date(2026, 11, 20)))  # True

实际使用中有几个细节很重要:

  • 使用检查当天的日期,并固定一个时区。 在午夜前后,服务器的“今天”和用户的“今天”可能不同。选定一条规则,并记录您所用的日期。
  • 2 月 29 日。 按上面的比较方式,2 月 29 日出生的人在非闰年于 3 月 1 日长一岁。如果您所在的司法管辖区另有规定,修改这一个分支即可。
  • 缺少日期不是答案。 如果扫描没有返回出生日期,结果应是“无法检查”,绝不能是“已满 18 岁”。
  • 有效期是另一个问题。 过期证件能否作为证据,属于您自己的政策,所以要读出有效期并明确做出决定。

保留结论,而不是证件

欧盟委员会的设计只向服务发送 "only a proof that the user is over 18"(仅证明用户已满 18 岁)。同样的思路也适用于您自己的系统:检查完成后,您需要的结果是一个布尔值和一个日期,而不是一张护照图像。

Ofcom 的隐私一节也指向同一方向。它提醒服务提供者 "All age assurance methods involve the processing of personal data and should follow a data protection by design approach"(所有年龄保证方法都涉及处理个人数据,应遵循设计即保护数据的方法),并把数据最小化和存储限制列为应遵循的原则。

一条最小记录如下:

{
  "user_id": "u_3f9c",
  "check": "age_over_18",
  "result": true,
  "checked_on": "2026-11-10",
  "method": "photo_id_matching"
}

没有图像,没有证件号码,没有出生日期。如果法律要求您保留更多内容,就只保留法律要求的那些,放在一个单独的存储中,并设定它自己的删除日期。

doc.cheap 的定位

doc.cheap 读取护照、身份证和驾驶证,并把印刷内容以 JSON 返回。对年龄检查而言,有用的字段是 holder.birth_date(ISO 格式的 YYYY-MM-DD 日期或 null),以及 document.expiry_date、document.is_expired 和 mrz.status,所以您传给 age_on 的日期来自一次可以自行复核的读取。

它是识别服务,不是核验服务。在仅识别场景下,响应中的 authenticity.overall 为 not_checked,人脸比对和活体检测交给专门的工具。它也不保留您没有要求保留的任何内容:在正式密钥上设置 retain_hours: 0 时根本不会写入任何记录,详见历史记录保留指南。图像本身从不存储。

想在设计其余部分之前先试一试读取这一步,可以从免费护照 OCR API开始。如果您正在挑选服务商,护照 OCR API 对比把各家公开的价格并排列出。

本文是工程层面的总结,不构成法律意见。

**最后一个问题:**在您的年龄检查中,哪一部分花了最长时间才做对:读取、人脸比对,还是保留的记录?欢迎在下方评论区告诉我们。