Search in sources :

Example 6 with EncryptedKey

use of org.apache.xml.security.encryption.EncryptedKey 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)

Example 7 with EncryptedKey

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

the class AMEncryptionProvider method encryptAndReplace.

/**
     * Encrypts the given XML element in a given XML Context document.
     * @param doc the context XML Document.
     * @param element Element to be encrypted.
     * @param secretKeyAlg Encryption Key Algorithm.
     * @param keyStrength Encryption Key Strength.
     * @param kek Key Encryption Key.
     * @param kekStrength Key Encryption Key Strength,
     * @param providerID Provider ID
     * @param isEncryptResourceID A flag indicates whether it's to encrypt
     * 		ResourceID or not.
     * @return org.w3c.dom.Document EncryptedResourceID XML Document if
     * 		isEncryptResourceID is set. Otherwise, return the XML Document
     *		replaced with encrypted data for a given XML element.
     */
private org.w3c.dom.Document encryptAndReplace(org.w3c.dom.Document doc, org.w3c.dom.Element element, java.lang.String secretKeyAlg, int keyStrength, java.security.Key kek, int kekStrength, String providerID, boolean isEncryptResourceID) throws EncryptionException {
    if (doc == null || element == null || kek == null) {
        EncryptionUtils.debug.error("AMEncryptionProvider.encryptAnd" + "Replace: Null values");
        throw new EncryptionException(EncryptionUtils.bundle.getString("nullValues"));
    }
    SecretKey secretKey = null;
    String secretKeyAlgShortName = getEncryptionAlgorithmShortName(secretKeyAlg);
    if (providerID != null) {
        if (keyMap.containsKey(providerID)) {
            secretKey = (SecretKey) keyMap.get(providerID);
        } else {
            secretKey = generateSecretKey(secretKeyAlgShortName, keyStrength);
            keyMap.put(providerID, secretKey);
        }
    } else {
        secretKey = generateSecretKey(secretKeyAlgShortName, keyStrength);
    }
    if (secretKey == null) {
        throw new EncryptionException(EncryptionUtils.bundle.getString("generateKeyError"));
    }
    try {
        XMLCipher cipher = null;
        String keyEncAlg = kek.getAlgorithm();
        if (keyEncAlg.equals(EncryptionConstants.RSA)) {
            cipher = XMLCipher.getInstance(XMLCipher.RSA_v1dot5);
        } else if (keyEncAlg.equals(EncryptionConstants.TRIPLEDES)) {
            cipher = XMLCipher.getInstance(XMLCipher.TRIPLEDES_KeyWrap);
        } else if (keyEncAlg.equals(EncryptionConstants.AES)) {
            if (kekStrength == 0 || kekStrength == 128) {
                cipher = XMLCipher.getInstance(XMLCipher.AES_128_KeyWrap);
            } else if (kekStrength == 192) {
                cipher = XMLCipher.getInstance(XMLCipher.AES_192_KeyWrap);
            } else if (kekStrength == 256) {
                cipher = XMLCipher.getInstance(XMLCipher.AES_256_KeyWrap);
            } else {
                throw new EncryptionException(EncryptionUtils.bundle.getString("invalidKeyStrength"));
            }
        } else {
            throw new EncryptionException(EncryptionUtils.bundle.getString("unsupportedKeyAlg"));
        }
        // Encrypt the key with key encryption key
        cipher.init(XMLCipher.WRAP_MODE, kek);
        EncryptedKey encryptedKey = cipher.encryptKey(doc, secretKey);
        KeyInfo insideKi = new KeyInfo(doc);
        X509Data x509Data = new X509Data(doc);
        x509Data.addCertificate((X509Certificate) keyProvider.getCertificate((PublicKey) kek));
        insideKi.add(x509Data);
        encryptedKey.setKeyInfo(insideKi);
        String ekID = null;
        if (isEncryptResourceID) {
            ekID = com.sun.identity.saml.common.SAMLUtils.generateID();
            encryptedKey.setId(ekID);
        }
        if (EncryptionUtils.debug.messageEnabled()) {
            EncryptionUtils.debug.message("AMEncryptionProvider.encrypt" + "AndReplace: Encrypted key = " + toString(cipher.martial(doc, encryptedKey)));
        }
        String encAlgorithm = getEncryptionAlgorithm(secretKeyAlgShortName, keyStrength);
        cipher = XMLCipher.getInstance(encAlgorithm);
        cipher.init(XMLCipher.ENCRYPT_MODE, secretKey);
        EncryptedData builder = cipher.getEncryptedData();
        KeyInfo builderKeyInfo = builder.getKeyInfo();
        if (builderKeyInfo == null) {
            builderKeyInfo = new KeyInfo(doc);
            builder.setKeyInfo(builderKeyInfo);
        }
        if (isEncryptResourceID) {
            builderKeyInfo.addKeyName(providerID);
            builderKeyInfo.addRetrievalMethod("#" + ekID, null, "http://www.w3.org/2001/04/xmlenc#EncryptedKey");
        } else {
            builderKeyInfo.add(encryptedKey);
        }
        Document result = cipher.doFinal(doc, element);
        if (isEncryptResourceID) {
            Element ee = (Element) result.getElementsByTagNameNS("http://www.w3.org/2001/04/xmlenc#", "EncryptedData").item(0);
            Node parentNode = ee.getParentNode();
            Element newone = result.createElementNS("urn:liberty:disco:2003-08", "EncryptedResourceID");
            parentNode.replaceChild(newone, ee);
            newone.appendChild(ee);
            Element ek = cipher.martial(doc, encryptedKey);
            Element carriedName = doc.createElementNS("http://www.w3.org/2001/04/xmlenc#", "xenc:CarriedKeyName");
            carriedName.appendChild(doc.createTextNode(providerID));
            ek.appendChild(carriedName);
            newone.appendChild(ek);
        }
        return result;
    } catch (Exception xe) {
        EncryptionUtils.debug.error("AMEncryptionProvider.encryptAnd" + "Replace: XML Encryption error", xe);
        throw new EncryptionException(xe);
    }
}
Also used : SecretKey(javax.crypto.SecretKey) EncryptedKey(org.apache.xml.security.encryption.EncryptedKey) KeyInfo(org.apache.xml.security.keys.KeyInfo) Element(org.w3c.dom.Element) Node(org.w3c.dom.Node) XMLCipher(org.apache.xml.security.encryption.XMLCipher) EncryptedData(org.apache.xml.security.encryption.EncryptedData) Document(org.w3c.dom.Document) X509Data(org.apache.xml.security.keys.content.X509Data) IOException(java.io.IOException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException)

Aggregations

EncryptedKey (org.apache.xml.security.encryption.EncryptedKey)7 SecretKey (javax.crypto.SecretKey)5 EncryptedData (org.apache.xml.security.encryption.EncryptedData)5 XMLCipher (org.apache.xml.security.encryption.XMLCipher)5 Document (org.w3c.dom.Document)5 Element (org.w3c.dom.Element)5 SAML2Exception (com.sun.identity.saml2.common.SAML2Exception)4 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)4 XMLEncryptionException (org.apache.xml.security.encryption.XMLEncryptionException)4 NodeList (org.w3c.dom.NodeList)4 Key (java.security.Key)3 PrivateKey (java.security.PrivateKey)3 IOException (java.io.IOException)2 PublicKey (java.security.PublicKey)2 KeyInfo (org.apache.xml.security.keys.KeyInfo)2 X509Data (org.apache.xml.security.keys.content.X509Data)1 Node (org.w3c.dom.Node)1