Java Code Examples for org.apache.xml.security.encryption.XMLCipher

The following examples show how to use org.apache.xml.security.encryption.XMLCipher. These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source Project: cxf   Source File: JAXRSXmlSecTest.java    License: Apache License 2.0 6 votes vote down vote up
@Test
public void testPostEncryptedBookSHA256() throws Exception {
    String address = "https://localhost:" + test.port + "/xmlenc/bookstore/books";
    Map<String, Object> properties = new HashMap<>();
    properties.put(SecurityConstants.CALLBACK_HANDLER,
                   "org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback");
    properties.put(SecurityConstants.ENCRYPT_USERNAME, "bob");
    properties.put(SecurityConstants.ENCRYPT_PROPERTIES,
                   "org/apache/cxf/systest/jaxrs/security/bob.properties");

    EncryptionProperties encryptionProperties = new EncryptionProperties();
    encryptionProperties.setEncryptionSymmetricKeyAlgo(XMLCipher.AES_128);
    encryptionProperties.setEncryptionKeyIdType(RSSecurityUtils.X509_CERT);
    encryptionProperties.setEncryptionDigestAlgo(XMLCipher.SHA256);

    doTestPostEncryptedBook(
        address, false, properties, encryptionProperties, false, test.streaming
    );
}
 
Example 2
Source Project: cxf   Source File: JAXRSXmlSecTest.java    License: Apache License 2.0 6 votes vote down vote up
@Test
public void testPostEncryptedBookIssuerSerial() throws Exception {
    String address = "https://localhost:" + test.port + "/xmlenc/bookstore/books";
    Map<String, Object> properties = new HashMap<>();
    properties.put(SecurityConstants.CALLBACK_HANDLER,
                   "org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback");
    properties.put(SecurityConstants.ENCRYPT_USERNAME, "bob");
    properties.put(SecurityConstants.ENCRYPT_PROPERTIES,
                   "org/apache/cxf/systest/jaxrs/security/bob.properties");

    EncryptionProperties encryptionProperties = new EncryptionProperties();
    encryptionProperties.setEncryptionSymmetricKeyAlgo(XMLCipher.AES_128);
    encryptionProperties.setEncryptionKeyIdType(RSSecurityUtils.X509_ISSUER_SERIAL);

    doTestPostEncryptedBook(
        address, false, properties, encryptionProperties, false, test.streaming
    );
}
 
Example 3
Source Project: keycloak   Source File: XMLEncryptionUtil.java    License: Apache License 2.0 6 votes vote down vote up
/**
 * From the secret key, get the W3C XML Encryption URL
 *
 * @param publicKeyAlgo
 * @param keySize
 *
 * @return
 */
private static String getXMLEncryptionURLForKeyUnwrap(String publicKeyAlgo, int keySize) {
    if ("AES".equals(publicKeyAlgo)) {
        switch (keySize) {
            case 192:
                return XMLCipher.AES_192_KeyWrap;
            case 256:
                return XMLCipher.AES_256_KeyWrap;
            default:
                return XMLCipher.AES_128_KeyWrap;
        }
    }
    if (publicKeyAlgo.contains("RSA"))
        return RSA_ENCRYPTION_SCHEME;
    throw logger.unsupportedType("unsupported publicKey Algo:" + publicKeyAlgo);
}
 
Example 4
Source Project: keycloak   Source File: XMLEncryptionUtil.java    License: Apache License 2.0 6 votes vote down vote up
/**
 * From the secret key, get the W3C XML Encryption URL
 *
 * @param secretKey
 * @param keySize
 *
 * @return
 */
private static String getXMLEncryptionURL(String algo, int keySize) {
    if ("AES".equals(algo)) {
        switch (keySize) {
            case 192:
                return XMLCipher.AES_192;
            case 256:
                return XMLCipher.AES_256;
            default:
                return XMLCipher.AES_128;
        }
    }
    if (algo.contains("RSA"))
        return XMLCipher.RSA_v1dot5;
    throw logger.unsupportedType("Secret Key with unsupported algo:" + algo);
}
 
