Reputation: 153
I want to encrypt the body of the SOAP XML document. It works perfectly fine with SoapUI, where I use certificate, Subject Key Identifier as Key Identifier Type, AES256-CBC encoding and RSA 1_5 encryption algorithm. I also checked the box to create encrypted key. I want to recreate there settings with python code, using the following code:
from zeep.wsse.utils
import base64
from zeep.wsse.utils import get_security_header
import xmlsec
from lxml import etree
def encrypt(envelope, certfile):
"""Encrypt body contents of given SOAP envelope using given X509 cert."""
doc = etree.fromstring(envelope)
security = get_security_header(doc)
# Create a keys manager and load the cert into it.
manager = xmlsec.KeysManager()
key = xmlsec.Key.from_file(certfile, xmlsec.KeyFormat.CERT_PEM, None)
manager.add_key(key)
body = doc.find(ns(SOAP_NS, 'Body'))
enc_data = xmlsec.template.encrypted_data_create(
body,
xmlsec.constants.TransformAes256Cbc,
type=xmlsec.EncryptionType.CONTENT,
ns='xenc',
)
xmlsec.template.encrypted_data_ensure_cipher_value(enc_data)
key_info = xmlsec.template.encrypted_data_ensure_key_info(
enc_data, ns='ds')
enc_key = xmlsec.template.add_encrypted_key(
key_info, xmlsec.constants.TransformRsaPkcs1)
#enc_key.append(create_key_info_ski(certfile))
xmlsec.template.encrypted_data_ensure_cipher_value(enc_key)
enc_ctx = xmlsec.EncryptionContext(manager)
# Generate a per-session AES key (will be encrypted using the cert).
enc_ctx.key = xmlsec.Key.generate(
xmlsec.constants.KeyDataAes, 256, xmlsec.constants.KeyDataTypeSession)
# Ask XMLSec to actually do the encryption.
enc_data = enc_ctx.encrypt_xml(enc_data, body)
# Move the EncryptedKey node up into the wsse:Security header.
security.append(enc_key)
# Create DataReference element
add_data_reference(enc_key, enc_data)
enc_data.remove(key_info)
return doc
def create_key_info_ski(certfile):
key_info = etree.Element(f"{{{DS_NS}}}KeyInfo", nsmap=namespaces)
security_token_reference = etree.Element(f"{{{WSSE_NS}}}SecurityTokenReference")
key_identifier = etree.Element(f"{{{WSSE_NS}}}KeyIdentifier",
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier",
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary")
key_identifier.text = extract_ski(certfile)
security_token_reference.append(key_identifier)
key_info.append(security_token_reference)
return key_info
Everything seems ok if I don't use X509SubjectKeyIdentifier. So if I comment out line
#enc_key.append(create_key_info_ski(certfile))
I get the following error:
xmlsec.Error: (1, 'failed to encrypt xml')
Are keys correctly used? What am I missing?
EDIT:
Input envelope example:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:wse="http://.../wse">
<soap:Header/>
<soap:Body>
<wse:GetDateTime/>
</soap:Body>
</soap:Envelope>
Expected output:
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:wse="http://.../wse">
<soap:Header>
<wsse:Security
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<xenc:EncryptedKey Id="EK-ADF72CB9C6AC5D5A531716899228423321"
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
<ds:KeyInfo
xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier">...</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>...</xenc:CipherValue>
</xenc:CipherData>
<xenc:ReferenceList>
<xenc:DataReference URI="#ED-ADF72CB9C6AC5D5A531716899228424322"/>
</xenc:ReferenceList>
</xenc:EncryptedKey>
</wsse:Security>
</soap:Header>
<soap:Body>
<xenc:EncryptedData Id="ED-ADF72CB9C6AC5D5A531716899228424322" Type="http://www.w3.org/2001/04/xmlenc#Content"
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
<ds:KeyInfo
xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd">
<wsse:Reference URI="#EK-ADF72CB9C6AC5D5A531716899228423321"/>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>...</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</soap:Body>
</soap:Envelope>
Upvotes: 2
Views: 192