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

如何用Kerberos加密请求消息体?认证成功但加密请求报错

问题分析与解决方案

你的核心问题是:第二个请求仅构造了multipart/encrypted的格式框架,但没有用Kerberos会话密钥加密SOAP消息体,WEC服务器无法解密明文内容,因此返回failed to unwrap kerberos packet错误。

结合OpenWEC协议文档关键内容翻译:

客户端发送枚举请求时,需使用multipart/encrypted格式的请求体,其中包含两部分:

  1. 第一部分为元数据,指定原始内容类型和长度;
  2. 第二部分是通过Kerberos会话密钥加密后的SOAP消息二进制数据,需使用GSSAPI的wrap操作生成。

具体实现步骤

  • 保留Kerberos GSS上下文:第一个认证请求不能只获取token,需要保留GSS客户端上下文,用于后续的加密操作。
  • 加密SOAP消息体:使用kerberos.authGSSClientWrap方法,通过已建立的Kerberos会话加密SOAP内容。
  • 修正multipart payload构造:将加密后的二进制数据放入application/octet-stream部分,而不是明文。

修改后的完整代码

import requests
import kerberos

def init_kerberos_context(service):
    # 初始化GSS客户端上下文并完成认证,返回上下文和token
    _, krb_context = kerberos.authGSSClientInit(service)
    kerberos.authGSSClientStep(krb_context, "")
    negotiate_token = kerberos.authGSSClientResponse(krb_context)
    return krb_context, negotiate_token

# 替换为实际的SOAP内容
soap_message = "<soap:Envelope ...></soap:Envelope>"
auth_url = "http://localhost:8081/wsman"

# 初始化Kerberos上下文并获取认证token
krb_context, negotiate_token = init_kerberos_context(service="http@localhost")

auth_headers = {
    'Host': 'localhost:8081',
    'Content-Length': '0',
    'Authorization': f'Kerberos {negotiate_token}',
    'Content-Type': 'application/soap+xml;charset=UTF-8',
    'Accept-Encoding': 'gzip'
}

session = requests.Session()
auth_response = session.post(auth_url, headers=auth_headers)
print(f"Auth Response status code: {auth_response.status_code}")
print(f"Auth Response content: {auth_response.text}")

# 加密SOAP消息体
# wrap参数:上下文、明文内容、是否为隐私(加密+完整性)、是否为序列
encrypted_data, _ = kerberos.authGSSClientWrap(krb_context, soap_message.encode('utf-8'), True, True)

boundary = "Encrypted Boundary"
# 构造正确的multipart/encrypted payload
payload_parts = [
    f"--{boundary}",
    'Content-Type: application/HTTP-Kerberos-session-encrypted',
    f'OriginalContent: type=application/soap+xml;charset=UTF-8;Length={len(soap_message)}',
    f"--{boundary}",
    'Content-Type: application/octet-stream',
    '',  # 空行分隔头部和内容
    f"--{boundary}--"  # 结束边界必须带--
]
# 用\r\n连接文本部分,再拼接二进制加密数据
payload = '\r\n'.join(payload_parts[:-2]).encode('utf-8') + b'\r\n' + encrypted_data + b'\r\n' + payload_parts[-1].encode('utf-8')

soap_headers = {
    'Host': 'localhost:8081',
    'User-Agent': 'Go-http-client/1.1',
    'Content-Type': f'multipart/encrypted;protocol="application/HTTP-Kerberos-session-encrypted";boundary="{boundary}"',
    'Accept-Encoding': 'gzip'
}

soap_url = "http://localhost:8081/wsman/subscriptions/24f5eb95-d9b1-1005-8062-697970657274/0"
soap_response = session.post(soap_url, headers=soap_headers, data=payload)

print(f"SOAP Response status code: {soap_response.status_code}")
print(f"SOAP Response content: {soap_response.text}")

# 清理上下文
kerberos.authGSSClientClean(krb_context)

关键修改说明

  • 保留GSS上下文:init_kerberos_context函数返回上下文对象,这是后续加密操作的核心支撑,之前代码缺失了这一步。
  • 加密操作:authGSSClientWrap使用Kerberos会话密钥对SOAP内容加密,生成WEC可解密的二进制数据。
  • payload格式修正:
    • 结束边界必须添加--,符合multipart规范;
    • 原始内容长度要与明文SOAP的字节数一致;
    • 加密后的二进制数据直接作为二进制内容拼接,不能转成字符串处理。

内容的提问来源于stack exchange,提问作者user14073111

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 20:24:57