Example 5
Source Project: cxf   Source File: JAXRSXmlSecTest.java    License: Apache License 2.0 5 votes vote down vote up
public void doTestPostEncryptedBook(String address, boolean sign, Map<String, Object> properties,
                                    boolean streaming)
    throws Exception {
    EncryptionProperties encryptionProperties = new EncryptionProperties();
    encryptionProperties.setEncryptionSymmetricKeyAlgo(XMLCipher.AES_128);
    encryptionProperties.setEncryptionKeyIdType(RSSecurityUtils.X509_CERT);
    doTestPostEncryptedBook(
        address, sign, properties, encryptionProperties, false, test.streaming
    );
}
 
Example 6
Source Project: cxf   Source File: EncryptionUtils.java    License: Apache License 2.0 5 votes vote down vote up
public static XMLCipher initXMLCipher(String symEncAlgo, int mode, Key key)
    throws WSSecurityException {
    try {
        XMLCipher cipher = XMLCipher.getInstance(symEncAlgo);
        cipher.setSecureValidation(true);
        cipher.init(mode, key);
        return cipher;
    } catch (XMLEncryptionException ex) {
        throw new WSSecurityException(WSSecurityException.ErrorCode.UNSUPPORTED_ALGORITHM, ex);
    }
}
 
Example 7
Source Project: cxf   Source File: SAMLProtocolResponseValidator.java    License: Apache License 2.0 5 votes vote down vote up
private byte[] decryptPayload(
    Element root, byte[] secretKeyBytes, String symEncAlgo
) throws WSSecurityException {
    SecretKey key = KeyUtils.prepareSecretKey(symEncAlgo, secretKeyBytes);
    try {
        XMLCipher xmlCipher =
            EncryptionUtils.initXMLCipher(symEncAlgo, XMLCipher.DECRYPT_MODE, key);
        return xmlCipher.decryptToByteArray(root);
    } catch (XMLEncryptionException ex) {
        throw new WSSecurityException(WSSecurityException.ErrorCode.UNSUPPORTED_ALGORITHM, ex);
    }
}
 
Example 8
Source Project: camel-cookbook-examples   Source File: SecurityAsymRoute.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public void configure() throws Exception {
    final boolean secureTagContents = true;

    final KeyStoreParameters trustStoreParameters = new KeyStoreParameters();
    trustStoreParameters.setResource("xml_truststore.jks");
    trustStoreParameters.setPassword("truststorePassword");

    final KeyStoreParameters keyStoreParameters = new KeyStoreParameters();
    keyStoreParameters.setResource("xml_keystore.jks");
    keyStoreParameters.setPassword("keystorePassword");

    from("direct:encrypt").id("encrypt")
        .marshal()
            .secureXML(
                "/booksignings/store/address", // secure tag
                secureTagContents,
                "system_a",                    // recipient key alias
                XMLCipher.TRIPLEDES,           // xml cipher
                XMLCipher.RSA_v1dot5,          // key cipher
                trustStoreParameters)
        .to("direct:decrypt");

    from("direct:decrypt").id("decrypt")
        .unmarshal()
            .secureXML(
                "/booksignings/store/address", // secure tag
                secureTagContents,
                "system_a",                    // recipient key alias
                XMLCipher.TRIPLEDES,           // xml cipher
                XMLCipher.RSA_v1dot5,          // key cipher
                keyStoreParameters,
                "keyPasswordA")                // key password
        .to("mock:out");
}
 
