import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.apache.xerces.parsers.DOMParser;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;

import com.ibm.xml.enc.AlgorithmFactoryExtn;
import com.ibm.xml.enc.EncryptionContext;
import com.ibm.xml.enc.KeyInfoResolver;
import com.ibm.xml.enc.KeyInfoResolvingException;
import com.ibm.xml.enc.StructureException;
import com.ibm.xml.enc.util.KeyStoreKeyInfoResolver;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import java.io.IOException;
import java.io.InputStream;
import java.io.File;
import java.io.FileInputStream;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.cert.CertificateException;


public class XMLEncryptionSample {
    public static void main(String[] args) {
        try {

          /******** Step 1: Author a SOAP message.**********/

            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document soapDoc = db.newDocument();

            Element soapEnv = soapDoc.createElementNS("http://www.w3.org/2001/12/soap-envelope","Envelope");
            Element soapHeader = soapDoc.createElementNS("http://www.w3.org/2001/12/soap-envelope","Header");
            soapEnv.appendChild(soapHeader);

            Element soapBody = soapDoc.createElementNS("http://www.w3.org/2001/12/soap-envelope","Body");
            soapEnv.appendChild(soapBody);

            Element hotelBookingResponse = soapDoc.createElementNS(
                                 "http://www.MyHotel.com/partnerservice/",
                                 "GetSpecialDiscountedBookingForPartnersResponse");
            hotelBookingResponse.appendChild(
                soapDoc.createElementNS(
                    "http://www.MyHotel.com/partnerservice/",
                    "BookingDetails"));

            soapBody.appendChild(hotelBookingResponse);
            soapDoc.appendChild(soapEnv);

            System.out.println("The SOAP message:");
            printDocument(soapDoc);
            System.out.println();

            /******************* End of step 1 **********************/



            /********************************************************
             Step 2: Load the encryption template into a DOM obejct.
             ********************************************************/

            DOMParser dp = new DOMParser();
            dp.parse("EncryptionTemplate.xml");
            Element encryptionTemplate = dp.getDocument().getDocumentElement();

            /********************* End of step 2 ********************/



            /******** Step 3: Create a key resolver object.**********/

            // Load a key store into a KeyStore object.
            KeyStore store = KeyStore.getInstance("jceks");
            File f = new File("tourOperatorRSAKey");
            InputStream is = null;             if (f.exists()) {
                is = new FileInputStream(f);
            }
            char[] storePass;
            storePass = new String("myKeyStorePass").toCharArray();
            store.load(is, storePass);

            // Create a new KeyStoreKeyInfoResolver object.
            KeyStoreKeyInfoResolver kiRes = new KeyStoreKeyInfoResolver(store);

            // Instantiate an algo factory. 
            AlgorithmFactoryExtn af = new AlgorithmFactoryExtn();

            // Set the algo factory for use by the key resolver.
            kiRes.setAlgorithmFactory(af);

            // The key resolver needs to know the key pass.
            char keyPass[];
            keyPass = new String ("myKeyPass").toCharArray();
            kiRes.putAliasAndPassword("myTourOperatorKey", keyPass);

            // Set the mode of operation of the key resolver to "encryption".  
            kiRes.setOperationMode(KeyInfoResolver.ENCRYPT_MODE);

            /******************* End of step 3 **********************/



            /******** Step 4: Create a key resolver object.**********/

            EncryptionContext ec = new EncryptionContext();
            ec.setAlgorithmFactory(af);
            ec.setKeyInfoResolver(kiRes);
            ec.setData(hotelBookingResponse);
            ec.setEncryptedType((Element)encryptionTemplate.cloneNode(true),
                                null, null, null);
            ec.encrypt();
            ec.replace();

            /******** End of step 4 *********************************/


            System.out.println("The XML encrypted message:");
            printDocument(soapDoc);
            System.out.println();


        }//try
        catch (Exception e) {
            e.printStackTrace();
        }//catch

    }//main


    static void printDocument(Document doc) throws IOException {
        OutputFormat of = new OutputFormat(doc);
        of.setPreserveSpace(true);
        XMLSerializer xs = new XMLSerializer(System.out, of);
        xs.serialize(doc);
        System.out.println();
    }//printDocument

}//class