身份认证凭据管理系统

身份认证凭据管理系统

身份认证凭据管理系统,要回答的不是「把口令、令牌、证书收在一个库里」,而是「一次认证到底动用了哪些凭据、按什么规则取、取的时候怎么校验、用完怎么留痕」。某平台上线统一认证时碰到过这样一件事:运维排查一次「明明输对了口令却登不进」的故障,翻了半天才发现,那次登录除了口令还要过一道设备证书,而设备证书早已到期------口令与证书分属两个小组管,谁也没把「这次登录要动用几类凭据」这件事写在一处。

坐标先立:《中华人民共和国密码法》与《商用密码管理条例》对商用密码的使用与密钥管理提出要求;GB/T 22239-2019《信息安全技术 网络安全等级保护基本要求》在身份鉴别里要求身份标识与主体一一对应、口令具备复杂度并定期更换、采用两种或两种以上组合的鉴别技术时应有一种为密码技术;GB/T 39786《信息安全技术 信息系统密码应用基本要求》把密钥的产生、存储、分发、使用、销毁纳入密码应用要求;GB/T 20518《信息安全技术 公钥基础设施 数字证书格式》给出证书这一形态凭据的结构要求。本文切入的是最容易被拆到两个小组的那一块:一次认证要用到的凭据,能不能被编排在一处。

01 | 身份认证凭据管理系统,难在哪儿

身份认证凭据管理系统,难点很少出在「能不能存」,多半出在「一次认证要动用几类凭据、谁说了算」。下面五处最常被检查点到。

首要难在凭据目录缺失。 哪个场景该用口令加第二个因素、哪个场景该用客户端证书、哪个场景该用一次性令牌,往往散在不同人的经验里,没有一份目录。结果是同一个场景在不同系统里用了不同强度的凭据,出了事谁也说不清「这里本该用哪一类」。这套编排要做的头一件事,就是先把场景与凭据的对应关系写成一份目录。

其次难在每类凭据的校验方式不同,却按一套流程处理。 口令是「比摘要」,令牌是「一次性应答」,证书是「验签名」。三者的校验逻辑完全不同,用一套「取出来比对一下」的流程去套,必然有一类做不到位------口令或许还行,令牌和证书就形同虚设。登录认证中如何应用凭据管理系统,最容易被省略的正是「每类凭据各自怎么校验」这一节。

再有一处难在时效被忽略。 口令有更换周期、令牌是一次一用、证书有有效期、票据有到期时间。四类凭据的时效口径各不相同,只要有一类没被检查,「过期的东西还能用」就会成为一条长期存在的口子。身份认证中如何应用凭据管理系统,时效线是四条线里最不起眼、也最容易漏的一条。

第四处难在使用没有留痕。 谁在什么场景、用哪一类凭据、认证结果是放行还是拒绝,这些在不少系统里查不到,或者只留下一个无主体的计数。检查方要复算一次认证用了哪些凭据时,团队只能回去翻日志再靠人脑拼。把凭据管住之后,还要回答「凭据是怎么被用的」。

最后一处难在几类凭据各管一段、互不对话。 口令在一处、证书在一处、令牌在另一处,各自维护、各自校验,登录时再把它们临时拼起来。这种拼法在平时看不出问题,一旦要加一类新凭据或调整某类凭据的策略,就要同时改三处,还要保证三处的时间表一致。收敛到一套目录与一本台账,是这件事最难、也最有价值的一段。

把这五处串起来看,核心矛盾是:认证要的是「一次登录用哪几类凭据、每类怎么验、过期没过期、谁用的」,而现实给的往往是「凭据分别存在几处、用时临时拼」。

02 | 机制拆解:身份认证凭据管理系统的四条线

身份认证凭据管理系统,落到机制上其实是四条线的编排:目录线、校验线、时效线、留痕线。四条线回答四个不同的问题,缺一条就会在某一类追问上卡住。

