Search in sources :

Example 36 with XMLCipher

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

the class XMLSecurityDataFormat method encryptAsymmetric.

/**
     * Configure the public key for the asymmetric key wrap algorithm, create the key cipher, and delegate
     * to common encryption method.
     * 
     * The method first checks the exchange for a declared key alias, and will fall back to the
     * statically-defined instance variable if no value is found in the exchange. This allows different
     * aliases / keys to be used for multiple-recipient messaging integration patterns such as CBR
     * or recipient list.
     */
private void encryptAsymmetric(Exchange exchange, Document document, OutputStream stream) throws Exception {
    String exchangeRecipientAlias = getRecipientKeyAlias(exchange);
    if (null == exchangeRecipientAlias) {
        throw new IllegalStateException("The  recipient's key alias must be defined for asymmetric key encryption.");
    }
    if (trustStore == null && null != this.keyOrTrustStoreParameters) {
        trustStore = keyOrTrustStoreParameters.createKeyStore();
        trustStorePassword = keyOrTrustStoreParameters.getPassword();
    }
    if (null == trustStore) {
        throw new IllegalStateException("A trust store must be defined for asymmetric key encryption.");
    }
    String password = this.keyPassword != null ? this.keyPassword : this.trustStorePassword;
    Key keyEncryptionKey = getPublicKey(this.trustStore, exchangeRecipientAlias, password);
    if (null == keyEncryptionKey) {
        throw new IllegalStateException("No key for the alias [ " + exchangeRecipientAlias + " ] exists in " + "the configured trust store.");
    }
    Key dataEncryptionKey = generateDataEncryptionKey();
    XMLCipher keyCipher;
    if (null != this.getKeyCipherAlgorithm()) {
        keyCipher = XMLCipher.getInstance(this.getKeyCipherAlgorithm(), null, digestAlgorithm);
    } else {
        keyCipher = XMLCipher.getInstance(XMLCipher.RSA_OAEP, null, digestAlgorithm);
    }
    keyCipher.init(XMLCipher.WRAP_MODE, keyEncryptionKey);
    encrypt(exchange, document, stream, dataEncryptionKey, keyCipher, keyEncryptionKey);
}
Also used : XMLCipher(org.apache.xml.security.encryption.XMLCipher) PublicKey(java.security.PublicKey) EncryptedKey(org.apache.xml.security.encryption.EncryptedKey) Key(java.security.Key) PrivateKey(java.security.PrivateKey)

Example 37 with XMLCipher

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

the class XMLSecurityDataFormat method decode.

private Object decode(Exchange exchange, Document encodedDocument, Key keyEncryptionKey) throws Exception {
    XMLCipher xmlCipher = XMLCipher.getInstance();
    xmlCipher.setSecureValidation(true);
    xmlCipher.init(XMLCipher.DECRYPT_MODE, null);
    xmlCipher.setKEK(keyEncryptionKey);
    if (secureTag.equalsIgnoreCase("")) {
        checkEncryptionAlgorithm(keyEncryptionKey, encodedDocument.getDocumentElement());
        encodedDocument = xmlCipher.doFinal(encodedDocument, encodedDocument.getDocumentElement());
    } else {
        XPathBuilder xpathBuilder = new XPathBuilder(secureTag);
        xpathBuilder.setNamespaceContext(getNamespaceContext());
        NodeList nodeList = xpathBuilder.evaluate(exchange, NodeList.class);
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node node = nodeList.item(i);
            encodedDocument = node.getOwnerDocument();
            if (getSecureTagContents()) {
                checkEncryptionAlgorithm(keyEncryptionKey, (Element) node);
                Document temp = xmlCipher.doFinal(encodedDocument, (Element) node, true);
                encodedDocument.importNode(temp.getDocumentElement().cloneNode(true), true);
            } else {
                NodeList childNodes = node.getChildNodes();
                for (int j = 0; j < childNodes.getLength(); j++) {
                    Node childNode = childNodes.item(j);
                    if (childNode.getLocalName().equals("EncryptedData")) {
                        checkEncryptionAlgorithm(keyEncryptionKey, (Element) childNode);
                        Document temp = xmlCipher.doFinal(encodedDocument, (Element) childNode, false);
                        encodedDocument.importNode(temp.getDocumentElement().cloneNode(true), true);
                    }
                }
            }
        }
    }
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    try {
        DOMSource source = new DOMSource(encodedDocument);
        InputStream sis = exchange.getContext().getTypeConverter().mandatoryConvertTo(InputStream.class, source);
        IOHelper.copy(sis, bos);
    } finally {
        bos.close();
    }
    // Return the decrypted data
    return bos.toByteArray();
}
Also used : DOMSource(javax.xml.transform.dom.DOMSource) InputStream(java.io.InputStream) NodeList(org.w3c.dom.NodeList) Node(org.w3c.dom.Node) XMLCipher(org.apache.xml.security.encryption.XMLCipher) XPathBuilder(org.apache.camel.builder.xml.XPathBuilder) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Document(org.w3c.dom.Document)