Example 9
@Override
public void configure() throws Exception {
    final boolean secureTagContents = true;

    final KeyStoreParameters trustStoreParameters = new KeyStoreParameters();
    trustStoreParameters.setResource("xml_truststore.jks");
    trustStoreParameters.setPassword("truststorePassword");

    final KeyStoreParameters keyStoreParameters = new KeyStoreParameters();
    keyStoreParameters.setResource("xml_keystore.jks");
    keyStoreParameters.setPassword("keystorePassword");

    final Map<String, String> namespaces = new HashMap<String, String>();
    namespaces.put("c", "http://camelcookbook.org/schema/booksignings");

    from("direct:encrypt").id("encrypt")
        .marshal()
            .secureXML(
                "/c:booksignings/c:store/c:address", // secure tag
                namespaces,
                secureTagContents,
                "system_a",                    // recipient key alias
                XMLCipher.TRIPLEDES,           // xml cipher
                XMLCipher.RSA_v1dot5,          // key cipher
                trustStoreParameters)
        .to("direct:decrypt");

    from("direct:decrypt").id("decrypt")
        .unmarshal()
            .secureXML(
                "/c:booksignings/c:store/c:address", // secure tag
                namespaces,
                secureTagContents,             // secure tag contents
                "system_a",                    // recipient key alias
                XMLCipher.TRIPLEDES,           // xml cipher
                XMLCipher.RSA_v1dot5,          // key cipher
                keyStoreParameters,
                "keyPasswordA")                // key password
        .to("mock:out");
}
 
Example 10
Source Project: keycloak   Source File: XMLEncryptionUtil.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * <p>
 * Encrypt the Key to be transported
 * </p>
 * <p>
 * Data is encrypted with a SecretKey. Then the key needs to be transported to the other end where it is needed for
 * decryption. For the Key transport, the SecretKey is encrypted with the recipient's public key. At the receiving
 * end, the
 * receiver can decrypt the Secret Key using his private key.s
 * </p>
 *
 * @param document
 * @param keyToBeEncrypted Symmetric Key (SecretKey)
 * @param keyUsedToEncryptSecretKey Asymmetric Key (Public Key)
 * @param keySize Length of the key
 *
 * @return
 *
 * @throws org.keycloak.saml.common.exceptions.ProcessingException
 */
public static EncryptedKey encryptKey(Document document, SecretKey keyToBeEncrypted, PublicKey keyUsedToEncryptSecretKey,
                                      int keySize) throws ProcessingException {
    XMLCipher keyCipher;
    String pubKeyAlg = keyUsedToEncryptSecretKey.getAlgorithm();

    try {
        String keyWrapAlgo = getXMLEncryptionURLForKeyUnwrap(pubKeyAlg, keySize);
        keyCipher = XMLCipher.getInstance(keyWrapAlgo);

        keyCipher.init(XMLCipher.WRAP_MODE, keyUsedToEncryptSecretKey);
        return keyCipher.encryptKey(document, keyToBeEncrypted);
    } catch (XMLEncryptionException e) {
        throw logger.processingError(e);
    }
}
 
Example 11
Source Project: cxf   Source File: JAXRSXmlSecTest.java    License: Apache License 2.0 4 votes vote down vote up
@Test
public void testEncryptionNoSignature() throws Exception {
    if (test.streaming) {
        // Only testing the endpoints, not the clients here
        return;
    }
    String address = "https://localhost:" + test.port + "/xmlsec-validate";

    JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
    bean.setAddress(address);

    SpringBusFactory bf = new SpringBusFactory();
    URL busFile = JAXRSXmlSecTest.class.getResource("client.xml");
    Bus springBus = bf.createBus(busFile.toString());
    bean.setBus(springBus);

    Map<String, Object> properties = new HashMap<>();
    properties.put(SecurityConstants.CALLBACK_HANDLER,
                   "org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback");
    properties.put(SecurityConstants.ENCRYPT_USERNAME, "bob");
    properties.put(SecurityConstants.ENCRYPT_PROPERTIES,
                   "org/apache/cxf/systest/jaxrs/security/bob.properties");
    properties.put(SecurityConstants.SIGNATURE_PROPERTIES,
                   "org/apache/cxf/systest/jaxrs/security/alice.properties");
    bean.setProperties(properties);

    XmlEncOutInterceptor encInterceptor = new XmlEncOutInterceptor();
    encInterceptor.setKeyIdentifierType(RSSecurityUtils.X509_CERT);
    encInterceptor.setSymmetricEncAlgorithm(XMLCipher.AES_128);
    bean.getOutInterceptors().add(encInterceptor);
    bean.getInInterceptors().add(new XmlEncInInterceptor());
    bean.getInInterceptors().add(new XmlSigInInterceptor());

    bean.setServiceClass(BookStore.class);

    BookStore store = bean.create(BookStore.class);
    try {
        store.addBook(new Book("CXF", 126L));
        fail("Failure expected on no Signature");
    } catch (WebApplicationException ex) {
        // expected
    }
}
 