线 回答的问题 推进方式 缺了会怎样
目录线 哪个场景用哪类凭据 场景与凭据的对应表 同类场景强度不一
校验线 每类凭据各自怎么验 按类型定校验方式 令牌证书形同虚设
时效线 过期没过期怎么判 按类型定时效口径 过期凭据还能用
留痕线 谁用哪类凭据怎么核 使用记录整体签名 来龙去脉查不到

四条线的边界要讲清楚:目录线管的是「该用哪一把锁」,校验线管的是「这把锁怎么开」,时效线管的是「这把锁什么时候作废」,留痕线管的是「谁动过这把锁」。四者要落在同一本认证台账上------目录决定校验方式,校验通过后才谈时效,时效与结果一并进留痕。把四条线并到一处,就是这套编排方法最容易被忽略的底稿:先定场景与凭据的对应表,再谈用哪套工具。

身份认证凭据管理系统:目录线

目录线要回答的是「哪个场景用哪类凭据」。做法是把认证场景列出来,逐个定它该用的凭据类型:控制台登录用口令加第二个因素,服务间调用用客户端证书,一次性链接用令牌,高风险操作再用密钥对做一次性挑战-应答。目录要能机器读取、要能落到策略里,而不是写成一份供人查阅的说明;未列入目录的场景默认拒绝,而不是默认放行。身份认证中如何应用凭据管理系统,第一步就是把这份目录立起来。

身份认证凭据管理系统:校验线

校验线要回答的是「每类凭据各自怎么验」。口令比的是加盐单向摘要,同一主体同一口令结果可复现、不同主体即使口令相同结果也不同;令牌考的是一次性应答,应答随挑战值变化,换一个挑战值原应答立即失效;证书验的是签名,主体被改一个字段签名就不成立。把这三类校验方式分开写、分开实现,才不会出现「用比口令的方式去验证书」这类错位。

身份认证凭据管理系统:时效线

时效线要回答的是「过期没过期怎么判」。口令按更换周期、令牌一次一用、证书按有效期、票据按到期时间,四类口径各自成立;校验通过之后必须再过一道时效判断,而不是只验内容不验时间。这一条最容易被省:很多系统验了口令对不对,却没验这张票据是不是早就过期了。登录认证中如何应用凭据管理系统,时效线往往是补起来最有收益的一环。

身份认证凭据管理系统:留痕线

留痕线要回答的是「谁用哪类凭据怎么核」。做法是给每一次认证生成一条含主体、场景、凭据标识、结果与时间的记录并整体签名,汇入同一本认证台账。记录整体签名之后不可事后修改,第三方只凭公开密钥即可复算一次认证动用了哪几类凭据、结果如何。这条线是四条线里最后收口的一环,它让前三件事从「做过」变成「可核」。

下面这张图说明四条线在一次认证里的位置关系:

text 复制代码
[目录线]   认证场景 --> [场景与凭据对应表] --> [未列入即拒绝]
      |
      v
[校验线]   口令 --> [比加盐摘要] | 令牌 --> [考一次性应答] | 证书 --> [验签名]
      |
      v
[时效线]   口令(周期) / 令牌(一次) / 证书(有效期) / 票据(到期) --> [时效判断]
      |
      v
[留痕线]   主体+场景+凭据标识+结果+时间 --> [整条记录签名] --> [第三方可复算]

03 | 先跑通:身份认证凭据管理系统的四个验证点

下面这段演示把凭据目录、口令加盐摘要、令牌一次性应答、证书主体验签,以及票据时效与认证使用记录整体签名串在同一段代码里跑一遍,用的是公开算法:SM2 签名、SM3 摘要、SM4 分组加密。代码只依赖 gmssl,可以直接复现。

python 复制代码
# -*- coding: utf-8 -*-
"""
W39 Day8 #2 · 身份认证凭据管理系统
演示认证时刻凭据编排四线:凭据目录(按场景选凭据) / 校验线(口令摘要 + 令牌一次性 + 证书验签) /
时效线(票据到期即拒) / 留痕线(认证使用记录整体签名)
"""

