通过Python签署肥皂消息

时间:2015-03-17 21:11:06

标签: encryption soap rsa python-2.6 m2crypto

我正在努力使用私钥签署XML soap消息。我以前在Java中已经完成了它,但是通过Python完成它非常困难。我在主目录中保留了一个模板XML,其值填充了“BinarySecurityToken”和“KeyInfo”标记。其中的值是通过SOAP UI使用相同的私钥生成的(因为指向Body标记的URI始终相同)。之后我计算整个Body标签的摘要值,并在“SignedInfo”中的“DigestValue”标签中填充它。现在我正在对此签名信息标记进行封装,并在其上计算“SignatureValue”。但最终,当我将这个Soap XML传递给webservice时,我收到了一条策略faliure消息(因为Signature generaion错误),下面是我的代码:

          body = etree.tostring(root.find('.//{http://schemas.xmlsoap.org/soap/envelope/}Body'))
          c14n_exc = True
          ref_xml = canonicalize(body, c14n_exc)
          digest_value = sha1_hash_digest(ref_xml)
          #Inserting the digest Value
          for soapheader in root.xpath('soapenv:Header/wsse:Security/ds:Signature/ds:SignedInfo/ds:Reference', namespaces=ns):
                soaptag = etree.XPathEvaluator(soapheader,namespaces=ns)
                soaptag('ds:DigestValue')[0].text = digest_value

          signed_info_xml = etree.tostring(root.find('.//{http://www.w3.org/2000/09/xmldsig#}SignedInfo'))
          signed_info = canonicalize(signed_info_xml, c14n_exc)
          pkey = RSA.load_key("privkeyifind.pem", lambda *args, **kwargs: "nopass")
          signature = pkey.sign(hashlib.sha1(signed_info).digest())
          signature_value = base64.b64encode(signature)
          #Inserting the signature Value

          for signedInfo in root.xpath('soapenv:Header/wsse:Security/ds:Signature', namespaces=ns):
                signtag = etree.XPathEvaluator(signedInfo,namespaces=ns)
                signtag('ds:SignatureValue')[0].text = signature_value
  canonReq = canonicalize(etree.tostring(root), c14n_exc)
          proc = Popen(["curl", "-k", "-s" ,"--connect-timeout", '3', '--data-binary' , canon2, "https://world-service-dev.intra.aexp.com:4414/worldservice/CLIC/CaseManagementService/V1"], stdout=PIPE, stderr=PIPE)
          response, err = proc.communicate()



#######################################################
#Method to generate the digest value of the xml message
#######################################################
def sha1_hash_digest(payload):
    "Create a SHA1 hash and return the base64 string"
    return base64.b64encode(hashlib.sha1(payload).digest())

#####################################
#Method to canonicalize a request XML
#to remove tabs, line feeds/spaces,
#quoting, attribute ordering and form
#a proper XML
#####################################
def canonicalize(xml, c14n_exc=True):
    "Return the canonical (c14n) form of the xml document for hashing"
    # UTF8, normalization of line feeds/spaces, quoting, attribute ordering...
    output = StringIO()
    # use faster libxml2 / lxml canonicalization function if available
    et = lxml.etree.parse(StringIO(xml))
    et.write_c14n(output, exclusive=c14n_exc)
    return output.getvalue()

我只能使用2.6.6的标准Python函数。我无法下载像signxml等消息签名库(由于对环境的限制)。

0 个答案:

没有答案