Example 12
Source Project: cxf-fediz   Source File: SAMLEncryptedResponseTest.java    License: Apache License 2.0 4 votes vote down vote up
private void encryptElement(
        Document document,
        Element elementToEncrypt,
        String algorithm,
        Key encryptingKey,
        String keyTransportAlgorithm,
        X509Certificate wrappingCert,
        boolean content
) throws Exception {
    XMLCipher cipher = XMLCipher.getInstance(algorithm);
    cipher.init(XMLCipher.ENCRYPT_MODE, encryptingKey);

    if (wrappingCert != null) {
        XMLCipher newCipher = XMLCipher.getInstance(keyTransportAlgorithm);
        newCipher.init(XMLCipher.WRAP_MODE, wrappingCert.getPublicKey());

        EncryptedKey encryptedKey = newCipher.encryptKey(document, encryptingKey);
        // Create a KeyInfo for the EncryptedKey
        org.apache.xml.security.keys.KeyInfo encryptedKeyKeyInfo = encryptedKey.getKeyInfo();
        if (encryptedKeyKeyInfo == null) {
            encryptedKeyKeyInfo = new org.apache.xml.security.keys.KeyInfo(document);
            encryptedKeyKeyInfo.getElement().setAttributeNS(
                    "http://www.w3.org/2000/xmlns/", "xmlns:dsig", "http://www.w3.org/2000/09/xmldsig#"
            );
            encryptedKey.setKeyInfo(encryptedKeyKeyInfo);
        }

        X509Data x509Data = new X509Data(document);
        // x509Data.addCertificate(wrappingCert);
        x509Data.addIssuerSerial(wrappingCert.getIssuerX500Principal().getName(),
                wrappingCert.getSerialNumber());
        encryptedKeyKeyInfo.add(x509Data);

        // Create a KeyInfo for the EncryptedData
        EncryptedData builder = cipher.getEncryptedData();
        org.apache.xml.security.keys.KeyInfo builderKeyInfo = builder.getKeyInfo();
        if (builderKeyInfo == null) {
            builderKeyInfo = new org.apache.xml.security.keys.KeyInfo(document);
            builderKeyInfo.getElement().setAttributeNS(
                    "http://www.w3.org/2000/xmlns/", "xmlns:dsig", "http://www.w3.org/2000/09/xmldsig#"
            );
            builder.setKeyInfo(builderKeyInfo);
        }

        builderKeyInfo.add(encryptedKey);
    }

    cipher.doFinal(document, elementToEncrypt, content);
}
 
Example 13
Source Project: keycloak   Source File: XMLEncryptionUtil.java    License: Apache License 2.0 4 votes vote down vote up
/**
 * Given an element in a Document, encrypt the element and replace the element in the document with the encrypted
 * data
 *
 * @param elementQName QName of the element that we like to encrypt
 * @param document
 * @param publicKey
 * @param secretKey
 * @param keySize
 * @param wrappingElementQName A QName of an element that will wrap the encrypted element
 * @param addEncryptedKeyInKeyInfo Need for the EncryptedKey to be placed in ds:KeyInfo
 *
 * @throws ProcessingException
 */