from gmssl import sm2, sm4, sm3, func

# ---- 固定私钥(已过 xxcsdn_keycheck.py 三关) ----
PRIV_CRED = "3e6b18d53e6b18d53e6b18d53e6b18d53e6b18d53e6b18d53e6b18d53e6b18d5"   # 凭据签发方
PRIV_FORGE = "2f7a03e92f7a03e92f7a03e92f7a03e92f7a03e92f7a03e92f7a03e92f7a03e9"  # 冒名方
FIXED_K = "0101010101010101010101010101010101010101010101010101010101010101"


def pub_of(priv: str) -> str:
    """P = d·G。gmssl 不会从私钥派生公钥,必须显式算出再传给 CryptSM2。"""
    return sm2.CryptSM2(private_key=priv, public_key="")._kg(
        int(priv, 16), sm2.default_ecc_table["g"])


PUB_CRED = pub_of(PRIV_CRED)
PUB_FORGE = pub_of(PRIV_FORGE)


def sm3_hex(data: bytes) -> str:
    return sm3.sm3_hash(func.bytes_to_list(data))


# ---- 手写 SM4-CBC:gmssl 的 crypt_cbc 有缺陷,one_round 是 16 进 16 出的单块运算 ----
def sm4_cbc(key: bytes, iv: bytes, data: bytes, enc: bool) -> bytes:
    assert len(key) == 16, "SM4 KEY 必须 16 字节"
    assert len(iv) == 16, "IV 必须 16 字节(少一字节会 IndexError)"
    c = sm4.CryptSM4()
    c.set_key(key, sm4.SM4_ENCRYPT if enc else sm4.SM4_DECRYPT)
    out, prev = b"", iv
    for i in range(0, len(data), 16):
        blk = data[i:i + 16]
        if enc:
            x = bytes(a ^ b for a, b in zip(blk, prev))
            e = bytes(c.one_round(c.sk, list(x)))
            out += e
            prev = e
        else:
            d = bytes(c.one_round(c.sk, list(blk)))
            out += bytes(a ^ b for a, b in zip(d, prev))
            prev = blk
    return out


def pkcs7_pad(data: bytes, block: int = 16) -> bytes:
    pad = block - (len(data) % block)
    return data + bytes([pad]) * pad


def pkcs7_unpad(data: bytes) -> bytes:
    pad = data[-1]
    if not (1 <= pad <= 16):
        return data
    return data[:-pad]


def decrypt_or_none(key: bytes, iv: bytes, ct: bytes):
    try:
        return pkcs7_unpad(sm4_cbc(key, iv, ct, False))
    except Exception:  # noqa: BLE001
        return None


def dec_is(key: bytes, iv: bytes, ct: bytes, plain: bytes) -> bool:
    """「换密钥解不开」的判据是「还不出原文」,不能写 `is None`(用错密钥通常不抛异常)。"""
    return decrypt_or_none(key, iv, ct) == plain


# ======================================================================= #
# 业务逻辑区
# ======================================================================= #

KEY = b"16BYTEKEYFORCRED"        # 16 字节,数过
IV = b"16BYTEIVFORCRED0"         # 16 字节,数过
WRONG_KEY = b"WRONGKEYFORCRED0"  # 16 字节,数过
assert len(KEY) == len(IV) == len(WRONG_KEY) == 16

signer = sm2.CryptSM2(public_key=PUB_CRED, private_key=PRIV_CRED)
forge = sm2.CryptSM2(public_key=PUB_FORGE, private_key=PRIV_FORGE)


# --- 1) 凭据目录线:按认证场景选出该场景该用的凭据类型,同场景可复现、不同场景不同 ---
CATALOG = {
    "console-login": "password+mfa",
    "service-call": "client-cert",
    "one-time-link": "token",
    "high-risk-op": "keypair-challenge",
}


