Search in sources :

Example 76 with XMLCipher

use of org.apache.xml.security.encryption.XMLCipher in project keycloak by keycloak.

the class XMLEncryptionUtil method decryptElementInDocument.

/**
 * Decrypt an encrypted element inside a document
 *
 * @param documentWithEncryptedElement
 * @param privateKey key need to unwrap the encryption key
 *
 * @return the document with the encrypted element replaced by the data element
 */
public static Element decryptElementInDocument(Document documentWithEncryptedElement, PrivateKey privateKey) throws ProcessingException {
    if (documentWithEncryptedElement == null)
        throw logger.nullArgumentError("Input document is null");
    // Look for encrypted data element
    Element documentRoot = documentWithEncryptedElement.getDocumentElement();
    Element encDataElement = getNextElementNode(documentRoot.getFirstChild());
    if (encDataElement == null)
        throw logger.domMissingElementError("No element representing the encrypted data found");
    // Look at siblings for the key
    Element encKeyElement = getNextElementNode(encDataElement.getNextSibling());
    if (encKeyElement == null) {
        // Search the enc data element for enc key
        NodeList nodeList = encDataElement.getElementsByTagNameNS(EncryptionConstants.EncryptionSpecNS, EncryptionConstants._TAG_ENCRYPTEDKEY);
        if (nodeList == null || nodeList.getLength() == 0)
            throw logger.nullValueError("Encrypted Key not found in the enc data");
        encKeyElement = (Element) nodeList.item(0);
    }
    XMLCipher cipher;
    EncryptedData encryptedData;
    EncryptedKey encryptedKey;
    try {
        cipher = XMLCipher.getInstance();
        cipher.init(XMLCipher.DECRYPT_MODE, null);
        encryptedData = cipher.loadEncryptedData(documentWithEncryptedElement, encDataElement);
        encryptedKey = cipher.loadEncryptedKey(documentWithEncryptedElement, encKeyElement);
    } catch (XMLEncryptionException e1) {
        throw logger.processingError(e1);
    }
    Document decryptedDoc = null;
    if (encryptedData != null && encryptedKey != null) {
        try {
            String encAlgoURL = encryptedData.getEncryptionMethod().getAlgorithm();
            XMLCipher keyCipher = XMLCipher.getInstance();
            keyCipher.init(XMLCipher.UNWRAP_MODE, privateKey);
            Key encryptionKey = keyCipher.decryptKey(encryptedKey, encAlgoURL);
            cipher = XMLCipher.getInstance();
            cipher.init(XMLCipher.DECRYPT_MODE, encryptionKey);
            decryptedDoc = cipher.doFinal(documentWithEncryptedElement, encDataElement);
        } catch (Exception e) {
            throw logger.processingError(e);
        }
    }
    if (decryptedDoc == null) {
        throw logger.nullValueError("decryptedDoc");
    }
    Element decryptedRoot = decryptedDoc.getDocumentElement();
    Element dataElement = getNextElementNode(decryptedRoot.getFirstChild());
    if (dataElement == null)
        throw logger.nullValueError("Data Element after encryption is null");
    decryptedRoot.removeChild(dataElement);
    decryptedDoc.replaceChild(dataElement, decryptedRoot);
    return decryptedDoc.getDocumentElement();
}
Also used : EncryptedKey(org.apache.xml.security.encryption.EncryptedKey) Element(org.w3c.dom.Element) NodeList(org.w3c.dom.NodeList) XMLCipher(org.apache.xml.security.encryption.XMLCipher) EncryptedData(org.apache.xml.security.encryption.EncryptedData) Document(org.w3c.dom.Document) PublicKey(java.security.PublicKey) EncryptedKey(org.apache.xml.security.encryption.EncryptedKey) Key(java.security.Key) PrivateKey(java.security.PrivateKey) SecretKey(javax.crypto.SecretKey) ProcessingException(org.keycloak.saml.common.exceptions.ProcessingException) XMLEncryptionException(org.apache.xml.security.encryption.XMLEncryptionException) ConfigurationException(org.keycloak.saml.common.exceptions.ConfigurationException) XMLEncryptionException(org.apache.xml.security.encryption.XMLEncryptionException)

Example 77 with XMLCipher

use of org.apache.xml.security.encryption.XMLCipher in project keycloak by keycloak.

the class XMLEncryptionUtil method encryptElement.

/**
 * 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);
    }
}
Also used : EncryptedKey(org.apache.xml.security.encryption.EncryptedKey) Element(org.w3c.dom.Element) NodeList(org.w3c.dom.NodeList) Node(org.w3c.dom.Node) XMLCipher(org.apache.xml.security.encryption.XMLCipher) Document(org.w3c.dom.Document) ProcessingException(org.keycloak.saml.common.exceptions.ProcessingException) XMLEncryptionException(org.apache.xml.security.encryption.XMLEncryptionException) ConfigurationException(org.keycloak.saml.common.exceptions.ConfigurationException) XMLEncryptionException(org.apache.xml.security.encryption.XMLEncryptionException)

Example 78 with XMLCipher

use of org.apache.xml.security.encryption.XMLCipher in project keycloak by keycloak.

the class XMLEncryptionUtil method encryptKey.

/**
 * <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);
    }
}
Also used : XMLCipher(org.apache.xml.security.encryption.XMLCipher) XMLEncryptionException(org.apache.xml.security.encryption.XMLEncryptionException)

Example 79 with XMLCipher

use of org.apache.xml.security.encryption.XMLCipher in project keycloak by keycloak.

the class XMLEncryptionUtil method encryptElementInDocument.

/**
 * 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();
}
Also used : EncryptedKey(org.apache.xml.security.encryption.EncryptedKey) Element(org.w3c.dom.Element) NodeList(org.w3c.dom.NodeList) XMLCipher(org.apache.xml.security.encryption.XMLCipher) Document(org.w3c.dom.Document) ProcessingException(org.keycloak.saml.common.exceptions.ProcessingException) XMLEncryptionException(org.apache.xml.security.encryption.XMLEncryptionException) ConfigurationException(org.keycloak.saml.common.exceptions.ConfigurationException) XMLEncryptionException(org.apache.xml.security.encryption.XMLEncryptionException)

Aggregations

XMLCipher (org.apache.xml.security.encryption.XMLCipher)79 Document (org.w3c.dom.Document)54 EncryptedKey (org.apache.xml.security.encryption.EncryptedKey)51 NodeList (org.w3c.dom.NodeList)48 SecretKey (javax.crypto.SecretKey)41 Element (org.w3c.dom.Element)37 DocumentBuilder (javax.xml.parsers.DocumentBuilder)30 InputStream (java.io.InputStream)29 KeyGenerator (javax.crypto.KeyGenerator)25 ArrayList (java.util.ArrayList)22 EncryptedData (org.apache.xml.security.encryption.EncryptedData)22 Key (java.security.Key)19 ByteArrayInputStream (java.io.ByteArrayInputStream)16 KeyInfo (org.apache.xml.security.keys.KeyInfo)16 PrivateKey (java.security.PrivateKey)15 ByteArrayOutputStream (java.io.ByteArrayOutputStream)13 DOMSource (javax.xml.transform.dom.DOMSource)13 XMLStreamReader (javax.xml.stream.XMLStreamReader)11 StreamResult (javax.xml.transform.stream.StreamResult)11 XMLEncryptionException (org.apache.xml.security.encryption.XMLEncryptionException)11