LabHub
学习 学习路径 课程

企业认证对接

拆开 SAML Assertion

在 LabHub 中继续学习

目标

解码真实格式的 SAML Response,亲自提取 Issuer、NameID、Conditions、属性和签名元素,并整理 SP 必须验证的项目。

为什么重要

SAML 集成通常由库完成,但发生故障后最终仍要直接查看 XML。收到“Audience 不匹配”“超过 NotOnOrAfter”“缺少 InResponseTo”等错误时,必须知道该在文档的哪个位置检查。

本实验真正的目的,是理解签名验证的陷阱。XML Signature Wrapping 攻击可以在签名验证通过的同时,让应用读取到伪造数据。“签名是否有效”与“我读取的节点是否就是被签名的节点”是两个不同问题。亲自在文档中确认这一点后,就能解释为什么不应自行实现 SAML。

步骤

  1. 解码 /opt/lab/fixtures/auth/saml/response.b64,保存为 /root/saml/response.xml。它必须是有效 XML。
  2. 创建 /root/saml/head.txt,共四行,格式如下。
    issuer=<Response 의 Issuer 값>
    destination=<Destination 속성>
    inresponseto=<InResponseTo 속성>
    status=<StatusCode 의 Value 속성>
    
  3. 创建 /root/saml/subject.txt,共两行。
    nameid=<NameID 값>
    format=<NameID 의 Format 속성>
    
  4. 创建 /root/saml/conditions.txt,共四行。
    notbefore=<NotBefore>
    notonorafter=<NotOnOrAfter>
    audience=<Audience 값>
    valid=<현재 시각 기준 유효하면 Y, 아니면 N>
    
  5. 提取 AttributeStatement 的属性,创建 /root/saml/attrs.csv。第一行为 name,value,按名称升序排列。
  6. 创建 /root/saml/sig.txt,共三行。
    reference_uri=<Reference 의 URI 속성>
    digest_alg=<DigestMethod 의 Algorithm 속성>
    signature_alg=<SignatureMethod 의 Algorithm 속성>
    
  7. 将 XML 中的 X509Certificate 内容恢复为 PEM 格式,并保存到 /root/saml/idp.pemopenssl x509 -in /root/saml/idp.pem -noout -subject 必须成功。
  8. 编写 /root/saml/checklist.md。列出 SP 必须验证的至少 7 项,并为每项补充一行验证失败时的风险。正文中必须出现 AudienceNotOnOrAfterInResponseToDestinationIssuer서명재사용 七个词。

参考

解码 SAMLResponse

解码 /opt/lab/fixtures/auth/saml/response.b64, 保存为 /root/saml/response.xml。它必须是有效 XML。

SAMLResponse 参数采用 base64。请同时记住,POST binding 不压缩,而 Redirect binding 还会增加 deflate 压缩。

提取 Response header 信息

创建 /root/saml/head.txt,共四行,格式如下。

issuer=<Response 의 Issuer 값>
destination=<Destination 속성>
inresponseto=<InResponseTo 속성>
status=<StatusCode 의 Value 속성>

这是包含多个 namespace 的 XML。在 xmlstarlet 中按 local name 查找,就不会受 prefix 影响。

提取 NameID 与格式

创建 /root/saml/subject.txt,共两行。

nameid=<NameID 값>
format=<NameID 의 Format 속성>

NameID 的 Format 会影响 SP 识别用户的方式。想一想 persistent 与 transient 的区别。

检查有效时间与受众

创建 /root/saml/conditions.txt,共四行。

notbefore=<NotBefore>
notonorafter=<NotOnOrAfter>
audience=<Audience 값>
valid=<현재 시각 기준 유효하면 Y, 아니면 N>

NotOnOrAfter 表示“从该时刻起无效”。请与当前时间比较后判断;此 fixture 是过去签发的。

提取属性

提取 AttributeStatement 的属性,创建 /root/saml/attrs.csv。 第一行为 name,value,按名称升序排列。

AttributeStatement 中有多个 Attribute,每个又可能有一个以上的值。请把名称与值配对并排序。

检查签名元素

创建 /root/saml/sig.txt,共三行。

reference_uri=<Reference 의 URI 속성>
digest_alg=<DigestMethod 의 Algorithm 속성>
signature_alg=<SignatureMethod 의 Algorithm 속성>

关键在于 Reference 的 URI 指向什么。确认它与我们实际读取的节点相同,是签名验证的一半。

恢复 IdP 证书

将 XML 中的 X509Certificate 内容恢复为 PEM 格式, 并保存到 /root/saml/idp.pemopenssl x509 -in /root/saml/idp.pem -noout -subject 必须成功。

X509Certificate 元素只包含 PEM 的正文(base64)。必须补上 header、footer 和换行,openssl 才能读取。

编写 SP 验证检查清单

编写 /root/saml/checklist.md。列出 SP 必须验证的 至少 7 项,并为每项补充一行验证失败时的风险。 正文中必须出现 AudienceNotOnOrAfterInResponseToDestinationIssuer서명재사용 七个词。

“签名是否有效”与“我读取的节点是否就是被签名的节点”是两个不同问题。这一区别正是 XML Signature Wrapping 攻击的核心。