def cat_of(scene: str) -> str:
    return CATALOG.get(scene, "deny")


ok_cat_repro = cat_of("console-login") == cat_of("console-login")
ok_cat_diff = cat_of("console-login") != cat_of("service-call")
ok_cat_deny = cat_of("unknown-scene") == "deny"


# --- 2) 校验线 A:口令加盐单向摘要,同主体可复现、不同主体不同、不含原文 ---
def pwd_digest(uid: str, pwd: str) -> str:
    return sm3_hex(b"cred-auth|" + uid.encode("utf-8") + b"|" + pwd.encode("utf-8"))


pwd = "Pw2026Kx"
ok_pwd_same = pwd_digest("u7001", pwd) == pwd_digest("u7001", pwd)
ok_pwd_salt = pwd_digest("u7001", pwd) != pwd_digest("u7002", pwd)
ok_pwd_no_plain = pwd not in pwd_digest("u7001", pwd)


# --- 3) 校验线 B:令牌一次性,应答随挑战变化,换挑战原应答失效 ---
def token_resp(token_id: str, challenge: str) -> str:
    return sm3_hex(b"tok=" + token_id.encode("utf-8")
                   + b"|chal=" + challenge.encode("utf-8"))


tok1 = "OTP-7001-0001"
ok_tok_same = token_resp(tok1, "CH-1") == token_resp(tok1, "CH-1")
ok_tok_change = token_resp(tok1, "CH-1") != token_resp(tok1, "CH-2")


# --- 4) 校验线 C:证书主体签名,验签通过 / 主体被改被拒 / 冒名被拒 ---
cert = "sn=C-0007|subj=svc-payment|issuer=cred-ca|valid_to=20270201"
h_cert = sm3_hex(cert.encode("utf-8"))
sig_cert = signer.sign(h_cert.encode("utf-8"), FIXED_K)
ok_cert = signer.verify(sig_cert, h_cert.encode("utf-8"))
cert_tampered = cert.replace("subj=svc-payment", "subj=svc-admin")
ok_cert_tamper = not signer.verify(
    sig_cert, sm3_hex(cert_tampered.encode("utf-8")).encode("utf-8"))
sig_forge = forge.sign(h_cert.encode("utf-8"), FIXED_K)
ok_cert_imposter = not signer.verify(sig_forge, h_cert.encode("utf-8"))


# --- 5) 时效线:票据到期即拒,未到期接受 ---
def expired(issued_min: int, ttl_min: int, now_min: int) -> bool:
    return now_min >= issued_min + ttl_min


ok_ticket_valid = not expired(600, 30, 615)   # 10:00 签发,10:15 使用
ok_ticket_expired = expired(600, 30, 640)     # 10:40 使用,已过期


# --- 6) 留痕线:认证凭据使用记录整体签名,可核、被改即拒 ---
record = "subj=u7001|scene=console-login|cred=OTP-7001-0001|result=allow|at=20261014T1015"
h_rec = sm3_hex(record.encode("utf-8"))
sig_rec = signer.sign(h_rec.encode("utf-8"), FIXED_K)
ok_rec = signer.verify(sig_rec, h_rec.encode("utf-8"))
rec_tampered = record.replace("result=allow", "result=deny")
ok_rec_tamper = not signer.verify(
    sig_rec, sm3_hex(rec_tampered.encode("utf-8")).encode("utf-8"))
ok_repro = signer.sign(h_rec.encode("utf-8"), FIXED_K) == sig_rec


# --- 7) 记录加密落盘:可还原、换密钥解不开 ---
secret = record.encode("utf-8")
ct = sm4_cbc(KEY, IV, pkcs7_pad(secret), True)
ok_enc = dec_is(KEY, IV, ct, secret)
ok_ct_diff = ct != secret
ok_wrong_key = not dec_is(WRONG_KEY, IV, ct, secret)

