xmlcipher.java

来自「JAVA 所有包」· Java 代码 · 共 1,715 行 · 第 1/5 页

JAVA
1,715
字号
/* * Copyright  2003-2004 The Apache Software Foundation. * *  Licensed under the Apache License, Version 2.0 (the "License"); *  you may not use this file except in compliance with the License. *  You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * *  Unless required by applicable law or agreed to in writing, software *  distributed under the License is distributed on an "AS IS" BASIS, *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *  See the License for the specific language governing permissions and *  limitations under the License. * */package com.sun.org.apache.xml.internal.security.encryption;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.StringReader;import java.io.UnsupportedEncodingException;import java.security.InvalidAlgorithmParameterException;import java.security.InvalidKeyException;import java.security.Key;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;import javax.crypto.spec.IvParameterSpec;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.ParserConfigurationException;import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper;import com.sun.org.apache.xml.internal.security.algorithms.MessageDigestAlgorithm;import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException;import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;import com.sun.org.apache.xml.internal.security.keys.KeyInfo;import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolverException;import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.EncryptedKeyResolver;import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException;import com.sun.org.apache.xml.internal.security.transforms.InvalidTransformException;import com.sun.org.apache.xml.internal.security.transforms.TransformationException;import com.sun.org.apache.xml.internal.security.utils.Base64;import com.sun.org.apache.xml.internal.security.utils.Constants;import com.sun.org.apache.xml.internal.security.utils.ElementProxy;import com.sun.org.apache.xml.internal.security.utils.EncryptionConstants;import com.sun.org.apache.xml.internal.security.utils.XMLUtils;import com.sun.org.apache.xml.internal.utils.URI;import org.w3c.dom.Attr;import org.w3c.dom.Document;import org.w3c.dom.DocumentFragment;import org.w3c.dom.Element;import org.w3c.dom.NamedNodeMap;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.xml.sax.InputSource;import org.xml.sax.SAXException;/** * <code>XMLCipher</code> encrypts and decrypts the contents of * <code>Document</code>s, <code>Element</code>s and <code>Element</code> * contents. It was designed to resemble <code>javax.crypto.Cipher</code> in * order to facilitate understanding of its functioning. * * @author Axl Mattheus (Sun Microsystems) * @author Christian Geuer-Pollmann */public class XMLCipher {    private static java.util.logging.Logger logger =         java.util.logging.Logger.getLogger(XMLCipher.class.getName());	//J-	/** Triple DES EDE (192 bit key) in CBC mode */    public static final String TRIPLEDES =                           EncryptionConstants.ALGO_ID_BLOCKCIPHER_TRIPLEDES;    /** AES 128 Cipher */    public static final String AES_128 =                             EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128;    /** AES 256 Cipher */    public static final String AES_256 =                             EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256;    /** AES 192 Cipher */    public static final String AES_192 =                             EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES192;    /** RSA 1.5 Cipher */    public static final String RSA_v1dot5 =                          EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15;    /** RSA OAEP Cipher */    public static final String RSA_OAEP =                            EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP;    /** DIFFIE_HELLMAN Cipher */    public static final String DIFFIE_HELLMAN =                      EncryptionConstants.ALGO_ID_KEYAGREEMENT_DH;    /** Triple DES EDE (192 bit key) in CBC mode KEYWRAP*/    public static final String TRIPLEDES_KeyWrap =                   EncryptionConstants.ALGO_ID_KEYWRAP_TRIPLEDES;    /** AES 128 Cipher KeyWrap */    public static final String AES_128_KeyWrap =                     EncryptionConstants.ALGO_ID_KEYWRAP_AES128;    /** AES 256 Cipher KeyWrap */    public static final String AES_256_KeyWrap =                     EncryptionConstants.ALGO_ID_KEYWRAP_AES256;    /** AES 192 Cipher KeyWrap */    public static final String AES_192_KeyWrap =                     EncryptionConstants.ALGO_ID_KEYWRAP_AES192;    /** SHA1 Cipher */    public static final String SHA1 =                                Constants.ALGO_ID_DIGEST_SHA1;    /** SHA256 Cipher */    public static final String SHA256 =                              MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA256;    /** SHA512 Cipher */    public static final String SHA512 =                              MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA512;    /** RIPEMD Cipher */    public static final String RIPEMD_160 =                          MessageDigestAlgorithm.ALGO_ID_DIGEST_RIPEMD160;    /** XML Signature NS */    public static final String XML_DSIG =                            Constants.SignatureSpecNS;    /** N14C_XML */    public static final String N14C_XML =                            Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS;    /** N14C_XML with comments*/    public static final String N14C_XML_WITH_COMMENTS =              Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS;    /** N14C_XML excluisve */    public static final String EXCL_XML_N14C =                       Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;    /** N14C_XML exclusive with commetns*/    public static final String EXCL_XML_N14C_WITH_COMMENTS =         Canonicalizer.ALGO_ID_C14N_EXCL_WITH_COMMENTS;    /** Base64 encoding */    public static final String BASE64_ENCODING =                     com.sun.org.apache.xml.internal.security.transforms.Transforms.TRANSFORM_BASE64_DECODE;	//J+        /** ENCRYPT Mode */    public static final int ENCRYPT_MODE = Cipher.ENCRYPT_MODE;    /** DECRYPT Mode */    public static final int DECRYPT_MODE = Cipher.DECRYPT_MODE;    /** UNWRAP Mode */    public static final int UNWRAP_MODE  = Cipher.UNWRAP_MODE;    /** WRAP Mode */    public static final int WRAP_MODE    = Cipher.WRAP_MODE;	    private static final String ENC_ALGORITHMS = TRIPLEDES + "\n" +        AES_128 + "\n" + AES_256 + "\n" + AES_192 + "\n" + RSA_v1dot5 + "\n" +        RSA_OAEP + "\n" + TRIPLEDES_KeyWrap + "\n" + AES_128_KeyWrap + "\n" +        AES_256_KeyWrap + "\n" + AES_192_KeyWrap+ "\n";		/** Cipher created during initialisation that is used for encryption */    private Cipher _contextCipher;	/** Mode that the XMLCipher object is operating in */    private int _cipherMode = Integer.MIN_VALUE;	/** URI of algorithm that is being used for cryptographic operation */    private String _algorithm = null;	/** Cryptographic provider requested by caller */	private String _requestedJCEProvider = null;	/** Holds c14n to serialize, if initialized then _always_ use this c14n to serialize */	private Canonicalizer _canon;	/** Used for creation of DOM nodes in WRAP and ENCRYPT modes */    private Document _contextDocument;	/** Instance of factory used to create XML Encryption objects */    private Factory _factory;	/** Internal serializer class for going to/from UTF-8 */    private Serializer _serializer;	/** Local copy of user's key */	private Key _key;	/** Local copy of the kek (used to decrypt EncryptedKeys during a     *  DECRYPT_MODE operation */	private Key _kek;	// The EncryptedKey being built (part of a WRAP operation) or read	// (part of an UNWRAP operation)	private EncryptedKey _ek;	// The EncryptedData being built (part of a WRAP operation) or read	// (part of an UNWRAP operation)	private EncryptedData _ed;    /**     * Creates a new <code>XMLCipher</code>.     *     * @since 1.0.     */    private XMLCipher() {        if (logger.isLoggable(java.util.logging.Level.FINE))                                     logger.log(java.util.logging.Level.FINE, "Constructing XMLCipher...");        _factory = new Factory();        _serializer = new Serializer();    }    /**     * Checks to ensure that the supplied algorithm is valid.     *     * @param algorithm the algorithm to check.     * @return true if the algorithm is valid, otherwise false.     * @since 1.0.     */    private static boolean isValidEncryptionAlgorithm(String algorithm) {        boolean result = (            algorithm.equals(TRIPLEDES) ||            algorithm.equals(AES_128) ||            algorithm.equals(AES_256) ||            algorithm.equals(AES_192) ||            algorithm.equals(RSA_v1dot5) ||            algorithm.equals(RSA_OAEP) ||            algorithm.equals(TRIPLEDES_KeyWrap) ||            algorithm.equals(AES_128_KeyWrap) ||            algorithm.equals(AES_256_KeyWrap) ||            algorithm.equals(AES_192_KeyWrap)        );        return (result);    }    /**     * Returns an <code>XMLCipher</code> that implements the specified     * transformation and operates on the specified context document.     * <p>     * If the default provider package supplies an implementation of the     * requested transformation, an instance of Cipher containing that     * implementation is returned. If the transformation is not available in     * the default provider package, other provider packages are searched.     * <p>     * <b>NOTE<sub>1</sub>:</b> The transformation name does not follow the same     * pattern as that oulined in the Java Cryptography Extension Reference     * Guide but rather that specified by the XML Encryption Syntax and     * Processing document. The rational behind this is to make it easier for a     * novice at writing Java Encryption software to use the library.     * <p>     * <b>NOTE<sub>2</sub>:</b> <code>getInstance()</code> does not follow the     * same pattern regarding exceptional conditions as that used in     * <code>javax.crypto.Cipher</code>. Instead, it only throws an     * <code>XMLEncryptionException</code> which wraps an underlying exception.     * The stack trace from the exception should be self explanitory.     *     * @param transformation the name of the transformation, e.g.,     *   <code>XMLCipher.TRIPLEDES</code> which is shorthand for     *   &quot;http://www.w3.org/2001/04/xmlenc#tripledes-cbc&quot;     * @throws XMLEncryptionException     * @return the XMLCipher     * @see javax.crypto.Cipher#getInstance(java.lang.String)     */    public static XMLCipher getInstance(String transformation) throws            XMLEncryptionException {        // sanity checks        if (logger.isLoggable(java.util.logging.Level.FINE))                                     logger.log(java.util.logging.Level.FINE, "Getting XMLCipher...");        if (null == transformation)            logger.log(java.util.logging.Level.SEVERE, "Transformation unexpectedly null...");        if(!isValidEncryptionAlgorithm(transformation))            logger.log(java.util.logging.Level.WARNING, "Algorithm non-standard, expected one of " + ENC_ALGORITHMS);		XMLCipher instance = new XMLCipher();        instance._algorithm = transformation;		instance._key = null;		instance._kek = null;		/* Create a canonicaliser - used when serialising DOM to octets		 * prior to encryption (and for the reverse) */		try {			instance._canon = Canonicalizer.getInstance				(Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS);            		} catch (InvalidCanonicalizerException ice) {			throw new XMLEncryptionException("empty", ice);		}		String jceAlgorithm = JCEMapper.translateURItoJCEID(transformation);		try {            instance._contextCipher = Cipher.getInstance(jceAlgorithm);            if (logger.isLoggable(java.util.logging.Level.FINE))                                     logger.log(java.util.logging.Level.FINE, "cihper.algoritm = " +                instance._contextCipher.getAlgorithm());        } catch (NoSuchAlgorithmException nsae) {            throw new XMLEncryptionException("empty", nsae);        } catch (NoSuchPaddingException nspe) {            throw new XMLEncryptionException("empty", nspe);        }        return (instance);    }    public static XMLCipher getInstance(String transformation,Cipher cipher) throws            XMLEncryptionException {        // sanity checks        logger.log(java.util.logging.Level.FINE, "Getting XMLCipher...");        if (null == transformation)            logger.log(java.util.logging.Level.SEVERE, "Transformation unexpectedly null...");        if(!isValidEncryptionAlgorithm(transformation))            logger.log(java.util.logging.Level.WARNING, "Algorithm non-standard, expected one of " + ENC_ALGORITHMS);                XMLCipher instance = new XMLCipher();                instance._algorithm = transformation;        instance._key = null;        instance._kek = null;                                /* Create a canonicaliser - used when serialising DOM to octets                 * prior to encryption (and for the reverse) */                try {            instance._canon = Canonicalizer.getInstance                    (Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS);                    } catch (InvalidCanonicalizerException ice) {            throw new XMLEncryptionException("empty", ice);        }                String jceAlgorithm = JCEMapper.translateURItoJCEID(transformation);                try {            instance._contextCipher = cipher;            //Cipher.getInstance(jceAlgorithm);            logger.log(java.util.logging.Level.FINE, "cihper.algoritm = " +                    instance._contextCipher.getAlgorithm());        }catch(Exception ex) {            throw new XMLEncryptionException("empty", ex);        }                return (instance);    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?