欢迎光临
我们一直在努力

水务SCADA密钥管理实战:操作员UKEY双因子认证与水务燃气统一密钥平台落地

在水司调度中心,“操作员登录 SCADA"往往是最先被等保、密评复查按下去的一环:几台操作员站共用一个账号、口令写在显示器边框上、夜班交接从不退出。真出了"误开阀门”"越权投加药"这类事,日志里只查得到账号,查不到人。

这不是管理糙不糙的问题,是审查口径明确卡着:

  • 等保 2.0 三级(GB/T 22239—2019,安全计算环境·身份鉴别):应采用口令、密码技术、生物技术等两种或两种以上组合的鉴别技术对用户进行身份鉴别,且其中一种至少应使用密码技术来实现;
  • 密评(GB/T 39786—2021,应用和数据安全层面 8.4 a):应采用密码技术对登录用户进行身份鉴别,保证应用系统用户身份的真实性(三级为"应"级要求)。

注意一个常被误读的坑:短信验证码不是密码技术,"口令+短信"过不了"至少一种使用密码技术"这条。供水这类城市生命线系统又往往被纳入关键信息基础设施(CII)运营者范畴,身份真实性、操作可追溯只会越查越严。

而 SCADA 场景还有一条硬约束:鉴别必须发生在操作员站本身登录的那一刻——只在前端挂一台堡垒机做双因子,挡不住绕开堡垒机的本地登录,被评测评测时照样不合规。

工控/水务场景下把"密码技术这一种"落得最顺的,就是 UKEY 挑战-应答签名认证:人持一把智能密码钥匙(UKEY),私钥锁在 Key 的安全芯片里,服务端发一次性随机挑战,Key 在芯片内完成 SM2 签名,服务端用这把 Key 在统一密钥平台登记的证书公钥验签。

本文按罗升阳式"一条链拆到底"的思路,从操作员插 Key 登录 SCADA 的那一刻追起:①挑战为什么必须一次性 → ②PIN 和 Key 各管哪一半 → ③私钥怎么做到"不出 Key"还完成签名 → ④服务端凭什么验 → ⑤审计怎么闭环,最后落到"水务燃气统一密钥平台"——因为单看一次登录不够,全公司每把 Key 的公钥、证书、吊销、换人,必须有个统一的地方管。

阅读路径:坐标系 → 链路全貌 → 可复现跑链 → 机制"为什么" → 信任源 → 同平台复用 → 现场自查 → 系列预告。

01 | 先立坐标系:SCADA 安全域里,登录是"人与设备"的接缝

一张图看水务 SCADA 的安全域,人和系统的第一次交汇点就在登录:

水司/燃气 SCADA 安全域(示意)

┌─────────────────────────────┐
值班员/调度员 ──►│ 操作员站(HMI/工程师站) │──► SCADA 服务端
(人) │ Windows 工控机 / 瘦客户端 │ 数据采集/下发
插 UKEY │ 本地登录 = 鉴别发生点 │
输 PIN └─────────────────────────────┘
▲ │
│ 人等保/密评盯得最紧的接缝: ▼
│ "人→操作员站"这一次登录 营收/生产数据库

整张图里,"人 → 操作员站"这半米,是人这个不可信主体进入可信工控网络的入口关卡,也是身份真实性、双因子、审计三件事的交点。它身后的 SCADA 服务端、数据库、泵站通信各自有各自的密钥问题(后文 06 复用表会串起来),本文先把"人登录"这条链挖穿。

一个必须对齐的口径:等保原文写的是"两种或两种以上组合的鉴别技术",不是"两个口令/两张卡"。判定落到三类认证要素里至少取两类:

要素例子属性
你知道的 口令、PIN 可被撞库/钓鱼/键盘记录
你持有的 UKEY、智能卡、令牌 物理持有,丢了就丢
你特有的 指纹、人脸 生物特征