Example 38 with XMLCipher

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

the class XMLSecurityDataFormat method encrypt.

private void encrypt(Exchange exchange, Document document, OutputStream stream, Key dataEncryptionKey, XMLCipher keyCipher, Key keyEncryptionKey) throws Exception {
    XMLCipher xmlCipher = XMLCipher.getInstance(xmlCipherAlgorithm);
    xmlCipher.init(XMLCipher.ENCRYPT_MODE, dataEncryptionKey);
    if (secureTag.equalsIgnoreCase("")) {
        embedKeyInfoInEncryptedData(document, keyCipher, xmlCipher, dataEncryptionKey, keyEncryptionKey);
        document = xmlCipher.doFinal(document, document.getDocumentElement());
    } else {
        XPathBuilder xpathBuilder = new XPathBuilder(secureTag);
        xpathBuilder.setNamespaceContext(getNamespaceContext());
        NodeList nodeList = xpathBuilder.evaluate(exchange, NodeList.class);
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node node = nodeList.item(i);
            document = node.getOwnerDocument();
            embedKeyInfoInEncryptedData(node.getOwnerDocument(), keyCipher, xmlCipher, dataEncryptionKey, keyEncryptionKey);
            Document temp = xmlCipher.doFinal(node.getOwnerDocument(), (Element) node, getSecureTagContents());
            document.importNode(temp.getDocumentElement().cloneNode(true), true);
        }
    }
    try {
        DOMSource source = new DOMSource(document);
        InputStream sis = exchange.getContext().getTypeConverter().mandatoryConvertTo(InputStream.class, source);
        IOHelper.copy(sis, stream);
    } finally {
        stream.close();
    }
}
Also used : DOMSource(javax.xml.transform.dom.DOMSource) InputStream(java.io.InputStream) NodeList(org.w3c.dom.NodeList) Node(org.w3c.dom.Node) XMLCipher(org.apache.xml.security.encryption.XMLCipher) XPathBuilder(org.apache.camel.builder.xml.XPathBuilder) Document(org.w3c.dom.Document)

Example 39 with XMLCipher

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

the class FMEncProvider method getSecretKey.

