You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SAML响应“信封式签名”验证失败问题咨询

SAML信封式签名验证失败问题排查

1. 元素格式问题

你提供的存在Transform顺序错误,这会直接导致签名验证失败:

<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"></ds:CanonicalizationMethod>
  <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod>
  <ds:Reference URI="#pfxffef2099-cc79-fd84-e7e8-5bdced364715">
    <ds:Transforms>
      <!-- 错误:enveloped-signature必须放在C14N之前 -->
      <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"></ds:Transform>      
      <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform>
    </ds:Transforms>
    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
    <ds:DigestValue>LC/2Thrnfl3SUqWp8LXfZFyXoZA=</ds:DigestValue>
  </ds:Reference>
</ds:SignedInfo>

错误原因:

信封式签名(enveloped-signature)的作用是先将节点从XML文档中移除,再对剩余内容做规范化处理。如果先执行C14N再执行enveloped转换,签名计算时会包含节点本身的内容,导致验证方计算的摘要与生成的DigestValue逻辑冲突。

修正后的Transforms顺序:

<ds:Transforms>
  <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform>
  <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"></ds:Transform>
</ds:Transforms>

其他部分(命名空间、算法URI、DigestValue)均符合XML-DSig标准,无问题。


2. Python签名代码问题

你的代码存在签名填充算法不匹配的问题,这是验证失败的另一个关键原因:

from cryptography.hazmat.primitives.asymmetric import utils
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
import base64  # 原代码漏写该导入

with open("mysaml_pr_key.pem", "rb") as key_file:
    private_key = serialization.load_pem_private_key(
        key_file.read(),
        password=None,
        backend=default_backend()
    )
# 错误:使用PSS填充,但XML-DSig的rsa-sha1要求用PKCS#1 v1.5填充
mypadding_for_signature=padding.PSS(
mgf=padding.MGF1(hashes.SHA1()),
salt_length=padding.PSS.MAX_LENGTH
)
hasher2 = hashes.Hash(hashes.SHA1())
hasher2.update(to_be_signed.encode())
digest_of_signed_info=hasher2.finalize()
signature_before_64encode=private_key.sign(digest_of_signed_info,mypadding_for_signature,utils.prehashed(hashes.SHA1()))
signature=base64.b64encode(signature_before_64encode)

错误原因:

return (<SignedInfo>中指定的签名算法`http://www.w3.org/2000/09/xmldsig#rsa-sha1`,标准要求使用**PKCS#1 v1.5**填充,而非代码中的PSS填充。验证方会按PKCS#1 v1.5规则验证,自然会失败。

### 修正后的代码:
```python
from cryptography.hazmat.primitives.asymmetric import utils
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
import base64

with open("mysaml_pr_key.pem", "rb") as key_file:
    private_key = serialization.load_pem_private_key(
        key_file.read(),
        password=None,
        backend=default_backend()
    )
# 使用PKCS#1 v1.5填充,符合XML-DSig rsa-sha1规范
mypadding_for_signature = padding.PKCS1v15()
# 确保to_be_signed是经过C14N#WithComments规范化后的字节流
hasher2 = hashes.Hash(hashes.SHA1())
hasher2.update(to_be_signed)  # 若to_be_signed已是字节流,无需encode()
digest_of_signed_info = hasher2.finalize()
signature_before_64encode = private_key.sign(
    digest_of_signed_info,
    mypadding_for_signature,
    utils.Prehashed(hashes.SHA1())
)
signature = base64.b64encode(signature_before_64encode)
```

### 额外注意:
必须保证`to_be_signed`是**严格按照C14N#WithComments规范处理后的<SignedInfo>字节流**,不能是原始未规范化的XML字符串,否则即使填充正确,签名仍会不匹配。

---

## 总结
签名验证失败大概率由两个问题共同导致:
1. <SignedInfo>中Transform顺序错误,enveloped-signature未放在C14N之前
2. Python签名代码使用了错误的填充算法,应替换为PKCS#1 v1.5

修正这两个问题后重新生成签名,即可通过验证。

内容的提问来源于stack exchange,提问作者KimoAnalyzer)
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 22:42:57