其中"至少一种用密码技术实现"这一步,UKEY(含 SM2 数字证书/密钥对、私钥不出硬件的智能密码钥匙)正好是等保测评里认可的"密码技术"载体——它比动态口令更能抗重放,也比口令能扛住"操作员站被种木马"这种工控区常见的现实威胁。这正是本文要拆到芯片层的机制。

02 | 一条链拆到底:挑战-应答登录的五环

把"插 Key 登录成功"这一个动作,拆成下面五环。逐环盯住一个问题:这一环在防谁、靠什么防。

先列攻击者会打这半米登录链的几种常见招,读五环时对号入座:

攻击攻击者拿到了什么被哪一环挡下
截获重放 一次登录的(挑战,签名) 第 1 环随机挑战 + 第 4 环台账:签名不可搬运、不可二次消费
中间人劫持 正在传输的挑战与签名 签名只对服务端签发的那个挑战有效,报文被改一个字节验签即败
口令被撞库/钓鱼 操作员的用户名+口令 第 2 环持有要素兜底:没有 Key 内签名过不了第 4 环验签
木马偷私钥 操作员站硬盘上的密钥文件 第 3 环:私钥在芯片里,硬盘上根本没有
拖库服务端 服务器/数据库里的凭据 第 5 环:服务端只存公钥,拖走也伪造不了登录
捡到/偷到 Key 一把 UKEY 硬件 第 2 环 PIN 门禁 + 04 节的锁定与吊销

操作员站(客户端) SCADA 服务端 统一密钥平台(KSP)
│ │ │
│ ①请求登录 │ │
│ ───────────────────────────────────────►│ │
│ │ 生成一次性随机挑战 challenge│
│ ②下发挑战 │ (绑定会话,不可预测) │
│ ◄───────────────────────────────────────│ │
│ ③PIN解锁→Key内SM2签名 │ │
│ (私钥不出芯片) │ │
│ ④提交 挑战+签名 │ │
│ ───────────────────────────────────────►│ ⑤验签:用 KSP/CA 登记的 │
│ │ 公钥验签,查防重放台账 │
│ │ 通过→建会话→审计留痕 │

第 1 环,挑战下发:一次登录一个随机挑战。
服务端不要求口令走网络,而是先给一个"一次性随机挑战"。挑战的作用是让后面那句签名绑定到"这一次登录":签名只对这一个挑战有效,换一个挑战就对不上。挑战由服务端真随机生成、用后即弃,攻击者没法预判、也没法拿旧签名套用。

第 2 环,PIN 解锁:你知道的那一半。
操作员插上 UKEY 后要输 PIN。PIN 不是"第二口令",而是解锁签名私钥的门禁——UKEY 的签名命令只在 PIN 校验通过后才放行,连错会被锁定(错误码 9004)。

第 3 环,Key 内签名:私钥不出芯片的那一步。
这是整条链的机制核心,放 03/04 两节专门展开。这里先记住结论:SM2 私钥从生成到销毁都只在 UKEY 安全芯片内,签名命令进去的是待签摘要、出来的是签名值,私钥本身对外不可见。

第 4 环,提交与防重放:签名绑定挑战。
客户端把"挑战 + 签名"交回服务端。服务端验签前先查两件事:挑战是不是本次签发的、有没有被用过。攻击者截获了上一会话的(挑战,签名)也没用——本次挑战变了,旧签名验不过;即便攻击者原样重放本次的(挑战,签名),服务端的挑战台账也会拦下第二次。

第 5 环,验签与审计:只验公钥,不碰私钥。
服务端用该操作员在统一密钥平台登记的证书公钥验签,签名有效且挑战匹配才建立会话,并把"谁、何时、哪台操作员站、验签结果"写入审计。服务端全程没有、也不需要私钥——这就让"攻击服务端=拿到全部登录凭据"这件事在结构上不成立。

把五环压成一张表,正好回答评审最爱问的一句"这一环到底在防谁、靠什么防":