@Override
public SecretKey getSecretKey(String xmlString, Set<PrivateKey> privateKeys) throws SAML2Exception {
    String classMethod = "FMEncProvider.getSecretKey: ";
    if (SAML2SDKUtils.debug.messageEnabled()) {
        SAML2SDKUtils.debug.message(classMethod + "Entering ...");
    }
    if (xmlString == null || xmlString.length() == 0 || privateKeys == null) {
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("nullInput"));
    }
    Document doc = XMLUtils.toDOMDocument(xmlString, SAML2SDKUtils.debug);
    if (doc == null) {
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("errorObtainingElement"));
    }
    Element rootElement = doc.getDocumentElement();
    if (rootElement == null) {
        SAML2SDKUtils.debug.error(classMethod + "Empty document.");
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("emptyDoc"));
    }
    Element firstChild = getNextElementNode(rootElement.getFirstChild());
    if (firstChild == null) {
        SAML2SDKUtils.debug.error(classMethod + "Missing the EncryptedData element.");
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("missingElementEncryptedData"));
    }
    Element secondChild = getNextElementNode(firstChild.getNextSibling());
    if (secondChild == null) {
        if (SAML2SDKUtils.debug.messageEnabled()) {
            SAML2SDKUtils.debug.message(classMethod + "looking for encrytion key inside first child.");
        }
        NodeList nl = firstChild.getElementsByTagNameNS(SAML2Constants.NS_XMLENC, "EncryptedKey");
        if ((nl == null) || (nl.getLength() == 0)) {
            SAML2SDKUtils.debug.error(classMethod + "Missing the EncryptedKey element.");
            throw new SAML2Exception(SAML2SDKUtils.bundle.getString("missingElementEncryptedKey"));
        } else {
            // use the first EncryptedKey found
            secondChild = (Element) nl.item(0);
        }
    }
    XMLCipher cipher = null;
    try {
        cipher = XMLCipher.getInstance();
    } catch (XMLEncryptionException xe1) {
        SAML2SDKUtils.debug.error(classMethod + "Unable to get a cipher instance.", xe1);
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("noCipher"));
    }
    try {
        cipher.init(XMLCipher.DECRYPT_MODE, null);
    } catch (XMLEncryptionException xe2) {
        SAML2SDKUtils.debug.error(classMethod + "Failed to initialize cipher for decryption mode", xe2);
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("failedInitCipherForDecrypt"));
    }
    EncryptedData encryptedData = null;
    try {
        encryptedData = cipher.loadEncryptedData(doc, firstChild);
    } catch (XMLEncryptionException xe3) {
        SAML2SDKUtils.debug.error(classMethod + "Failed to load encrypted data", xe3);
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("failedLoadingEncryptedData"));
    }
    EncryptedKey encryptedKey = null;
    try {
        encryptedKey = cipher.loadEncryptedKey(doc, secondChild);
    } catch (XMLEncryptionException xe4) {
        SAML2SDKUtils.debug.error(classMethod + "Failed to load encrypted key", xe4);
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("failedLoadingEncryptedKey"));
    }
    if ((encryptedKey != null) && (encryptedData != null)) {
        XMLCipher keyCipher;
        try {
            keyCipher = XMLCipher.getInstance();
        } catch (XMLEncryptionException xe5) {
            SAML2SDKUtils.debug.error(classMethod + "Failed to get a cipher instance for decrypting secret key.", xe5);
            throw new SAML2Exception(SAML2SDKUtils.bundle.getString("noCipher"));
        }
        return (SecretKey) getEncryptionKey(keyCipher, privateKeys, encryptedKey, encryptedData.getEncryptionMethod().getAlgorithm());
    }
    return null;
}
Also used : SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) SecretKey(javax.crypto.SecretKey) 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) XMLEncryptionException(org.apache.xml.security.encryption.XMLEncryptionException)

Example 40 with XMLCipher

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

the class FMEncProvider method encrypt.

/**
     * Encrypts the root element of the given XML document.
     * @param xmlString String representing an XML document whose root
     *                  element is to be encrypted.
     * @param recipientPublicKey Public key used to encrypt the data encryption
     *                           (secret) key, it is the public key of the
     *                           recipient of the XML document to be encrypted.
     * @param secretKey the secret key used to encrypted data.
     * @param dataEncAlgorithm Data encryption algorithm.
     * @param dataEncStrength Data encryption strength.
     * @param recipientEntityID Unique identifier of the recipient, it is used
     *                          as the index to the cached secret key so that
     *                          the key can be reused for the same recipient;
     *                          It can be null in which case the secret key will
     *                          be generated every time and will not be cached
     *                          and reused. Note that the generation of a secret
     *                          key is a relatively expensive operation.
     * @param outerElementName Name of the element that will wrap around the
     *                         encrypted data and encrypted key(s) sub-elements
     * @return org.w3c.dom.Element Root element of the encypted document; The
     *                             name of this root element is indicated by
     *                             the last input parameter
     * @exception SAML2Exception if there is an error during the encryption
     *                           process
     */