public static void encryptElement(QName elementQName, Document document, PublicKey publicKey, SecretKey secretKey,
                                  int keySize, QName wrappingElementQName, boolean addEncryptedKeyInKeyInfo) throws ProcessingException {
    if (elementQName == null)
        throw logger.nullArgumentError("elementQName");
    if (document == null)
        throw logger.nullArgumentError("document");
    String wrappingElementPrefix = wrappingElementQName.getPrefix();
    if (wrappingElementPrefix == null || "".equals(wrappingElementPrefix))
        throw logger.wrongTypeError("Wrapping element prefix invalid");

    Element documentElement = DocumentUtil.getElement(document, elementQName);

    if (documentElement == null)
        throw logger.domMissingDocElementError(elementQName.toString());

    XMLCipher cipher = null;
    EncryptedKey encryptedKey = encryptKey(document, secretKey, publicKey, keySize);

    String encryptionAlgorithm = getXMLEncryptionURL(secretKey.getAlgorithm(), keySize);
    // Encrypt the Document
    try {
        cipher = XMLCipher.getInstance(encryptionAlgorithm);
        cipher.init(XMLCipher.ENCRYPT_MODE, secretKey);
    } catch (XMLEncryptionException e1) {
        throw logger.processingError(e1);
    }

    Document encryptedDoc;
    try {
        encryptedDoc = cipher.doFinal(document, documentElement);
    } catch (Exception e) {
        throw logger.processingError(e);
    }

    // The EncryptedKey element is added
    Element encryptedKeyElement = cipher.martial(document, encryptedKey);

    final String wrappingElementName;

    if (StringUtil.isNullOrEmpty(wrappingElementPrefix)) {
        wrappingElementName = wrappingElementQName.getLocalPart();
    } else {
        wrappingElementName = wrappingElementPrefix + ":" + wrappingElementQName.getLocalPart();
    }
    // Create the wrapping element and set its attribute NS
    Element wrappingElement = encryptedDoc.createElementNS(wrappingElementQName.getNamespaceURI(), wrappingElementName);

    if (! StringUtil.isNullOrEmpty(wrappingElementPrefix)) {
        wrappingElement.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:" + wrappingElementPrefix, wrappingElementQName.getNamespaceURI());
    }

    // Get Hold of the Cipher Data
    NodeList cipherElements = encryptedDoc.getElementsByTagNameNS(EncryptionConstants.EncryptionSpecNS, EncryptionConstants._TAG_ENCRYPTEDDATA);
    if (cipherElements == null || cipherElements.getLength() == 0)
        throw logger.domMissingElementError("xenc:EncryptedData");
    Element encryptedDataElement = (Element) cipherElements.item(0);

    Node parentOfEncNode = encryptedDataElement.getParentNode();
    parentOfEncNode.replaceChild(wrappingElement, encryptedDataElement);

    wrappingElement.appendChild(encryptedDataElement);

    if (addEncryptedKeyInKeyInfo) {
        // Outer ds:KeyInfo Element to hold the EncryptionKey
        Element sigElement = encryptedDoc.createElementNS(XMLSignature.XMLNS, DS_KEY_INFO);
        sigElement.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:ds", XMLSignature.XMLNS);
        sigElement.appendChild(encryptedKeyElement);

        // Insert the Encrypted key before the CipherData element
        NodeList nodeList = encryptedDoc.getElementsByTagNameNS(EncryptionConstants.EncryptionSpecNS, EncryptionConstants._TAG_CIPHERDATA);
        if (nodeList == null || nodeList.getLength() == 0)
            throw logger.domMissingElementError("xenc:CipherData");
        Element cipherDataElement = (Element) nodeList.item(0);
        Node cipherParent = cipherDataElement.getParentNode();
        cipherParent.insertBefore(sigElement, cipherDataElement);
    } else {
        // Add the encrypted key as a child of the wrapping element
        wrappingElement.appendChild(encryptedKeyElement);
    }
}
 