环动作防谁靠什么
1 挑战下发 服务端生成一次性随机挑战 重放、预判 真随机、会话级、用过即弃
2 PIN 解锁 输 PIN 通过才放行签名命令 捡到/偷到 Key 的人 "你知道的"作门禁
3 Key 内签名 SM2 私钥在芯片内签 SM3(挑战) 私钥被复制、被拖库 私钥永不出芯片
4 提交验签 服务端用登记的证书公钥验签 冒名登录 签名绑定一次性挑战
5 审计 人/时间/站点/结果写日志 事后赖账、无法溯源 全程留痕可追责

03 | 跑一遍这条链:可复现的 python 演示

把上面五环落成一段可运行的最小演示。真实环境里 SM2 私钥生成并锁在 UKEY 芯片内、不可导出,下面的 PRIV 只是为了演示可复现——产品里你根本拿不到这段私钥,这恰恰就是"私钥不出 Key"要表达的机制本身。

# -*- coding: utf-8 -*-
# 水务 SCADA 操作员登录:UKEY 挑战-应答签名认证机制演示
# 真实环境里 SM2 私钥生成并锁在 UKEY 安全芯片内、不可导出;PIN 是解锁这道门禁。
# 下面的 PRIV 只是为了演示可复现 —— 产品里你根本拿不到这段私钥,这正是"私钥不出 Key"。
from gmssl import sm2, sm3

# —- 统一密钥平台(KSP/CA)发证时登记的只有公钥;私钥在 UKEY 内 —-
PRIV = "58e2a3f5c1d4b7a90f6e8d2c4b1a7f3e9c0d5b8a1f2e4c6d8a0b3c5d7e9f1a3b"
K_FIX = "6b1d3e5f708192a3b4c5d6e7f8091a2b3c4d5e6f708192a3b4c5d6e7f8091a2b" # 演示固定K,输出可复现

ukey_sk = sm2.CryptSM2(private_key=PRIV, public_key="00" * 64) # 只在 UKEY 芯片内存在
pub_hex = ukey_sk._kg(int(PRIV, 16), sm2.default_ecc_table["g"]) # 发证时派生出公钥
server = sm2.CryptSM2(private_key="00" * 64, public_key=pub_hex) # 服务端只持公钥

def digest(msg: bytes) > bytes:
return bytes.fromhex(sm3.sm3_hash(list(msg))) # 国密 SM3 摘要(32B)

def ukey_sign(pin_ok: bool, data: bytes):
if not pin_ok: # 真实 UKEY:VerifyUserPIN 失败返回 9004,签名命令被拒
return None # 错 PIN -> 不产出任何签名
return ukey_sk.sign(data, K_FIX) # 私钥在芯片内完成 SM2 签名,永不出芯片

print("[① 挑战下发] 服务端为本次登录生成一次性随机挑战(用过即弃)")
ch_now = "scada-session-9f6c1e2d-b7a8" # 本次挑战;演示固定值便于复现
print(" challenge =", ch_now)
used = set() # 挑战台账:记录已成功提交过的挑战

print("[② PIN 解锁] 操作员输入 PIN,VerifyUserPIN 通过")
sig = ukey_sign(True, digest(ch_now.encode()))

print("[③ 芯片签名] UKEY 内 SM2 私钥对 SM3(挑战)签名,私钥不离开芯片")
print(" signature =", sig[:48] + "…")

print("[④ 服务端验签] 用平台登记的该操作员公钥验签(服务端永远碰不到私钥)")
ok = server.verify(sig, digest(ch_now.encode()))
used.add(ch_now)
print(" verify =", ok, " -> 认证通过,建立会话,本次挑战记账")

print("[⑤ 防重放·旧签名] 攻击者把上一会话截获的 signature 拿到本次登录来用")
ch_old = "scada-session-3a1b9c0d-7788" # 上一会话的挑战
sig_old = ukey_sign(True, digest(ch_old.encode())) # 上一会话:同一把 Key 签的旧签名
ok2 = server.verify(sig_old, digest(ch_now.encode()))
print(" 用本次挑战验旧签名 =", ok2, " -> 挑战不匹配,拒绝")