public Element encrypt(String xmlString, Key recipientPublicKey, SecretKey secretKey, String dataEncAlgorithm, int dataEncStrength, String recipientEntityID, String outerElementName) throws SAML2Exception {
    String classMethod = "FMEncProvider.encrypt: ";
    // checking the input parameters
    if (xmlString == null || xmlString.length() == 0 || recipientPublicKey == null || dataEncAlgorithm == null || dataEncAlgorithm.length() == 0 || outerElementName == null || outerElementName.length() == 0) {
        SAML2SDKUtils.debug.error(classMethod + "Null input parameter(s).");
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("nullInput"));
    }
    if (!dataEncAlgorithm.equals(XMLCipher.AES_128) && !dataEncAlgorithm.equals(XMLCipher.AES_192) && !dataEncAlgorithm.equals(XMLCipher.AES_256) && !dataEncAlgorithm.equals(XMLCipher.TRIPLEDES)) {
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("unsupportedKeyAlg"));
    }
    if ((dataEncAlgorithm.equals(XMLCipher.AES_128) && dataEncStrength != 128) || (dataEncAlgorithm.equals(XMLCipher.AES_192) && dataEncStrength != 192) || (dataEncAlgorithm.equals(XMLCipher.AES_256) && dataEncStrength != 256)) {
        SAML2SDKUtils.debug.error(classMethod + "Data encryption algorithm " + dataEncAlgorithm + "and strength " + dataEncStrength + " mismatch.");
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("algSizeMismatch"));
    }
    Document doc = XMLUtils.toDOMDocument(xmlString, SAML2SDKUtils.debug);
    if (doc == null) {
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("errorObtainingElement"));
    }
    if (dataEncStrength <= 0) {
        dataEncStrength = 128;
    }
    Element rootElement = doc.getDocumentElement();
    if (rootElement == null) {
        SAML2SDKUtils.debug.error(classMethod + "Empty document.");
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("emptyDoc"));
    }
    // start of obtaining secret key
    if (secretKey == null) {
        if (recipientEntityID != null) {
            if (cachedKeys.containsKey(recipientEntityID)) {
                secretKey = (SecretKey) cachedKeys.get(recipientEntityID);
            } else {
                secretKey = generateSecretKey(dataEncAlgorithm, dataEncStrength);
                cachedKeys.put(recipientEntityID, secretKey);
            }
        } else {
            secretKey = generateSecretKey(dataEncAlgorithm, dataEncStrength);
        }
        if (secretKey == null) {
            throw new SAML2Exception(SAML2SDKUtils.bundle.getString("errorGenerateKey"));
        }
    }
    // end of obtaining secret key
    XMLCipher cipher = null;
    // start of encrypting the secret key with public key
    String publicKeyEncAlg = recipientPublicKey.getAlgorithm();
    /* note that the public key encryption algorithm could only
	 * have three possible values here: "RSA", "AES", "DESede"
	 */
    try {
        if (publicKeyEncAlg.equals(EncryptionConstants.RSA)) {
            cipher = XMLCipher.getInstance(XMLCipher.RSA_v1dot5);
        } else if (publicKeyEncAlg.equals(EncryptionConstants.TRIPLEDES)) {
            cipher = XMLCipher.getInstance(XMLCipher.TRIPLEDES_KeyWrap);
        } else if (publicKeyEncAlg.equals(EncryptionConstants.AES)) {
            cipher = XMLCipher.getInstance(XMLCipher.AES_128_KeyWrap);
        } else {
            throw new SAML2Exception(SAML2SDKUtils.bundle.getString("unsupportedKeyAlg"));
        }
    } catch (XMLEncryptionException xe1) {
        SAML2SDKUtils.debug.error(classMethod + "Unable to obtain cipher with public key algorithm.", xe1);
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("noCipherForPublicKeyAlg"));
    }
    try {
        cipher.init(XMLCipher.WRAP_MODE, recipientPublicKey);
    } catch (XMLEncryptionException xe2) {
        SAML2SDKUtils.debug.error(classMethod + "Failed to initialize cipher with public key", xe2);
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("failedInitCipherWithPublicKey"));
    }
    EncryptedKey encryptedKey = null;
    try {
        encryptedKey = cipher.encryptKey(doc, secretKey);
    } catch (XMLEncryptionException xe3) {
        SAML2SDKUtils.debug.error(classMethod + "Failed to encrypt secret key with public key", xe3);
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("failedEncryptingSecretKeyWithPublicKey"));
    }
    // start of doing data encryption
    try {
        cipher = XMLCipher.getInstance(dataEncAlgorithm);
    } catch (XMLEncryptionException xe4) {
        SAML2SDKUtils.debug.error(classMethod + "Failed to obtain a cipher for " + "data encryption algorithm" + dataEncAlgorithm, xe4);
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("cipherNotAvailableForDataEncAlg"));
    }
    try {
        cipher.init(XMLCipher.ENCRYPT_MODE, secretKey);
    } catch (XMLEncryptionException xe5) {
        SAML2SDKUtils.debug.error(classMethod + "Failed to initialize cipher with secret key.", xe5);
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("failedInitCipherWithSecretKey"));
    }
    Document resultDoc = null;
    try {
        resultDoc = cipher.doFinal(doc, rootElement);
    } catch (Exception e) {
        SAML2SDKUtils.debug.error(classMethod + "Failed to do the final data encryption.", e);
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("failedEncryptingData"));
    }
    // end of doing data encryption
    // add the EncryptedKey element
    Element ek = null;
    try {
        ek = cipher.martial(doc, encryptedKey);
    } catch (Exception xe6) {
        SAML2SDKUtils.debug.error(classMethod + "Failed to martial the encrypted key", xe6);
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("failedMartialingEncryptedKey"));
    }
    String outerElemNS = SAML2Constants.ASSERTION_NAMESPACE_URI;
    String outerElemPrefix = "saml";
    if (outerElementName.equals("NewEncryptedID")) {
        outerElemNS = SAML2Constants.PROTOCOL_NAMESPACE;
        outerElemPrefix = "samlp";
    }
    Element outerElement = resultDoc.createElementNS(outerElemNS, outerElemPrefix + ":" + outerElementName);
    outerElement.setAttributeNS(SAML2Constants.NS_XML, "xmlns:" + outerElemPrefix, outerElemNS);
    Element ed = resultDoc.getDocumentElement();
    resultDoc.replaceChild(outerElement, ed);
    outerElement.appendChild(ed);
    if (encryptedKeyInKeyInfo) {
        // create a ds:KeyInfo Element to include the EncryptionKey
        Element dsElement = resultDoc.createElementNS(SAML2Constants.NS_XMLSIG, "ds:KeyInfo");
        dsElement.setAttributeNS(SAML2Constants.NS_XML, "xmlns:ds", SAML2Constants.NS_XMLSIG);
        dsElement.appendChild(ek);
        // find the xenc:CipherData Element inside the encrypted data
        NodeList nl = ed.getElementsByTagNameNS(SAML2Constants.NS_XMLENC, "CipherData");
        if ((nl == null) || (nl.getLength() == 0)) {
            SAML2SDKUtils.debug.error(classMethod + "Unable to find required xenc:CipherData Element.");
            throw new SAML2Exception(SAML2SDKUtils.bundle.getString("failedEncryptingData"));
        }
        Element cipherDataElement = (Element) nl.item(0);
        // insert the EncryptedKey before the xenc:CipherData Element
        ed.insertBefore(dsElement, cipherDataElement);
    } else {
        outerElement.appendChild(ek);
    }
    return resultDoc.getDocumentElement();
}
Also used : SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) 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) XMLEncryptionException(org.apache.xml.security.encryption.XMLEncryptionException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) 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