asserts = [
    ("同场景选出的凭据类型可复现", ok_cat_repro),
    ("不同场景选出的凭据类型不同", ok_cat_diff),
    ("未知场景默认拒绝", ok_cat_deny),
    ("口令加盐摘要可复现", ok_pwd_same),
    ("不同主体同口令摘要不同", ok_pwd_salt),
    ("口令摘要中不含口令原文", ok_pwd_no_plain),
    ("同一挑战令牌应答可复现", ok_tok_same),
    ("换挑战后原应答失效", ok_tok_change),
    ("证书主体签名验签通过", ok_cert),
    ("证书主体被改后签名被拒", ok_cert_tamper),
    ("冒名方签名被拒", ok_cert_imposter),
    ("未到期票据被接受", ok_ticket_valid),
    ("已到期票据被拒绝", ok_ticket_expired),
    ("认证使用记录整体签名验签通过", ok_rec),
    ("使用记录被改后签名被拒", ok_rec_tamper),
    ("固定 K 签名可复现", ok_repro),
    ("使用记录密文可解密还原", ok_enc),
    ("使用记录密文与明文不同形", ok_ct_diff),
    ("换密钥无法还原使用记录", ok_wrong_key),
]

# 首行必须是 '='*60:脚本靠它把「demo 输出块」与「ASCII 机制图」区分开
print("=" * 60)
for t, ok in asserts:
    print(f"[{t}] = {'True' if ok else 'False'}")
text 复制代码
============================================================
[同场景选出的凭据类型可复现] = True
[不同场景选出的凭据类型不同] = True
[未知场景默认拒绝] = True
[口令加盐摘要可复现] = True
[不同主体同口令摘要不同] = True
[口令摘要中不含口令原文] = True
[同一挑战令牌应答可复现] = True
[换挑战后原应答失效] = True
[证书主体签名验签通过] = True
[证书主体被改后签名被拒] = True
[冒名方签名被拒] = True
[未到期票据被接受] = True
[已到期票据被拒绝] = True
[认证使用记录整体签名验签通过] = True
[使用记录被改后签名被拒] = True
[固定 K 签名可复现] = True
[使用记录密文可解密还原] = True
[使用记录密文与明文不同形] = True
[换密钥无法还原使用记录] = True

逐段读一下这段代码在验什么。前三条验目录线:同一个场景选出的凭据类型可复现,换一个场景结果不同,未列入目录的场景默认拒绝------它说明「该用哪把锁」是可以被机器判定、而不是靠人记的。第四到六条验校验线里的口令:同一主体同一口令的摘要可复现,换一个主体摘要就不同,摘要里不含口令原文。第七、八条验令牌的一次性:同一挑战值的应答可复现,换一个挑战值原应答立即失效------这条直接对上了重放。第九到十一条验证书:主体签名能验过,主体被改一个值签名被拒,换一把私钥来签同样不被接受。第十二、十三条验时效线:未到期的票据被接受,已过期的票据被拒绝。第十四到十六条验留痕线:认证使用记录整体签名能验过,把结果从放行改成拒绝签名立刻被拒,冒名签名不被接受。最后三条验落盘与可复现:使用记录密文能解密还原、密文与明文不同形、换一把密钥就解不开。

现场演示时最能说明问题的是第八条和第十三条:换一个挑战值原应答就失效,说明令牌的「一次一用」不是写在策略里的一句话,而是算法保证的结果;票据一过期就被拒绝,说明时效不是靠人工记得去清,而是校验链上的一道固定判定。这两条把「一次一用」和「到期作废」从原则变成了当场能跑出来的结果。

要注意一处工程细节:演示里用的是固定随机数的 SM2 签名,目的是让每次输出一致、便于复现;真实系统里签名随机数必须由密码模块内部产生,同一私钥配同一个随机数会泄露私钥,这一点在技术评审时经常被追问。

