民航离港系统数据加密实战:数据库TDE与信息系统安全保护合规
某中型机场的一次数据安全自查,卡在一张很常见的表上:离港系统的旅客主表。这张表里有订座编号、旅客姓名、证件号码、联系电话、行程、座位、常旅客号、行李件数,还有一串特殊服务代码——轮椅、无成人陪伴儿童、餐食偏好。检查组问的问题很朴素:这些字段里,哪些是敏感个人信息,各用什么方式保护,谁能看到明文?信息化负责人翻了半天,答案是「整张表按同一个级别管的,能登系统的都能查」。同一周的另一件事更扎心:数据库备份文件被运维拷贝到测试环境做压力测试,测试机上跑的是同一张表的明文副本,而这张表在备份目录里躺了很久,谁拷过、拷到哪,没有一条记录。
坐标先立:交通运输线回线。这条线前六篇分别立了车载信号认证与访问控制、票卡密钥全链路、调度员认证与合规、不停车收费密钥派生、车站系统认证与国密改造、交通运输重要数据分类分级;矿业化工线五篇已收口。这一篇把坐标切回机场旅客服务侧,对象是离港系统(DCS, Departure Control System)的旅客数据——值机、登机、配载、行李这几件事背后的那套高并发事务库。注意两个边界:一是离港是机场旅客服务侧,AOC(航空公司运行控制中心)是航司运行控制侧,两套系统、两类数据,本篇只写离港,AOC 在下一篇单独展开;二是本文讲的是事务型库的加密落点,不是归档库、不是分析库,事务库的约束条件完全不同——延迟预算紧、停机窗口几乎没有、旁路比主链路还多。
01 | 离港库的这件事,难在哪儿
五条难点,每一条都是从「离港是生产系统」这个身份长出来的:
- 延迟预算极紧,加密不能吃掉事务时间。值机、改签、登机都是短事务,一次操作背后是数次读写;航班波一来,柜台、自助机、移动端同时打进来,吞吐峰值集中在起飞前那一两个小时到截载之间。加密动作如果给每次读写加几十毫秒,队列立刻堵住,柜台上表现出来的就是旅客排队变长。所以离港库的加密方案,性能不是加分项,是及格线。
- 停机窗口几乎没有。离港中断直接影响值机与登机,属于一分钟都停不起的系统。任何需要长时间停机切换、需要应用大版本改造的方案,在离港场景里都排不进实施计划。可行的路径只有一条:改造动作必须在业务不感知的前提下灰度完成。
- 数据边界不清,定级先于加密。旅客主表是一张典型的宽表:证件号码、联系电话属于个人敏感信息,行程属于行踪轨迹,特殊服务代码里可能夹带健康信息,而航班号、座位号、行李件数更偏业务运行数据。整张表定一个级别,要么保护过度拖累性能,要么保护不足留下缺口。定级这件事做不完,加密就没有裁剪依据。
- 旁路比主链路多。值机柜台走应用、报表走 BI、数据交换走 ETL、运维走数据库客户端、备份走存储、还有地面服务代理与联程中转的数据接口。主链路加密得再好,只要有一条旁路是明文出口,整条防线就按最短的那块板算。备份文件尤其典型——它天然要脱离生产环境,一旦副本里是明文,生产侧的加密等于白做。
- 密钥体系与生产可用性绑死。事务库加密之后,读数据要先取密钥。密钥服务不可用,值机就读不出旅客信息——密码体系在这里既是保护手段,也成了可用性链路上的一环。这要求密钥服务必须高可用、可降级、可应急,且退役与轮换的动作不能让历史事务变成打不开的死档。
这五条合起来,指向一个落地形态:字段定级先行,落盘加密兜底,旁路一并封堵,密钥体系按生产可用性标准建设。
02 | 机制拆解:三种加密落点怎么选
先说清楚「数据库加密」这个词在离港场景里到底有几种落法,各自的代价是什么。
| 落点 | 应用改造量 | 性能表现 | 能否防住运维旁路 | 覆盖范围 | 实施停机需求 |
|---|---|---|---|---|---|
| 应用层字段加密 | 大,每个读写接口都要改 | 取决于实现,重复加解密常见 | 弱,绕开应用仍见明文 | 只覆盖改造过的字段 | 需要发版窗口 |
| 数据库网关/字段加密网关 | 中,改连接方式 | 多一次网络跳转 | 中,接入网关的流量可控 | 覆盖接入网关的流量 | 需要切流窗口 |
| 驱动层透明加密 | 小,应用无需改造 | 驱动内完成,无额外跳转 | 强,进程与账号双重分级 | 覆盖落盘全量数据 | 可逐台灰度 |
三种落法不是互斥的,实际实施里常常组合:驱动层兜住落盘全量,网关照顾需要字段级保留格式的少数场景,应用层只在极个别字段上做端到端保护。但对离港这种「改不动、停不了」的系统来说,驱动层是主选——它的改造量与停机需求最低,而且它天然站在数据离开内存的最后一站,防的是「文件被拿走」这条最常见的出路。
为什么离港这类事务库更看重驱动层
事务型库和归档库的差别,不在数据量,在访问模式。归档库写一次读少见,加密慢一点没人察觉;事务库是高并发随机读写,每次读写都在关键路径上。驱动层加密的好处是它在文件系统与数据库之间完成加解密,不引入网络跳转,也不要求应用改一行代码——应用以为自己在写明文,磁盘上落的是密文。这样一来,性能预算可以压在驱动内部优化(对称算法、硬件加速、按页粒度)上,而不是花在跨进程通信上。
更关键的是旁路。驱动层天然能看到「是哪个进程在读」,这就给了再一道控制:按进程签名白名单放行,按数据库账号分级返回——业务进程拿明文,运维账号只见密文,未登记进程直接拒绝。这三档是归档库不太需要、事务库非有不可的东西,因为事务库的运维旁路实在太多。
为什么「备份脱离密钥环境不可解」才算真加密
判断一套落盘加密是不是真的有效,有个很朴素的测试:把数据库文件和备份文件整体拷到一台没有任何密钥的机器上,能不能打开?如果能,那这套加密防的只是「在线时被偷看」,防不住「离线时被搬走」。而后者恰恰是离港场景里更常见的风险——备份要异地、要恢复演练、要供测试环境使用,副本数量远多于生产实例。
要做到这一点,密钥必须不在数据库文件里、不在备份文件里、也不在应用配置里,而是由独立的密钥体系持有,按需下发、用完即毁。密文里只留一个密钥版本标识,用来在解密时定位该用哪把工作密钥。这样备份副本无论流到哪,都只是一堆解不开的字节。
┌──────────── 离港系统(DCS)旅客数据面 ────────────┐
值机柜台 ──▶ │ 应用进程 dcs_ckin ──▶ 事务写入 ──▶ 数据库 │
自助设备 ──▶ │ │ (应用无需改造) │ │
登机口 ──▶ │ ▼ ▼ │
│ [驱动层] 落盘即加密 磁盘: 密文+key_id │
│ ▲ │ │
运维账号 ──▶│ 进程签名白名单 + 账号分级 备份/ETL/报表:密文 │
外部脚本 ──▶│ 未登记进程: 拒绝 脱离密钥环境不可解 │
└────────────────────────────────────────────────┘
▲
密钥体系: 根密钥(HSM内) → 工作密钥(版本化)
03 | 先跑通:七个环节
下面这份演示把离港旅客数据的保护链路拆成七个环节跑一遍:字段定级 → 落盘加密 → 账号与进程分级 → 峰值性能约束 → 密钥版本化轮换 → 备份脱离密钥环境 → 审计链不可篡改。用国密 SM2/SM3/SM4,SM2 签名用固定随机数保证结果可复现。
# -*- coding: utf-8 -*-
# 民航离港系统(DCS)旅客数据加密演示(国密 SM2/SM3/SM4)
# 场景:旅客字段分级定档 → 值机事务落盘加密 → 账号与进程分级取数 →
# 峰值事务性能约束 → 事务密钥版本化在线轮换 → 备份脱离密钥环境不可解 → 事务审计链不可篡改
# 说明:同一 SM2 私钥配固定随机数 K 仅为结果可复现;真实系统必须使用随机 K,否则会泄露私钥。
# 演示数据全部为合成数据,与任何真实旅客无关。
import json
import time
from gmssl import sm2, sm3, sm4, func
def sm3h(b: bytes) -> str:
return sm3.sm3_hash(func.bytes_to_list(b))
def digest(b: bytes) -> bytes:
return bytes.fromhex(sm3h(b))
def sm4_enc(k: bytes, b: bytes) -> bytes:
c = sm4.CryptSM4()
c.set_key(k, sm4.SM4_ENCRYPT)
return c.crypt_ecb(b)
def sm4_dec(k: bytes, b: bytes) -> bytes:
c = sm4.CryptSM4()
c.set_key(k, sm4.SM4_DECRYPT)
return c.crypt_ecb(b)
def pad16(b: bytes) -> bytes:
p = 16 - len(b) % 16
return b + bytes([p]) * p
def unpad16(b: bytes) -> bytes:
return b[:-b[-1]] if b and b[-1] <= 16 else b
def try_dec(k: bytes, b: bytes):
try:
return unpad16(sm4_dec(k, b))
except Exception:
return None
def pub_of(p: str) -> str:
return sm2.CryptSM2(private_key=p, public_key="00")._kg(int(p, 16), sm2.default_ecc_table["g"])
def line(t: str, ok: bool):
print(f"[{t}] = {'True' if ok else 'False'}")
K = "20260601123456789abcdef0123456789abcdef0123456789abcdef012345678" # 固定K,仅演示用
# 三类签名主体:离港应用(业务进程登记)、运维平台、外部未登记程序
DCS_P = ("1a2b3c4d5e6f7081" "92a3b4c5d6e7f809" "1a2b3c4d5e6f7081" "92a3b4c5d6e7f809")
OPS_P = ("2b3c4d5e6f708192" "a3b4c5d6e7f8091a" "2b3c4d5e6f708192" "a3b4c5d6e7f8091a")
OUT_P = ("3c4d5e6f708192a3" "b4c5d6e7f8091a2b" "3c4d5e6f708192a3" "b4c5d6e7f8091a2b")
DCS = sm2.CryptSM2(private_key=DCS_P, public_key=pub_of(DCS_P))
OPS = sm2.CryptSM2(private_key=OPS_P, public_key=pub_of(OPS_P))
OUT = sm2.CryptSM2(private_key=OUT_P, public_key=pub_of(OUT_P))
AUDIT = sm2.CryptSM2(private_key=None, public_key=pub_of(DCS_P)) # 审计方只持业务公钥
print("== 环节0:旅客字段分级定档 ==")
LEVEL = {"旅客姓名": "一般", "证件号码": "高敏", "联系电话": "高敏",
"航班行程": "一般", "常旅客号": "一般", "行李件数": "一般"}
HIGH = {k for k, v in LEVEL.items() if v == "高敏"}
line("旅客字段定级表覆盖六类且高敏集合明确",
len(LEVEL) == 6 and HIGH == {"证件号码", "联系电话"})
print("== 环节1:值机事务落盘加密(驱动层透明加密) ==")
ID_NO = "310101199001011234" # 合成演示证件号
ticket = {"pnr": "HD7K9M", "旅客姓名": "张三", "证件号码": ID_NO,
"联系电话": "010-88880000", "航班行程": "PVG-CTU", "座位": "12A",
"ts": 1790000000}
rec = json.dumps(ticket, sort_keys=True, ensure_ascii=False).encode()
K_WORK = bytes.fromhex("a1" * 16) # 工作密钥,由根密钥保护,演示用
ct = sm4_enc(K_WORK, pad16(rec))
line("值机事务落盘为密文,磁盘上检索不到证件号明文",
ID_NO.encode() not in ct and b"12A" not in ct)
line("业务进程读取还原明文,应用侧无感知", try_dec(K_WORK, ct) == rec)
print("== 环节2:账号与进程分级取数 ==")
SIGNED_PROCS = {"dcs_ckin": DCS.sign(digest(b"dcs_ckin"), K),
"dcs_bags": DCS.sign(digest(b"dcs_bags"), K)}
def proc_ok(name: str, sig: str) -> bool:
return name in SIGNED_PROCS and AUDIT.verify(sig, digest(name.encode()))
def read_disk(account: str, name: str, sig: str):
if not proc_ok(name, sig):
return "拒绝"
if account == "app_ckin":
return try_dec(K_WORK, ct)
return ct # 运维类账号只见密文
ops_view = read_disk("ops_admin", "dcs_ckin", SIGNED_PROCS["dcs_ckin"])
line("运维账号读取值机数据只见密文", ops_view == ct and ops_view != rec)
line("未登记进程(后台导出脚本)取数被拒",
read_disk("app_ckin", "etl_probe", OUT.sign(digest(b"etl_probe"), K)) == "拒绝")
line("进程签名不在白名单内的请求校验不通过", not proc_ok("etl_probe", OUT.sign(digest(b"etl_probe"), K)))
print("== 环节3:峰值事务性能约束 ==")
N = 1000
BUDGET = 0.020 # 单笔事务加解密预算 20ms,留足峰值余量
t0 = time.time()
for _ in range(N):
c = sm4_enc(K_WORK, pad16(rec))
try_dec(K_WORK, c)
avg = (time.time() - t0) / N
line("千笔值机事务加解密平均耗时在预算内", avg < BUDGET)
print("== 环节4:事务密钥版本化在线轮换 ==")
KEYRING = {"DEK-2026-08": K_WORK, "DEK-2026-09": bytes.fromhex("b2" * 16)}
CUR = "DEK-2026-09"
def put(tx: dict, kid: str) -> dict:
body = json.dumps(tx, sort_keys=True, ensure_ascii=False).encode()
return {"key_id": kid, "ct": sm4_enc(KEYRING[kid], pad16(body))}
def get(store: dict):
return try_dec(KEYRING[store["key_id"]], store["ct"])
old = put(ticket, "DEK-2026-08")
new = put({"pnr": "PQ3T2X", "旅客姓名": "李四", "航班行程": "CTU-PVG"}, CUR)
line("密文携带密钥版本标识,可定位到具体工作密钥",
old["key_id"] in KEYRING and old["key_id"] != new["key_id"])
line("在线轮换后历史值机事务仍可解(按版本取旧密钥)", get(old) is not None)
line("轮换后新值机事务使用新版本密钥", new["key_id"] == CUR and get(new) is not None)
print("== 环节5:备份脱离密钥环境 ==")
backup = {"key_id": "DEK-2026-08", "ct": ct}
wrong = try_dec(bytes.fromhex("c3" * 16), backup["ct"]) # 换一把密钥去解
line("备份文件脱离密钥环境不可解(结果非原文)", wrong is None or wrong != rec)
line("恢复环境凭密钥体系取回后可解", try_dec(KEYRING[backup["key_id"]], backup["ct"]) == rec)
print("== 环节6:事务审计链不可篡改 ==")
audit = json.dumps({"pnr": ticket["pnr"], "act": "值机", "seat": "12A",
"ts": 1790000000}, sort_keys=True, ensure_ascii=False).encode()
sig = DCS.sign(digest(audit), K)
line("值机操作审计记录签名可验", AUDIT.verify(sig, digest(audit)))
line("改座位号保留原签名后验签失败",
not AUDIT.verify(sig, digest(audit.replace(b"12A", b"12B"))))
== 环节0:旅客字段分级定档 ==
[旅客字段定级表覆盖六类且高敏集合明确] = True
== 环节1:值机事务落盘加密(驱动层透明加密) ==
[值机事务落盘为密文,磁盘上检索不到证件号明文] = True
[业务进程读取还原明文,应用侧无感知] = True
== 环节2:账号与进程分级取数 ==
[运维账号读取值机数据只见密文] = True
[未登记进程(后台导出脚本)取数被拒] = True
[进程签名不在白名单内的请求校验不通过] = True
== 环节3:峰值事务性能约束 ==
[千笔值机事务加解密平均耗时在预算内] = True
== 环节4:事务密钥版本化在线轮换 ==
[密文携带密钥版本标识,可定位到具体工作密钥] = True
[在线轮换后历史值机事务仍可解(按版本取旧密钥)] = True
[轮换后新值机事务使用新版本密钥] = True
== 环节5:备份脱离密钥环境 ==
[备份文件脱离密钥环境不可解(结果非原文)] = True
[恢复环境凭密钥体系取回后可解] = True
== 环节6:事务审计链不可篡改 ==
[值机操作审计记录签名可验] = True
[改座位号保留原签名后验签失败] = True
逐段注解:
- 环节0 是定级。六类旅客字段按敏感程度分成两档,证件号码与联系电话进高敏档,其余为一般档。定级表是后面所有动作的裁剪依据:哪些字段必须密文落盘、哪些字段在报表里必须脱敏、哪些字段能进测试环境,全部由这张表决定。没有这张表,加密就只能全表一个档,性能和保护两头不讨好。
- 环节1 是落盘加密。一条值机事务(订座编号、姓名、证件号、电话、行程、座位)写入前在驱动层完成加密,磁盘上检索不到证件号明文,业务进程读取时还原明文——应用侧对整件事无感知,这正是「事务型库不能改应用」这条约束的解法。
- 环节2 是账号与进程分级。运维账号读同一份数据,拿到的是密文而不是明文;未登记的后台导出脚本请求取数,直接被拒;即使自报进程名,进程签名不在白名单内的请求同样校验不通过。这三档对应离港场景里最现实的三条旁路:有权限的运维、无权限的脚本、冒充业务进程的外部程序。
- 环节3 是性能约束。连续千笔值机事务的加解密平均耗时控制在预算内。这一段在演示里只是一行断言,在现场却是方案能不能上的决定性证据——建议直接在准生产环境按航班波的峰值并发压一遍,取 P99 而不是平均值,再决定是否全量铺开。
- 环节4 是密钥版本化轮换。密文里只带一个密钥版本标识,轮换后按版本取旧密钥,历史值机事务照常可解;新事务自动使用新版本密钥。注意这里和归档库的做法不同:事务库不能停,所以轮换是「在线加版本」,不是「停机重加密」。旧版本密钥在确认没有事务引用后才退役。
- 环节5 是备份。用错误的密钥去解备份文件,解出来的不是原文;凭密钥体系取回正确密钥后,恢复环境可以正常解密。这一条是整个方案的底线测试——它回答的是「数据被搬走之后还安不安全」。
- 环节6 是审计链。值机操作形成审计记录并整体签名,签名可验;把座位号从 12A 改成 12B 但保留原签名,验签失败。「谁在什么时间办了什么」由此从一条日志变成一条能自证的证据。
验证点:现场演示时按「定级表 → 落盘密文 → 三档取数 → 峰值压测 → 在线轮换 → 备份离线测试 → 审计验签」的顺序调出来。最有说服力的三个画面:在磁盘文件里 grep 证件号返回空(回应「加密到底加在哪」)、运维账号查询返回密文(回应「有权限的人能不能看」)、把备份文件拷到无密钥机器打不开(回应「数据被搬走怎么办」)。演示用固定随机数保证结果可复现;正式签发时随机数必须由安全模块内部生成,同一私钥配相同随机数会泄露私钥。
04 | 落地动作:分三条线怎么做
离港旅客数据保护按三条线推进,每条线配一个可对照的整改样本。
线一:字段分级与范围界定(对应定级底账)
- 动作:把离港系统的旅客相关表全部过一遍,按字段而不是按表定级,形成「字段—级别—保护措施」底账;据此确定哪些字段密文落盘、哪些字段在报表与测试环境必须脱敏或置换、哪些字段保留明文;数据保留策略一并落到字段级,联程与中转场景需要的保留期限单独标注。
- 整改样本(背景→动作→结果):某机场旅客主表 30 多个字段全部按同一级别管理,报表明文导出无限制 → 按字段定级,证件号码与联系电话定为高敏,行程按行踪轨迹处理,报表侧统一脱敏、测试环境一律置换 → 高敏字段的暴露面从「全表可见」收敛到「业务进程可见」。
- 注意:定级底账要跟着业务变化走。新增一个联程产品、接一家地面服务代理,都会带进新字段;底账不更新,新字段就是默认无保护。
线二:落盘加密与旁路封堵(对应驱动层)
- 动作:在数据库主机上部署驱动层透明加密,落盘即密文、读取即解密,应用无需改造;同步配置进程签名白名单与数据库账号分级——业务进程明文、运维账号密文、未登记进程拒绝;把备份、ETL、报表、数据交换这几条旁路逐条纳入,要么走受控通道,要么拿到的是密文。
- 整改样本:某机场生产库已加密,但备份目录里的副本是明文,测试环境长期用真实数据 → 把备份纳入密钥体系,副本全程密文,测试环境改用置换后的数据集 → 生产与备份两侧的保护强度拉齐。
- 注意:旁路清单要按「数据实际流向」而不是「系统架构图」来列。架构图上没有的那条运维手动导出,往往是最常用的一条。
线三:密钥体系与业务连续性(对应 KSP 底座)
- 动作:根密钥在硬件密码机内生成与使用、永不导出;工作密钥由根密钥保护、按版本管理、在线轮换;密钥服务按生产系统标准部署多节点,密钥下发链路冗余;制定密钥服务不可用时的应急流程,并定期演练;密钥的生成、使用、轮换、退役全程留痕,评估时直接出证。
- 整改样本:某企业(非民航)的加密库在密钥服务单点故障期间整库不可读,业务中断数小时 → 密钥服务改多节点热备并加应急流程,演练时主动切断主节点验证切换 → 同类故障下的恢复时间从小时级降到分钟级。
- 注意:密钥体系的可用性等级要等同于它所保护的业务的可用性等级。保护一个一分钟停不起的系统,就不能用一个可以慢慢修的密钥服务。
三条线的推进顺序:先做定级底账(线一),它是裁剪依据;再做落盘加密与旁路封堵(线二),它把保护面铺满;最后收密钥体系与连续性(线三),它决定这套加密能不能长期稳定地跑下去。最常见的反向坑是先买一套加密产品直接上生产——没有定级表,全表一个档;没有旁路清单,加密了主库漏了备份;没有密钥高可用,某次密钥服务抖动直接变成一次生产事件。
05 | 避坑清单:8 条最容易踩的坑
| # | 坑 | 后果 | 怎么验证避开了 |
|---|---|---|---|
| 1 | 只加密生产库,备份与 ETL 是明文 | 数据从副本侧流出 | 拷一份备份到无密钥机器尝试打开 |
| 2 | 不做字段定级,整表一个档 | 保护不足或性能被拖垮 | 查定级底账是否按字段而非按表 |
| 3 | 性能只看平均延迟 | 峰值时段柜台排队变长 | 按峰值并发压测取 P99 |
| 4 | 进程白名单只登记不校验签名 | 冒充业务进程即可取明文 | 用未签名进程发起请求,应被拒 |
| 5 | 运维账号保留明文权限 | 有权限的人直接看全量 | 运维账号查高敏字段,应返回密文 |
| 6 | 密钥轮换不版本化 | 历史事务变成打不开的死档 | 轮换后随机抽历史事务解密 |
| 7 | 密钥服务单点部署 | 密钥不可用导致整库不可读 | 主动切主节点验证切换时间 |
| 8 | 加密后审计记录仍可改 | 事后追责无据 | 改一条审计记录保留原签名,验签应失败 |
挑第 6 条展开:密钥版本化是事务库最容易在设计阶段被漏掉的一环。归档库的思路是「保存期内留重叠窗口」,事务库不能照搬——它没有停机窗口,轮换必须在线完成,而在线轮换意味着同一时刻库里存在用多把密钥加密的数据。如果密文里不留版本标识,解密时就不知道该取哪把密钥,最坏的结果是轮换之后一部分历史事务读不出来。验证方法很朴素:每次轮换后,随机抽取轮换前不同时段的事务各解一次,全部可解才算轮换完成;确认没有事务引用旧版本后,才允许旧密钥退役。
06 | 合规视角:要对上哪些要求
- 网络安全等级保护(GB/T 22239-2019):离港系统通常按三级定级。涉及数据的控制点集中在数据完整性与保密性、剩余信息保护、个人信息保护几处——密文落盘对应保密性,审计记录签名对应完整性,账号与进程分级对应剩余信息保护。本文不重复展开等级保护的框架本身。
- 个人信息保护法:身份证件号码、行踪轨迹、通信联系方式属于敏感个人信息,需要单独的处理规则与更强的保护措施。离港场景里,行程与证件号天然属于这一类;这意味着「整表一个档」在合规上也站不住,必须做到字段级区分。
- GB/T 35273《信息安全技术 个人信息安全规范》:给出了个人信息的分类与安全措施要求,可作为定级底账的参照口径。
- 密码法与商用密码应用安全性评估:真实性靠签名、保密性靠加密、密钥受控靠密钥管理体系。离港库上的密码应用是这三件事的组合,评估时按应用与数据层面的要求逐项对应。
- 民航行业信息系统安全保护相关要求:民航对信息系统的安全保护有专门的行业要求口径,涉及旅客服务系统的可用性、数据保护与应急处置。这类要求按现行版本执行即可,本文不引具体文号——行业文件更新较快,引文号容易失真,实施时以主管部门现行有效版本为准。
- 港口等交通枢纽的信息化安全标准:港口客运与货运信息化的数据保护口径与机场侧相近,同样强调生产系统连续性与旅客/货主信息保护,做集团型交通枢纽的可以合并建一套定级口径。
审查实操上,离港系统被问得最多的是三件事:旅客敏感信息在哪些地方以明文存在、备份和副本有没有一起管、谁能看到明文且有没有记录。这三问分别对应落盘加密与旁路封堵、备份纳入密钥体系、账号与进程分级加审计。把「字段定级底账 + 密钥版本台账 + 取数审计记录」一起调出来,举证会顺畅很多。证据留存统一四要素:时间、账号、数据对象、结论。
一句话边界:离港旅客数据保护是「生产连续性约束下的加密工程」——保护强度要够,但不能以牺牲值机与登机的连续性为代价;这两个目标不冲突,前提是加密落点选对、旁路封堵做全、密钥体系按生产标准建设。
07 | 落地答案:产品怎么承接
把三条线的动作翻译成落地组件,产品以「答案」身份出现,能力作主语:
- 驱动层透明加密(TDE):在数据库主机驱动层完成落盘加密与读取解密,应用无需改造,覆盖 MySQL、Oracle、PostgreSQL、SQL Server、达梦、人大金仓等常见库;按进程签名白名单与数据库账号分级控制取数——业务进程明文、运维账号密文、未登记进程拒绝;加密在驱动内完成,不引入网络跳转,性能损耗可控,适配离港这类延迟敏感的事务库。
- 密钥底座(KSP):根密钥在 HSM 内生成与使用、永不导出,工作密钥由根密钥保护、按版本管理、在线轮换;密文只带版本标识,历史事务按版本取旧密钥解密,轮换不停机;密钥服务多节点部署,密钥的生成、使用、轮换、退役全程留痕,评估时直接出证。这一层把「密钥体系与生产可用性绑死」这个风险点接住。
- 统一身份与访问(ASP):值机、登机、配载、行李各系统的操作账号收敛到统一身份平台,一人一账号、双因素登录、按角色授权、审计到人;运维侧的临时权限带时限、带审批、带回收。这一层解决「谁能看明文」的归因问题。
- 审计与留痕:值机、改签、登机、导出等操作形成审计记录并签名入链,四要素齐全,改一条验签即失败;审计记录与密钥操作记录可交叉核对,回溯时既能查「谁改了数据」,也能查「谁用了哪把密钥」。
这些组件的关系:透明加密管「落盘不可见」,密钥底座管「密钥可控可轮换」,统一身份管「谁能操作」,审计留痕管「事后能查」。机场侧按三条线(字段分级与范围界定 / 落盘加密与旁路封堵 / 密钥体系与业务连续性)逐项对上,即为离港旅客数据从定级到加密到连续运行的落地全路径。
08 | 验收清单与下一步
离港旅客数据保护 验收清单
| 检查项 | 对应要求 | 验证点 | 是否落地 |
|---|---|---|---|
| 字段级定级底账 | 个人信息保护 | 底账按字段而非按表,高敏集合明确 | □ |
| 高敏字段密文落盘 | 数据保密性 | 磁盘文件中检索不到证件号明文 | □ |
| 业务进程无感知 | 应用无需改造 | 应用未改代码,读取还原明文 | □ |
| 运维账号只见密文 | 剩余信息保护 | 运维账号查高敏字段返回密文 | □ |
| 未登记进程被拒 | 最小权限 | 未签名进程请求取数被拒 | □ |
| 峰值性能达标 | 生产连续性 | 峰值并发下 P99 在预算内 | □ |
| 密钥版本化轮换 | 密钥生命周期 | 轮换后历史事务全部可解 | □ |
| 备份脱离环境不可解 | 数据保密性 | 无密钥机器打开备份失败 | □ |
| 密钥服务高可用 | 业务连续性 | 主节点故障切换在分钟级 | □ |
| 审计记录不可篡改 | 数据完整性 | 改记录保留原签名验签失败 | □ |
趋势上,机场旅客数据的保护口径会从「系统级合规」走向「字段级举证」:旅客信息服务越做越细,字段只会越来越多、跨系统流转只会越来越频繁,检查问的也会从「你们加密了吗」变成「这个字段为什么是明文、谁能看、有没有记录」。另一个方向是生产连续性会被摆到更前面——越是关键的信息系统,越不允许用停机换安全,能在业务不感知的前提下完成加密改造,本身就是一种能力。
下一篇预告:离港是机场旅客服务侧,AOC 是航司运行控制侧——下一篇《民航AOC系统安全实战:签名验签与等保合规落地》,把坐标系换到航班运行指令,讲放行、改航、配载调整这类运行控制数据的签发主体绑定、指令完整性、越权拦截与防重放,以及运行控制场景下「可用性优先」怎么与「验签失败即拒」共存。
文章作者:安当加密-焱垚,安全工程师,专注身份认证、数据加密领域。

371

被折叠的 条评论
为什么被折叠?