print("[⑥ 防重放·同挑战重放] 攻击者把本次(挑战+签名)原样再提交一次")
ok3 = server.verify(sig, digest(ch_now.encode()))
hit = ch_now in used
print(" 数学上验签通过 =", ok3, ",但台账命中 =", hit, " -> 拒绝放行")

print("[⑦ 错 PIN] 攻击者猜错 PIN,VerifyUserPIN 返回 9004")
bad = ukey_sign(False, digest(b"000000"))
print(" UKEY 不产出签名 -> 服务端未收到签名 =", bad is None, " -> 拒绝")

print("[⑧ 审计留痕] 2026-09-03 09:03:07 | 张师傅 | 泵站3号操作员站 | verify=True")

把文件存成 d31_scada_login.py 直接跑,输出与下面一致(私钥、K、挑战全部写死,每次运行结果相同,可当场复验):

[① 挑战下发] 服务端为本次登录生成一次性随机挑战(用过即弃)
challenge = scada-session-9f6c1e2d-b7a8
[② PIN 解锁] 操作员输入 PIN,VerifyUserPIN 通过
[③ 芯片签名] UKEY 内 SM2 私钥对 SM3(挑战)签名,私钥不离开芯片
signature = 4eb3e8eb73d747801283f940f7ce7e81459bcf7d7c834275…
[④ 服务端验签] 用平台登记的该操作员公钥验签(服务端永远碰不到私钥)
verify = True -> 认证通过,建立会话,本次挑战记账
[⑤ 防重放·旧签名] 攻击者把上一会话截获的 signature 拿到本次登录来用
用本次挑战验旧签名 = False -> 挑战不匹配,拒绝
[⑥ 防重放·同挑战重放] 攻击者把本次(挑战+签名)原样再提交一次
数学上验签通过 = True ,但台账命中 = True -> 拒绝放行
[⑦ 错 PIN] 攻击者猜错 PIN,VerifyUserPIN 返回 9004
UKEY 不产出签名 -> 服务端未收到签名 = True -> 拒绝
[⑧ 审计留痕] 2026-09-03 09:03:07 | 张师傅 | 泵站3号操作员站 | verify=True

逐句对着跑,注解三处关键设计:

  • 第 ②→③ 行,ukey_sign 里 if not pin_ok: return None:签名命令被 PIN 门禁挡着,错 PIN 连签名都不会产生——服务端"没收到签名"和"验签失败"是两种状态,前者连猜的机会都不给。真实 UKEY 上对应 VerifyUserPIN 失败返回 9004,连续错会锁定。
  • 第 ④ 行 verify = True:服务端拿到的只有 pub_hex,PRIV 从头到尾只在 ukey_sk(模拟的"芯片内")里出现过一次。能验签的前提是服务端持公钥,而公钥永远推导不出私钥——这是公钥密码与对称口令最本质的区别。
  • 第 ⑤⑥ 行两个 False/拒绝:一次签名只绑定一个挑战。⑤ 是"旧签名拿到新会话",挑战对不上,验签本身失败;⑥ 是"同一(挑战,签名)原样重放",数学上验得过去(True),但挑战台账发现已被使用,拒绝放行。两条防线缺一不可:随机挑战让签名不可搬运,台账让同一挑战不可二次消费。

验证点①(认证链路成立):④ 打印 verify = True。
验证点②(签名绑定挑战,防搬运):⑤ 打印 用本次挑战验旧签名 = False。
验证点③(挑战一次性,防重放):⑥ 打印 台账命中 = True -> 拒绝。
验证点④(PIN 门禁):⑦ 打印 UKEY 不产出签名 -> 服务端未收到签名 = True。

**真实环境里,这条链长在操作员站的本地 2300 服务上。**SCADA 客户端是非浏览器的 C/S 程序,接 UKEY 一般通过本机 RESTful 中间件(127.0.0.1:2300)完成:客户端依次调 VerifyUserPIN(验 PIN,过第 2 环门禁)、GetECCSignData(把待签摘要送进 Key,让私钥在芯片内签名)、ExportECCPublicKey(发证/登记时导出公钥)。联调期记住三个错误码就能定位九成问题,它们正好对应第 2 环门禁的三个状态:

9001 未认证 -> 还没验 PIN,先别急着签名
9002 未插入 -> 这台操作员站根本没插 Key(或没读到)
9004 PIN 错误 -> 门禁没开,签名命令被拒(连续错会锁定)

04 | 为什么私钥必须"锁在 Key 里":机制层的三个为什么

看完跑通,回到机制层把三个"为什么"讲透,这是被测评问到时必须能说清的部分。

为什么不能让操作员站存私钥?
操作员站是 Windows 工控机,常年暴露在被植入木马、被 U 盘拷走文件、被远程桌面连过的环境里。如果 SM2 私钥以文件形式躺在硬盘上,木马扫一遍就能偷走,之后攻击者可以在任何机器上冒充这个操作员——你鉴别到的"身份"其实已经复制了。私钥一旦不可复制,偷走 Key 原件也还要过 PIN,偷走 PIN 也没有私钥,两层必须同时到手,攻击成本才真正抬起来。

为什么私钥在芯片里还能"签名"?
这正是智能密码钥匙的设计点:签名命令把待签摘要送进芯片,芯片用内部私钥算出签名值再送出来,私钥本身不参与任何对外 I/O。等保测评认可的"密码技术实现双因子",认的正是这条——UKEY 内是国密 SM2 密钥对、可配套 SM2 数字证书,属于基于公钥密码算法的数字签名机制(GB/T 39786 8.4 明确列出的实现方式之一)。而短信验证码不在这类里,因为它没有用到密码算法做鉴别。

为什么服务端只需要公钥?
SM2 签名(GB/T 32918)的性质是:私钥签名、公钥验签、不可逆。所以服务端和数据库里可以只存"哪个操作员对应哪个公钥",即使整个 SCADA 服务端被攻破,攻击者拿到的也只是一堆公钥,伪造不了任何一次登录。把秘密集中在用户手里的 Key 里、而不是集中在服务端的库里,是这条链比口令体系更抗拖库的结构性原因。

**那 Key 丢了、被偷了呢?**机制也要在设计上给答案,否则"持有"这一要素本身就成了风险源:

  • 连错 PIN:UKEY 自动锁定,后续签名命令全部拒绝——偷到 Key 没有 PIN 也白搭;
  • 平台吊销:操作员报失后,KSP 侧吊销其证书,服务端再验签即拒绝,丢失窗口被压到"报失之前";
  • 补发重绑:补发新 Key、重新出证、旧证书彻底作废,全程在平台留痕;
  • 追溯兜底:丢 Key 期间若已有可疑登录,第 5 环的审计日志能把时间、站点、验签结果翻出来定责。

这一节回答的是"机制本身怎么防止秘密泄露",下一节看"这些公钥、证书、吊销,由谁来统一可信地管"。

05 | 信任源从哪来:统一密钥平台(KSP)在链里的位置

操作员登录验签要用公钥,但"公钥"不是凭空来的——它必须有一个可信来源登记、签发、吊销。这就是统一密钥平台要回答的问题,也是标题里"统一密钥平台"落地的位置。

先看水司/燃气企业现实的痛点:钥匙是散的。

  • SCADA 操作员每人一把 UKEY,各自找厂商灌,没有统一的身份登记;
  • 有人调岗、离职,UKEY 收回来但公钥还在服务端白名单里,人走了身份没走;
  • 营收/生产数据库的加密密钥、泵站 PLC 的通信密钥又各是各的一套,没人说得清全公司有多少密钥、谁在用、何时该轮换;
  • 等保/密评要"密钥全生命周期管理 + 全程审计",散管状态下根本交不出账。

把信任源统一起来,链路上每个角色各管各的、各有所持:

统一密钥平台 KSP(信任根/账本)
┌────────────────────────────────────────────┐
│ HSM 硬件加密机:根密钥 KEK 在机内,永不明文导出 │
│ 内置 CA 组件:给每把 UKEY 的公钥签 SM2 证书 │
│ 登记+吊销:谁在用哪把 Key、是否有效,一查便知 │
│ 全量审计:密钥生命周期操作全程留痕 │
└────────────────────────────────────────────┘
▲ 登记/吊销 │ 下发放行(公钥/证书状态)
│ ▼
UKEY(私钥在芯片) SCADA 服务端(验签时向平台核对该操作员公钥与证书状态)

平台侧做的,是密钥管理三件事:

  • 身份登记:发 UKEY 时,由 KSP 内置 CA 给每把 Key 里的 SM2 公钥签证书/登记在案,人和 Key 一一绑定;
  • 信任源:SCADA 服务端验签用的公钥与证书状态来自平台,操作员调岗/离职,平台侧吊销即全局失效,不用去每台服务端手改白名单;
  • 生命周期与审计:密钥的生成、使用、轮换、归档、销毁都受平台策略管理,全程留痕——这正是密评"密钥管理"与等保"审计"要求要交的账。
  • **走一遍"调岗"场景,看信任源怎么生效:**值班员调去别的厂,管理员在 KSP 把该操作员的证书置为"吊销"。他原来的 UKEY 再插到任意操作员站,客户端照常发起登录,服务端向平台核对该公钥状态得到"已吊销",走不到放行——不用跑到每台 SCADA 服务端手工删白名单。换到新岗位则补发新 Key、重新绑定岗位权限。整个过程里,"人 → Key → 公钥 → 权限"四者的绑定关系只在一处维护,散管时代"人走了身份没走"的洞就堵上了。

    底座是 HSM 硬件加密机:KSP 的三级密钥体系里,根密钥(KEK)存在 HSM 内、永不明文导出,工作密钥由 KEK 加密保护,会话密钥用后即销毁。也就是说,不只是一次登录的验签公钥,整个水务燃气企业要用到的密钥,最后都收束在一个受硬件密码机保护的信任根上——这就是"统一密钥平台"和"散落各系统自管"的本质区别。

    补充一个结构事实:一次登录验签时服务端要的只是"该操作员公钥/证书当前是否有效",真正的高价值秘密(签名私钥、根密钥)一个在 UKEY 芯片、一个在 HSM 机内,都不在网络可达的服务器上。威胁模型里"打穿调度中心能不能伪造登录"这条线,被这两道硬件边界截断了。

    工控隔离网下,吊销状态怎么做到"当时生效"?调度中心常在隔离网段,SCADA 验签服务不能指望每次登录都连公网或总部在线查一次证书状态。落地时由平台把吊销名单(CRL/证书状态)周期同步到区内验签节点,服务端验签前先查本地状态再放行——所以"换人后多久失效"取决于同步周期,这一条要在整改时就与测评师对齐口径,而不是上线后才被问住。

    06 | 同一个平台、同一条链,还能接什么

    "统一"的价值在于复用:水司/燃气企业里凡是"要证明一个人或一台设备是谁、密钥要有人管"的场景,都能挂到同一套信任源上,而不是每家系统自建一堆钥匙。下表把登录链延伸到其它场景(星号 * 为预告篇,后续单独展开):

    场景认证/保护对象链路上的位置能承接的部分
    SCADA 操作员站登录(本篇) 值班员/调度员 人→操作员站,挑战-应答验签 UKEY(私钥在芯片)+ KSP 内置 CA 发证登记
    调度门户/Web 系统、VPN/堡垒机远程接入 运维/管理人员 同一把 UKEY 作第二因子 ASP 统一认证收口(SSO/MFA/RADIUS)复用 UKEY
    生产/营收数据库落盘 数据 存储机密性(GB/T 39786 8.4 e) KSP 管理工作密钥 + TDE 透明加密
    泵站 PLC / 远传通道通信 设备/链路 传输机密性与真实性 KSP 设备密钥分级管理,HSM 兜底
    燃气门站、加臭系统操作认证 * 燃气线人员与设备 同类人+Key 链路 同 UKEY + KSP/ASP,详见 D3-2/D3-3
    智能水表/燃气表密钥注入 * 计量设备 产线烧录到抄表全链路 密钥平台统一分发,详见 D4-2(CJ/T 188)

    这张表的另一面是给整改交账:等保/密评复查时,"身份怎么鉴别、密钥谁在管、审计留没留"不再是每个系统各答各的,而是一条链路、一个账本、一次讲清。

    换个角度,“统一"本身就是在消灭三类重复建设:重复发证(每个系统各给各的 Key 灌身份)、重复审计(各自记各自的日志,拼不成一条完整操作链)、重复密钥堆(人的、库的、设备的各成一套体系)。信任源收口到一处之后,新上一个 SCADA 系统要做的只是"接到平台的证、用平台验的签”,而不是再从零搭一套钥匙体系。

    07 | 现场自查:怎么当场证明做对了

    评审现场不讲 PPT,讲验证。照着下面逐项过,就是这条链"做对了"的可执行证据:

    □ 换人即失效:操作员离职,平台吊销其证书后,该 UKEY 再登录被拒
    (看服务端日志:verify 返回 False 或提示证书已吊销)
    □ 挑战不重样:连登两次,抓包或看服务端日志,两次 challenge 不同
    □ 防重放生效:把某次登录的(挑战,签名)原样重放,第二次被台账拦截
    □ 错 PIN 无签名:连错 PIN,服务端收到的是"无签名/锁定",不是一次验签失败
    □ 服务端无秘密:检查 SCADA 服务端与数据库,只存公钥/证书,找不到任何私钥文件
    □ 审计可追溯:登录记录能答出"谁、何时、哪台操作员站、验签结果"

    代码侧的自查命令,把上面的 python 存成 d31_scada_login.py 后一行跑完:

    # 四个断言全命中 = 认证通过 / 旧签名被拒 / 同挑战重放被台账拦下 / 错PIN无签名
    python3 d31_scada_login.py | grep -E "verify = True|验旧签名 = False|台账命中 = True|未收到签名 = True"

    期望命中四行,正是 03 节输出里的 ④⑤⑥⑦ 四行。

    真正测评时,测评师会额外盯这几个点,整改阶段提前对齐能少走一轮复测:

    • 身份鉴别是否发生在操作员站本身的登录上(而不是只在堡垒机/网关做了双因子,本地登录绕得过);
    • 日志能否对每一次登录给出"人 + Key + 站点 + 验签结果",而不是只有账号;
    • 服务端与数据库里是否真的不存在私钥(现场可要求查文件与配置);
    • 密钥生命周期是否有平台统一管理,并能当场出示审计记录。

    08 | 系列预告与收尾

    本文是账号"公共事业(水务·燃气)"知识线的第一篇,先把"人登录 SCADA"这条链讲穿;线内后续还会继续往下铺:

    • D3-2 燃气工控:燃气门站/SCADA 操作员认证与身份管理——同一条 UKEY 链在燃气侧的落地差异;
    • D4-1 水务密评三级:自来水厂等保与密评的区别与关键点,把 01 节两张合规口径展开成整改路径;
    • D4-2 智能水表密钥注入:CJ/T 188 数据安全与水表产线密钥烧录,把 06 表里"设备密钥"那格填满。

    回看交通线,这套"统一信任源"的思路和我们在《ETC 密钥管理:部省两级派生到车道注入》(D2-1)里拆的部省密钥体系、《轨道交通信号系统 ATS 认证》(D2-2)里拆的车地双向认证是一脉相承的:凡是要长期可信的鉴别,就得有可复现的机制、硬件封存的秘密、和一处统一的信任源——UKEY 把秘密锁进芯片,KSP/HSM 把信任根立起来,服务端只验公钥、只记审计。对水司来说,这既是等保三级双因子和 GB/T 39786 身份真实性这两条硬要求的答案,也是"出了事查得到人"的兜底。


    文章作者:安当加密-焱垚

    赞(0)
    未经允许不得转载:171主机测评 » 水务SCADA密钥管理实战:操作员UKEY双因子认证与水务燃气统一密钥平台落地
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址