04 | 落地动作:身份认证凭据管理系统分四条线怎么做

身份认证凭据管理系统,落到动作上可以按四条线分开说,每条线给出可验证的验收点,而不是给一串配置项。

目录线,动作是先把认证场景清单列全,再逐个定它该用的凭据类型,并写进策略、做成机器可读。验收点:随机报一个场景,系统能立刻给出该场景该用的凭据类型,未列入目录的场景一律拒绝。身份认证中如何应用凭据管理系统,起点就在这份目录。

校验线,动作是按凭据类型分别实现校验:口令比加盐摘要、令牌考一次性应答、证书验签名,三类逻辑不共用一套流程。验收点:把一枚令牌的应答重放一次必须被拒;把证书主体改一格,验签必须失败。

时效线,动作是给每类凭据定时效口径并在校验之后加一道时效判断。验收点:拿一张已过期的票据来登录,必须被拒绝;拿一枚已用过的令牌再来,必须被拒绝。登录认证中如何应用凭据管理系统,补上这一条收益最直接。

留痕线,动作是给每一次认证生成含主体、场景、凭据标识、结果与时间的记录并整体签名。验收点:抽一次历史认证,团队能当场复算出它用了哪几类凭据、结果如何;把记录改一格,验签必须失败。

整改样本(某电商平台)。 背景:口令、证书、令牌三类凭据分属三个小组,场景与凭据的对应关系没人说得清,票据过期没人清,认证记录只留一个计数。动作:先立场景与凭据对应目录并写进策略(三周);再按类型分别实现口令、令牌、证书三类校验(四周);随后给四类凭据补齐时效判断、清掉一批过期凭据(两周);最后给认证生成含主体与结果的签名记录、汇入认证台账(三周)。结果:一次登录用了哪几类凭据能当场说清;令牌重放第一次被系统拒绝;过期票据不再能登入;抽查任意一次认证都能复算到人。整个周期约三个月,主要工作量在把三个小组的口径收敛成一份目录。

05 | 避坑清单:身份认证凭据管理系统的 9 条常见坑

踩得最多的坑按后果严重度排序如下。判断是否避开,靠的是当场能跑出来的结果,而不是文档里写过。

# 坑 后果 怎么验证避开了
1 没有场景与凭据目录 同类场景强度不一 报一个场景即给出凭据类型
2 未列入场景默认放行 漏配场景无人兜底 未知场景默认拒绝
3 三类凭据一套校验流程 令牌证书形同虚设 令牌与证书各自可通过验证
4 口令明文或弱摘要 库被拖即全泄 只存加盐单向摘要
5 令牌可重复使用 应答可被重放 换挑战原应答即失效
6 只验内容不验时效 过期凭据还能用 过期票据被拒绝
7 证书主体可事后改 身份可被冒用 主体改一格即验签失败
8 认证记录无主体 来龙去脉查不到 记录含主体可复算
9 凭据分属几处各管一段 加一类要改三处 收敛到一套目录与台账

展开说第 6 条。只验内容不验时效,是最容易被放过的一条:系统把口令比对了、把签名验过了,就认为「凭据是对的」,却没有再问一句「这张凭据是不是已经过期」。口令有更换周期,长期不变的口令一旦泄露,就等于长期有效;令牌本应一次一用,被重复提交却照样通过,就退化成了一把长期口令;证书与票据都有明确的有效期,过了期还能用,等于有效期形同虚设。正确做法是在校验之后固定加一道时效判断:内容是内容、时间是时间,两道都过才放行。登录认证中如何应用凭据管理系统,真正要交付的不是一条比对规则,而是这套「验内容 + 验时效」的双重口径。

06 | 合规视角:身份认证凭据管理系统要对上哪些要求

身份认证凭据管理系统要对上的要求,可以归成四类,每类都落到具体动作上。