Example 14
Source Project: keycloak   Source File: XMLEncryptionUtil.java    License: Apache License 2.0 4 votes vote down vote up
/**
 * <p>
 * Encrypts an element in a XML document using the specified public key, secret key, and key size. This method
 * doesn't wrap
 * the encrypted element in a new element. Instead, it replaces the element with its encrypted version.
 * </p>
 * <p>
 * For example, calling this method to encrypt the <tt><b>inner</b></tt> element in the following XML document
 *
 * <pre>
 *    &lt;root&gt;
 *       &lt;outer&gt;
 *          &lt;inner&gt;
 *             ...
 *          &lt;/inner&gt;
 *       &lt;/outer&gt;
 *    &lt;/root&gt;
 * </pre>
 *
 * would result in a document similar to
 *
 * <pre>
 *    &lt;root&gt;
 *       &lt;outer&gt;
 *          &lt;xenc:EncryptedData xmlns:xenc="..."&gt;
 *             ...
 *          &lt;/xenc:EncryptedData&gt;
 *       &lt;/outer&gt;
 *    &lt;/root&gt;
 * </pre>
 *
 * </p>
 *
 * @param document the {@code Document} that contains the element to be encrypted.
 * @param element the {@code Element} to be encrypted.
 * @param publicKey the {@code PublicKey} that must be used to encrypt the secret key.
 * @param secretKey the {@code SecretKey} used to encrypt the specified element.
 * @param keySize the size (in bits) of the secret key.
 *
 * @throws ProcessingException if an error occurs while encrypting the element with the specified params.
 */
public static void encryptElement(Document document, Element element, PublicKey publicKey, SecretKey secretKey, int keySize)
        throws ProcessingException {
    if (element == null)
        throw logger.nullArgumentError("element");
    if (document == null)
        throw logger.nullArgumentError("document");

    XMLCipher cipher = null;
    EncryptedKey encryptedKey = encryptKey(document, secretKey, publicKey, keySize);
    String encryptionAlgorithm = getXMLEncryptionURL(secretKey.getAlgorithm(), keySize);

    // Encrypt the Document
    try {
        cipher = XMLCipher.getInstance(encryptionAlgorithm);
        cipher.init(XMLCipher.ENCRYPT_MODE, secretKey);
    } catch (XMLEncryptionException e1) {
        throw logger.processingError(e1);
    }

    Document encryptedDoc;
    try {
        encryptedDoc = cipher.doFinal(document, element);
    } catch (Exception e) {
        throw logger.processingError(e);
    }

    // The EncryptedKey element is added
    Element encryptedKeyElement = cipher.martial(document, encryptedKey);

    // Outer ds:KeyInfo Element to hold the EncryptionKey
    Element sigElement = encryptedDoc.createElementNS(XMLSignature.XMLNS, DS_KEY_INFO);
    sigElement.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:ds", XMLSignature.XMLNS);
    sigElement.appendChild(encryptedKeyElement);

    // Insert the Encrypted key before the CipherData element
    NodeList nodeList = encryptedDoc.getElementsByTagNameNS(EncryptionConstants.EncryptionSpecNS, EncryptionConstants._TAG_CIPHERDATA);
    if (nodeList == null || nodeList.getLength() == 0)
        throw logger.domMissingElementError("xenc:CipherData");
    Element cipherDataElement = (Element) nodeList.item(0);
    Node cipherParent = cipherDataElement.getParentNode();
    cipherParent.insertBefore(sigElement, cipherDataElement);
}
 
