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

如何在Python Flask应用中用AES_256解密Ping Identity的SAML响应

Flask接收SAML响应配置

依赖安装

首先安装SAML处理依赖:

pip install pysaml2 flask pycryptodome

基础配置步骤

  • 提前从Ping Identity控制台导出IdP元数据文件,同时生成SP侧的RSA密钥对(公钥给到Ping Identity侧配置断言加密使用,私钥保存在你的服务本地)
  • 在Flask项目中添加SAML SP配置,示例如下:
from saml2 import config
from saml2.client import Saml2Client
from flask import Flask, request

app = Flask(__name__)
SAML_CONFIG = {
    'entityid': '你的SP实体ID',
    'service': {
        'sp': {
            'name': '你的服务名称',
            'endpoints': {
                'assertion_consumer_service': [
                    ('https://你的服务域名/saml/acs', config.BINDING_HTTP_POST),
                ],
            },
            # 配置解密用的私钥路径
            'key_file': '本地路径/to/your/private.key',
            # 配置签名用的公钥路径
            'cert_file': '本地路径/to/your/public.crt',
            # 开启断言解密支持
            'want_assertions_encrypted': True,
        }
    },
    # Ping Identity的IdP元数据路径
    'metadata': {
        'local': ['本地路径/to/ping-identity-metadata.xml']
    },
    # 指定加密算法为AES-256
    'encryption_algorithm': 'http://www.w3.org/2001/04/xmlenc#aes256-cbc',
    'key_transport_algorithm': 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p',
}

saml_client = Saml2Client(config=config.SPConfig().load(SAML_CONFIG))
  • 配置ACS路由接收SAML响应:
@app.route('/saml/acs', methods=['POST'])
def saml_acs():
    saml_response = request.form.get('SAMLResponse')
    if not saml_response:
        return '无效SAML响应', 400
    # 后续响应解析、断言解密逻辑放在这里
AES-256解密SAML断言实现

SAML断言的加密逻辑为:Ping Identity用随机生成的AES-256密钥加密明文断言,再用你提供的SP公钥加密这个AES密钥,加密后的密钥和加密断言会一并放在SAML响应的EncryptedAssertion节点中,解密步骤如下:

解密逻辑代码示例

import base64
from xml.etree import ElementTree as ET
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
from saml2.sigver import decrypt_key

def decrypt_saml_assertion(encrypted_saml_response):
    # 1. 解码base64格式的SAML响应
    decoded_resp = base64.b64decode(encrypted_saml_response)
    resp_root = ET.fromstring(decoded_resp)
    # 2. 提取加密的AES密钥、初始化向量和加密断言数据
    encrypted_assertion = resp_root.find('.//{urn:oasis:names:tc:SAML:2.0:assertion}EncryptedAssertion')
    encrypted_key = encrypted_assertion.find('.//{http://www.w3.org/2001/04/xmlenc#}EncryptedKey')
    encrypted_data = encrypted_assertion.find('.//{http://www.w3.org/2001/04/xmlenc#}EncryptedData')
    cipher_value = encrypted_data.find('.//{http://www.w3.org/2001/04/xmlenc#}CipherValue').text
    iv = encrypted_data.find('.//{http://www.w3.org/2001/04/xmlenc#}IV').text
    # 3. 用SP私钥解密得到AES-256密钥
    aes_key = decrypt_key(encrypted_key, SAML_CONFIG['service']['sp']['key_file'])
    # 4. 用AES-256密钥解密断言内容
    cipher = AES.new(aes_key, AES.MODE_CBC, iv=base64.b64decode(iv))
    decrypted_data = cipher.decrypt(base64.b64decode(cipher_value))
    plain_assertion = unpad(decrypted_data, AES.block_size)
    return plain_assertion.decode('utf-8')

注意事项

  • Ping Identity侧配置断言加密时,必须选择AES-256算法,和你的服务配置保持一致
  • 解密后必须对断言做签名校验,避免数据被篡改
  • 私钥文件必须严格管控访问权限,不要提交到代码仓库

内容的提问来源于stack exchange,提问作者Harmeet Singh Pable

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 15:57:03