网络安全等级保护。 GB/T 22239-2019 在身份鉴别里要求身份标识与主体一一对应、口令具备复杂度并定期更换,采用两种或两种以上组合的鉴别技术时应有一种为密码技术。落到本文场景,就是四条动作:场景与凭据目录、口令加盐摘要、组合鉴别中至少一类为密码技术、凭据按周期更换。这几条要落到同一份目录里,而不是散在各系统的配置中。

商用密码应用安全性评估。 GB/T 39786《信息安全技术 信息系统密码应用基本要求》把密钥的产生、存储、分发、使用、更新、销毁纳入密码应用要求。认证环节要用到的密钥、证书、令牌都属密码应用范围,测评会追问密钥与证书的产生方式、存放位置与轮换周期,这三项要在方案里先写清楚。

密码法与商用密码管理条例。 两条法规对商用密码的使用、密钥管理与检测认证提出要求。落到认证场景,就是识别环节用到的算法与密钥管理要合规、凭据的使用要可追溯。

个人信息保护法的一般要求。 处理个人信息应遵循最小必要,并采取加密、去标识化等技术措施。认证环节天然接触主体标识,做法是只取做鉴别所必需的字段,认证台账里的主体标识用确定性映射承载,既保留按主体聚合的能力,又不把原始标识铺进认证明细。

关于「价值」怎么讲。 凭据编排最终不是多了一个凭据库,而是让「一次认证动用了什么」这件事被编排在一处:哪个场景用哪类凭据、每类怎么验、过期没过期、谁在什么时候用的,四件事都能当场说清。核查方要的不是一份算法清单,而是能当场复算的一条认证链路。把目录、校验、时效、留痕四件事做实,交出去的就是可验证的物件。

07 | 落地答案:身份认证凭据管理系统怎么承接

落地落到产品能力上,通常也是四段。对身份认证中如何应用凭据管理系统而言,评估顺序建议倒过来:先看一次认证能不能被完整编排,再看支持多少种凭据类型------编排不起来,类型再多也只是功能清单。

目录这一段,需要的能力是「场景与凭据的对应表可机器判定」。把认证场景列全、逐个绑定凭据类型并写进策略,未列入的场景默认拒绝。

校验这一段,需要的能力是「按类型分别校验」。口令比加盐摘要、令牌考一次性应答、证书验签名,三类逻辑分开实现、各自可通过验证。

时效这一段,需要的能力是「校验之后再过时效」。四类凭据各有各的时效口径,过期一律拒收,不需要人工定期清理。

留痕这一段,需要的能力是「认证使用记录整体签名」。主体、场景、凭据标识、结果与时间各留一条并整体签名,第三方只凭公开密钥即可复算一次认证。安当在这一段提供的能力落在凭据目录与认证记录的签名上,关键词是「可复算」:这次登录用了哪几类凭据、结果如何、谁在什么时候用的,三件事都能当场算出来。

08 | 验收清单与下一步

上线前建议逐项过一遍这张表,任何一项答不上来,就不要接受「凭据已经编排好」这个结论。

# 验收项 通过标准
1 场景与凭据目录在生效 报一个场景即给出凭据类型
2 未列入场景默认拒绝 未知场景不放行
3 口令只存摘要 库中不含口令原文
4 摘要按主体加盐 换主体摘要即不同
5 令牌一次一用 换挑战原应答即失效
6 证书主体可验 主体签名验签通过
7 冒名签名被拒 换私钥签名不被接受
8 主体改动即拒 改一格验签失败
9 校验后过时效 过期票据被拒绝
10 口令按周期更换 到期即触发更换
11 认证记录含主体 可定位到人
12 认证记录含场景与凭据 可还原用了哪几类
13 记录整体签名 改一格即验签失败
14 认证结果可复算 放行或拒绝均可复核
15 记录加密落盘 换密钥读不出
16 第三方可复算 只凭公钥即可验一条记录

