title: Verifying SAML signature with Python Flask
body: <p>I have a Python Flask web app. I am integrating OKTA SAML in this app for authentication. </p>
  
  <p>I have followed the steps in:</p>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/21209510/validating-saml-signature-in-python">Validating SAML signature in python</a></li>
  <li><a href="https://stackoverflow.com/questions/9704919/saml-signature-verification-using-python-m2crypto/17372895#17372895">SAML signature verification using Python/M2Crypto</a></li>
  </ul>
  
  <p>However the validation always fails. When I run <code>verify_signature()</code>, it always gives me <code>0</code>.</p>
  
  <p>My Code:</p>
  
  <pre><code>def verify_signature(signed_info, cert, signature):
      x509 = X509.load_cert_string(base64.decodestring(cert), X509.FORMAT_DER)
      pubkey = x509.get_pubkey().get_rsa()
      verify_EVP = EVP.PKey()
      verify_EVP.assign_rsa(pubkey)
      verify_EVP.reset_context(md='sha256')
      verify_EVP.verify_init()
      verify_EVP.verify_update(signed_info)
  
      return verify_EVP.verify_final(signature.decode('base64'))
  
  def decode_response(resp):
      return base64.b64decode(resp)
  
  def get_xmldoc(xmlstring):
      return XML.fromstring(xmlstring)
  
  def get_signature(doc):
      return doc.find('{http://www.w3.org/2000/09/xmldsig#}Signature')
  
  def get_signed_info(signature):
      signed_info = signature.find(
          '{http://www.w3.org/2000/09/xmldsig#}SignedInfo')
      signed_info_str = str(signed_info)
      # return parse(StringIO(signed_info_str))
      return signed_info_str
  
  def get_cert(signature):
      ns = '{http://www.w3.org/2000/09/xmldsig#}'
      keyinfo = signature.find('{}KeyInfo'.format(ns))
      keydata = keyinfo.find('{}X509Data'.format(ns))
      certelem = keydata.find('{}X509Certificate'.format(ns))
      return certelem.text
  
  def get_signature_value(signature):
      return signature.find(
          '{http://www.w3.org/2000/09/xmldsig#}SignatureValue').text
  
  # Main Function
  dec_resp = decode_response(saml)
  xml = get_xmldoc(dec_resp)
  signature = get_signature(xml)
  signed_info = get_signed_info(signature)
  cert = get_cert(signature)
  signature_value = get_signature_value(signature)
  is_valid = verify_signature(signed_info, cert, signature_value)
  print is_valid # ALWAYS PRINTS 0.
  </code></pre>