Example 15
Source Project: keycloak   Source File: XMLEncryptionUtil.java    License: Apache License 2.0 4 votes vote down vote up
/**
 * Encrypt the root document element inside a Document. <b>NOTE:</b> The document root element will be replaced by
 * the
 * wrapping element.
 *
 * @param document Document that contains an element to encrypt
 * @param publicKey The Public Key used to encrypt the secret encryption key
 * @param secretKey The secret encryption key
 * @param keySize Length of key
 * @param wrappingElementQName QName of the element to be used to wrap around the cipher data.
 * @param addEncryptedKeyInKeyInfo Should the encrypted key be inside a KeyInfo or added as a peer of Cipher Data
 *
 * @return An element that has the wrappingElementQName
 *
 * @throws ProcessingException
 * @throws org.keycloak.saml.common.exceptions.ConfigurationException
 */
public static Element encryptElementInDocument(Document document, PublicKey publicKey, SecretKey secretKey, int keySize,
                                               QName wrappingElementQName, boolean addEncryptedKeyInKeyInfo) throws ProcessingException, ConfigurationException {
    String wrappingElementPrefix = wrappingElementQName.getPrefix();
    if (wrappingElementPrefix == null || "".equals(wrappingElementPrefix))
        throw logger.wrongTypeError("Wrapping element prefix invalid");

    XMLCipher cipher = null;
    EncryptedKey encryptedKey = encryptKey(document, secretKey, publicKey, keySize);

    String encryptionAlgorithm = getXMLEncryptionURL(secretKey.getAlgorithm(), keySize);
    // Encrypt the Document
    try {
        cipher = XMLCipher.getInstance(encryptionAlgorithm);
        cipher.init(XMLCipher.ENCRYPT_MODE, secretKey);
    } catch (XMLEncryptionException e1) {
        throw logger.configurationError(e1);
    }

    Document encryptedDoc;
    try {
        encryptedDoc = cipher.doFinal(document, document.getDocumentElement());
    } catch (Exception e) {
        throw logger.processingError(e);
    }

    // The EncryptedKey element is added
    Element encryptedKeyElement = cipher.martial(document, encryptedKey);

    final String wrappingElementName;

    if (StringUtil.isNullOrEmpty(wrappingElementPrefix)) {
        wrappingElementName = wrappingElementQName.getLocalPart();
    } else {
        wrappingElementName = wrappingElementPrefix + ":" + wrappingElementQName.getLocalPart();
    }
    // Create the wrapping element and set its attribute NS
    Element wrappingElement = encryptedDoc.createElementNS(wrappingElementQName.getNamespaceURI(), wrappingElementName);

    if (! StringUtil.isNullOrEmpty(wrappingElementPrefix)) {
        wrappingElement.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:" + wrappingElementPrefix, wrappingElementQName.getNamespaceURI());
    }

    Element encryptedDocRootElement = encryptedDoc.getDocumentElement();
    // Bring in the encrypted wrapping element to wrap the root node
    encryptedDoc.replaceChild(wrappingElement, encryptedDocRootElement);

    wrappingElement.appendChild(encryptedDocRootElement);

    if (addEncryptedKeyInKeyInfo) {
        // Outer ds:KeyInfo Element to hold the EncryptionKey
        Element sigElement = encryptedDoc.createElementNS(XMLSignature.XMLNS, DS_KEY_INFO);
        sigElement.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:ds", XMLSignature.XMLNS);
        sigElement.appendChild(encryptedKeyElement);

        // Insert the Encrypted key before the CipherData element
        NodeList nodeList = encryptedDocRootElement.getElementsByTagNameNS(EncryptionConstants.EncryptionSpecNS, EncryptionConstants._TAG_CIPHERDATA);
        if (nodeList == null || nodeList.getLength() == 0)
            throw logger.domMissingElementError("xenc:CipherData");

        Element cipherDataElement = (Element) nodeList.item(0);
        encryptedDocRootElement.insertBefore(sigElement, cipherDataElement);
    } else {
        // Add the encrypted key as a child of the wrapping element
        wrappingElement.appendChild(encryptedKeyElement);
    }

    return encryptedDoc.getDocumentElement();
}