趋势上看,凭据管理正在从「凭据存在哪」走向「认证时取用了什么」。过去交一份凭据清单就算交差;现在检查会随机抽一次认证,要求团队当场说清它动用了哪几类凭据、每类怎么验的、有没有过期、是谁用的。这个迁移对平台的实质要求是:目录、校验、时效、留痕四条线必须落在同一套口径与同一本认证台账上------这也是这件事从「存得住」走向「编得清」的实质。

下一篇预告:同一工作日的另一篇,我们把镜头移回数据脱敏,看轻量级证书签发系统在脱敏作业里承担了什么------从规则签发到产物核验,一张证书能串起几段。

09 | 常见问题:身份认证凭据管理系统的 5 个高频疑问

  • Q: 身份认证凭据管理系统落地时,第一步需要什么准备?
    • A: 先把场景与凭据的对应目录立起来。把认证场景列全,逐个定它该用的凭据类型,写进策略并做成机器可读,未列入的场景默认拒绝。目录是后面三条线的底稿:先有目录,才谈每类怎么验、过期怎么判、用了怎么留痕;跳过目录直接实现校验,往往会出现同类场景强度不一。
  • Q: 登录认证中如何应用凭据管理系统,才能让令牌不被重放?
    • A: 让令牌的应答随挑战值变化,一个挑战只接受一次应答。系统先下发一次性挑战,主体用凭据对挑战作答,换一个挑战值原应答立即失效;把这条做进校验线之后,抓包重放这条路就走不通了。关键是挑战值要一次性且不可预测,而不是固定一个值反复比对。
  • Q: 身份认证中如何应用凭据管理系统,口令、令牌、证书要分开处理吗?
    • A: 要分开,三者校验逻辑本来就不同。口令比的是加盐单向摘要,令牌考的是一次性应答,证书验的是签名;用一套取出来比对一下的流程去套,令牌和证书就形同虚设。把三类分开实现、分开验收,才不会出现用比口令的方式去验证书这类错位。
  • Q: 认证凭据的时效要怎么做才算到位?
    • A: 校验之后固定再过一道时效判断。口令按更换周期、令牌一次一用、证书按有效期、票据按到期时间,四类口径各自成立;内容是内容、时间是时间,两道都过才放行。只验内容不验时间,是这类系统最常见也最容易被忽略的一个口子。
  • Q: 认证使用记录需要什么字段才够被复核?
    • A: 结论是至少留主体、场景、凭据标识、结果与时间五项,并且整条记录要签名。主体回答是谁,场景回答在什么入口,凭据标识回答用了哪一类凭据,结果回答放行还是拒绝,时间回答什么时候。五项齐备并整体签名之后,第三方只凭公开密钥即可复算一次认证。

相关阅读


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

相关推荐
躺柒1 天前
读数据安全架构设计与实践03身份认证(上)
网络安全·信息安全·数据安全·安全架构·身份认证
FungLeo2 天前
成为全栈·Flutter App 篇·Refresh Token 旋转与并发 401:安全存储与会话代次
flutter·jwt·移动安全·身份认证·token刷新·成为全栈
安当加密030114 天前
动态口令认证实施案例
身份认证·国密算法·双因素认证·动态口令·实施落地
安当加密030114 天前
动态口令认证排行榜
数据加密·身份认证·国密算法·动态口令·采购人选型
2601_962297251 个月前
JumpServer使用OpenID对接Azure AD身份认证
堡垒机·jumpserver·身份认证·openid·azuread
安当加密03012 个月前
矿山智能化身份认证与煤安合规解读:信息系统安全建设到认证落地
身份认证·密钥管理·ukey·矿山智能化·煤安合规
吴声子夜歌2 个月前
网络安全——身份认证
安全·web安全·身份认证
ChaITSimpleLove3 个月前
SimpleIdServer 6.0.4 Docker Compose 实战部署指南
运维·docker·容器·身份认证·id-server·simpleidserver