Class Decrypter


  • public class Decrypter
    extends Object
    Supports decryption of XMLObjects which represent data encrypted according to the XML Encryption specification, version 20021210.

    Details on the components specified as constructor options are as follows:

    1. newResolver: This KeyInfoCredentialResolver instance is used to resolve keys (as Credentials) based on the KeyInfo of EncryptedData elements. While it could in theory be used to handle the complete process of resolving the data decryption key, including decrypting any necessary EncryptedKey's, it would typically be used in cases where encrypted key transport via an EncryptedKey is not being employed. This corresponds to scenarios where decryption is instead based on resolving the (presumably shared secret) symmetric data decryption key directly, based on either context or information present in the EncryptedData's KeyInfo. In cases where the data decryption key is to be resolved by decrypting an EncryptedKey, this resolver would typically not be used and may be null.
    2. newKEKResolver: This KeyInfoCredentialResolver instance is used to resolve keys (as Credentials) used to decrypt EncryptedKey elements, based on the KeyInfo information contained within the EncryptedKey element (also known as a Key Encryption Key or KEK). For asymmetric key transport of encrypted keys, this would entail resolving the private key which corresponds to the public key which was used to encrypt the EncryptedKey.
    3. newEncKeyResolver: This EncryptedKeyResolver instance is responsible for resolving the EncryptedKey element(s) which hold(s) the encrypted data decryption key which would be used to decrypt an EncryptedData element.

    XML Encryption can encrypt either a single Element or the contents of an Element. The caller of this class must select the decryption method which is most appropriate for their specific use case.

    Note that the type of plaintext data contained by an EncryptedData can be checked prior to decryption by examining that element's type attribute (EncryptedType.getType()). This (optional) attribute may contain one of the following two constant values to aid in the decryption process: EncryptionConstants.TYPE_ELEMENT or EncryptionConstants.TYPE_CONTENT.

    By nature the fundamental output of XML decryption is a DOM DocumentFragment with 1 or more immediate top-level DOM Node children. This case is reflected in the method decryptDataToDOM(EncryptedData). It is up to the caller to properly process the DOM Nodes which are the children of this document fragment. The DocumentFragment and its Node children will be owned by the DOM Document which owned the original EncryptedData before decryption. Note, however, that the Node children will not be a part of the tree of Nodes rooted at that Document's document element.

    A typical use case will be that the content which was encrypted contained solely Element nodes. For this use case a convenience method is provided as decryptDataToList(EncryptedData), which returns a list of XMLObject's which are the result of unmarshalling each of the child Elements of the decrypted DocumentFragment.

    Another typical use case is that the content which was encrypted was a single Element. For this use case a convenience method is provided as decryptData(EncryptedData), which returns a single XMLObject which was the result of unmarshalling this decrypted Element.

    In both of these cases the underlying DOM Element which is represented by each of the returned XMLObjects will be owned by the DOM Document which also owns the original EncrytpedData Element. However, note that these cached DOM Elements are not part of the tree of Nodes rooted at that Document's document element. If these returned XMLObjects are then inserted as the children of other XMLObjects, it is up to the caller to ensure that the XMLObject tree is then remarshalled if the relationship of the cached DOM nodes is important (e.g. resolution of ID-typed attributes via Document.getElementById(String)).

    For some use cases where the returned XMLObjects will not necessarily be stored back as children of another parent XMLObject, it may still necessary for the DOM Elements of the resultant XMLObjects to exist within the tree of Nodes rooted at a DOM Document's document element (e.g. signature verification on the standalone decrypted XMLObject). For these cases these method variants may be used: decryptDataToList(EncryptedData, boolean) and decryptData(EncryptedData, boolean). The rootInNewDocument parameter is explained below. A default value for this parameter, for the overloaded convenience methods which do not take this parameter explicitly, may be set via setRootInNewDocument(boolean). This default value is initialized to false.

    If the boolean option rootInNewDocument is true at the time of decryption, then for each top-level child Element of the decrypted DocumentFragment, the following will occur:

    1. A new DOM Document will be created.
    2. The Element will be adopted into that Document.
    3. The Element will be made the root element of the Document.
    4. The Element will be unmarshalled into an XMLObject as in the single argument variant.

    Note that new Document creation, node adoption and rooting the new document element are potentially very expensive. This should only be done where the caller's use case really requires it.

    • Field Detail

      • parserPool

        private final ParserPool parserPool
        ParserPool used in parsing decrypted data.
      • unmarshallerFactory

        private final UnmarshallerFactory unmarshallerFactory
        Unmarshaller factory, used in decryption of EncryptedData objects.
      • log

        private final org.slf4j.Logger log
        Class logger.
      • encKeyResolver

        private EncryptedKeyResolver encKeyResolver
        Resolver for EncryptedKey instances which contain the encrypted data encryption key.
      • whitelistedAlgorithmURIs

        private Collection<String> whitelistedAlgorithmURIs
        The collection of algorithm URI's which are whitelisted.
      • blacklistedAlgorithmURIs

        private Collection<String> blacklistedAlgorithmURIs
        The collection of algorithm URI's which are blacklisted.
      • resolverCriteria

        private CriteriaSet resolverCriteria
        Additional criteria to use when resolving credentials based on an EncryptedData's KeyInfo.
      • kekResolverCriteria

        private CriteriaSet kekResolverCriteria
        Additional criteria to use when resolving credentials based on an EncryptedKey's KeyInfo.
      • jcaProviderName

        private String jcaProviderName
        The name of the JCA security provider to use.
      • defaultRootInNewDocument

        private boolean defaultRootInNewDocument
        Flag to determine whether by default the Element which backs the underlying decrypted SAMLObject will be the root of a new DOM document.
    • Constructor Detail

      • Decrypter

        public Decrypter​(DecryptionParameters params)
        Constructor.
        Parameters:
        params - decryption parameters to use
      • Decrypter

        public Decrypter​(@Nullable
                         KeyInfoCredentialResolver newResolver,
                         @Nullable
                         KeyInfoCredentialResolver newKEKResolver,
                         @Nullable
                         EncryptedKeyResolver newEncKeyResolver)
        Constructor.
        Parameters:
        newResolver - resolver for data encryption keys.
        newKEKResolver - resolver for key encryption keys.
        newEncKeyResolver - resolver for EncryptedKey elements
      • Decrypter

        public Decrypter​(@Nullable
                         KeyInfoCredentialResolver newResolver,
                         @Nullable
                         KeyInfoCredentialResolver newKEKResolver,
                         @Nullable
                         EncryptedKeyResolver newEncKeyResolver,
                         @Nullable
                         Collection<String> whitelistAlgos,
                         @Nullable
                         Collection<String> blacklistAlgos)
        Constructor.
        Parameters:
        newResolver - resolver for data encryption keys.
        newKEKResolver - resolver for key encryption keys.
        newEncKeyResolver - resolver for EncryptedKey elements
        whitelistAlgos - collection of whitelisted algorithm URIs
        blacklistAlgos - collection of blacklisted algorithm URIs
      • Decrypter

        private Decrypter()
        Constructor.
    • Method Detail

      • isRootInNewDocument

        public boolean isRootInNewDocument()
        Get the flag which indicates whether by default the DOM Element which backs a decrypted SAML object will be the root of a new DOM document. Defaults to false.
        Returns:
        the current value of the flag for this decrypter instance
      • setRootInNewDocument

        public void setRootInNewDocument​(boolean flag)
        Set the flag which indicates whether by default the DOM Element which backs a decrypted SAML object will be the root of a new DOM document. Defaults to false.
        Parameters:
        flag - the current value of the flag for this decrypter instance
      • getJCAProviderName

        @Nullable
        public String getJCAProviderName()
        Get the Java Cryptography Architecture (JCA) security provider name that should be used to provide the decryption support. Defaults to null, which means that the first registered provider which supports the indicated encryption algorithm URI will be used.
        Returns:
        the JCA provider name to use
      • setJCAProviderName

        public void setJCAProviderName​(@Nullable
                                       String providerName)
        Set the Java Cryptography Architecture (JCA) security provider name that should be used to provide the decryption support. Defaults to null, which means that the first registered provider which supports the indicated encryption algorithm URI will be used.
        Parameters:
        providerName - the JCA provider name to use
      • getKeyResolverCriteria

        public CriteriaSet getKeyResolverCriteria()
        Get the optional static set of criteria used when resolving credentials based on the KeyInfo of an EncryptedData element.
        Returns:
        the static criteria set to use
      • setKeyResolverCriteria

        public void setKeyResolverCriteria​(CriteriaSet newCriteria)
        Set the optional static set of criteria used when resolving credentials based on the KeyInfo of an EncryptedData element.
        Parameters:
        newCriteria - the static criteria set to use
      • getKEKResolverCriteria

        public CriteriaSet getKEKResolverCriteria()
        Get the optional static set of criteria used when resolving credentials based on the KeyInfo of an EncryptedKey element.
        Returns:
        the static criteria set to use
      • setKEKResolverCriteria

        public void setKEKResolverCriteria​(CriteriaSet newCriteria)
        Set the optional static set of criteria used when resolving credentials based on the KeyInfo of an EncryptedKey element.
        Parameters:
        newCriteria - the static criteria set to use
      • decryptData

        @Nonnull
        public XMLObject decryptData​(@Nonnull
                                     EncryptedData encryptedData,
                                     boolean rootInNewDocument)
                              throws DecryptionException
        Decrypts the supplied EncryptedData and returns the resulting XMLObject. This will only succeed if the decrypted EncryptedData contains exactly one DOM Node of type Element.
        Parameters:
        encryptedData - encrypted data element containing the data to be decrypted
        rootInNewDocument - if true, root the underlying Element of the returned XMLObject in a new Document as described in Decrypter
        Returns:
        the decrypted XMLObject
        Throws:
        DecryptionException - exception indicating a decryption error, possibly because the decrypted data contained more than one top-level Element, or some non-Element Node type.
      • decryptDataToList

        @Nonnull
        public List<XMLObject> decryptDataToList​(@Nonnull
                                                 EncryptedData encryptedData,
                                                 boolean rootInNewDocument)
                                          throws DecryptionException
        Decrypts the supplied EncryptedData and returns the resulting list of XMLObjects. This will succeed only if the decrypted EncryptedData contains at the top-level only DOM Elements (not other types of DOM Nodes).
        Parameters:
        encryptedData - encrypted data element containing the data to be decrypted
        rootInNewDocument - if true, root the underlying Elements of the returned XMLObjects in a new Document as described in Decrypter
        Returns:
        the list decrypted top-level XMLObjects
        Throws:
        DecryptionException - exception indicating a decryption error, possibly because the decrypted data contained DOM nodes other than type of Element
      • decryptDataToDOM

        @Nonnull
        public DocumentFragment decryptDataToDOM​(@Nonnull
                                                 EncryptedData encryptedData,
                                                 @Nonnull
                                                 Key dataEncKey)
                                          throws DecryptionException
        Decrypts the supplied EncryptedData using the specified key, and returns the resulting DOM DocumentFragment.
        Parameters:
        encryptedData - encrypted data element containing the data to be decrypted
        dataEncKey - Java Key with which to attempt decryption of the encrypted data
        Returns:
        the decrypted DOM DocumentFragment
        Throws:
        DecryptionException - exception indicating a decryption error
      • decryptKey

        @Nonnull
        public Key decryptKey​(@Nonnull
                              EncryptedKey encryptedKey,
                              @Nonnull
                              String algorithm)
                       throws DecryptionException
        Attempts to decrypt the supplied EncryptedKey and returns the resulting Java security Key object. The algorithm of the decrypted key must be supplied by the caller based on knowledge of the associated EncryptedData information.
        Parameters:
        encryptedKey - encrypted key element containing the encrypted key to be decrypted
        algorithm - the algorithm associated with the decrypted key
        Returns:
        the decrypted key
        Throws:
        DecryptionException - exception indicating a decryption error
      • decryptKey

        @Nonnull
        public Key decryptKey​(@Nonnull
                              EncryptedKey encryptedKey,
                              @Nonnull
                              String algorithm,
                              @Nonnull
                              Key kek)
                       throws DecryptionException
        Decrypts the supplied EncryptedKey and returns the resulting Java security Key object. The algorithm of the decrypted key must be supplied by the caller based on knowledge of the associated EncryptedData information.
        Parameters:
        encryptedKey - encrypted key element containing the encrypted key to be decrypted
        algorithm - the algorithm associated with the decrypted key
        kek - the key encryption key with which to attempt decryption of the encrypted key
        Returns:
        the decrypted key
        Throws:
        DecryptionException - exception indicating a decryption error
      • preProcessEncryptedKey

        protected void preProcessEncryptedKey​(@Nonnull
                                              EncryptedKey encryptedKey,
                                              @Nonnull
                                              String algorithm,
                                              @Nonnull
                                              Key kek)
                                       throws DecryptionException
        Preprocess the EncryptedKey. For example, check for supported algorithms.
        Parameters:
        encryptedKey - encrypted key element containing the encrypted key to be decrypted
        algorithm - the algorithm associated with the decrypted key
        kek - the key encryption key with which to attempt decryption of the encrypted key
        Throws:
        DecryptionException - exception indicating a decryption error
      • decryptUsingResolvedKey

        @Nullable
        private DocumentFragment decryptUsingResolvedKey​(@Nonnull
                                                         EncryptedData encryptedData)
        Attempt to decrypt by resolving the decryption key using the standard credential resolver.
        Parameters:
        encryptedData - the encrypted data to decrypt
        Returns:
        the decrypted document fragment, or null if decryption key could not be resolved or decryption failed
      • decryptUsingResolvedEncryptedKey

        @Nullable
        private DocumentFragment decryptUsingResolvedEncryptedKey​(@Nonnull
                                                                  EncryptedData encryptedData,
                                                                  @Nonnull
                                                                  String algorithm)
        Attempt to decrypt by resolving the decryption key by first resolving EncryptedKeys, and using the KEK credential resolver to resolve the key decryption for each.
        Parameters:
        encryptedData - the encrypted data to decrypt
        algorithm - the algorithm of the key to be decrypted
        Returns:
        the decrypted document fragment, or null if decryption key could not be resolved or decryption failed
      • parseInputStream

        @Nonnull
        private DocumentFragment parseInputStream​(@Nonnull
                                                  InputStream input,
                                                  @Nonnull
                                                  Document owningDocument)
                                           throws DecryptionException
        Parse the specified input stream in a DOM DocumentFragment, owned by the specified Document.
        Parameters:
        input - the InputStream to parse
        owningDocument - the Document which will own the returned DocumentFragment
        Returns:
        a DocumentFragment
        Throws:
        DecryptionException - thrown if there is an error parsing the input stream
      • buildCredentialCriteria

        @Nonnull
        private CriteriaSet buildCredentialCriteria​(@Nonnull
                                                    EncryptedType encryptedType,
                                                    @Nullable
                                                    CriteriaSet staticCriteria)
        Utility method to build a new set of credential criteria based on the KeyInfo of an EncryptedData or EncryptedKey, and any additional static criteria which might have been supplied to the decrypter.
        Parameters:
        encryptedType - an EncryptedData or EncryptedKey for which to resolve decryption credentials
        staticCriteria - static set of credential criteria to add to the new criteria set
        Returns:
        the new credential criteria set
      • buildKeyCriteria

        @Nullable
        private Set<Criterion> buildKeyCriteria​(@Nonnull
                                                EncryptedType encryptedType)
        Build decryption key credential criteria according to information in the encrypted type object.
        Parameters:
        encryptedType - the encrypted type from which to deduce decryption key criteria
        Returns:
        a set of credential criteria pertaining to the decryption key
      • buildKeyAlgorithmCriteria

        @Nullable
        private KeyAlgorithmCriterion buildKeyAlgorithmCriteria​(@Nullable
                                                                String encAlgorithmURI)
        Dynamically construct key algorithm credential criteria based on the specified algorithm URI.
        Parameters:
        encAlgorithmURI - the algorithm URI
        Returns:
        a new key algorithm credential criteria instance, or null if criteria could not be determined
      • buildKeyLengthCriteria

        @Nullable
        private KeyLengthCriterion buildKeyLengthCriteria​(@Nullable
                                                          String encAlgorithmURI)
        Dynamically construct key length credential criteria based on the specified algorithm URI.
        Parameters:
        encAlgorithmURI - the algorithm URI
        Returns:
        a new key length credential criteria instance, or null if the value could not be determined
      • checkAndMarshall

        protected void checkAndMarshall​(@Nonnull
                                        XMLObject xmlObject)
                                 throws DecryptionException
        Ensure that the XMLObject is marshalled.
        Parameters:
        xmlObject - the object to check and marshall
        Throws:
        DecryptionException - thrown if there is an error when marshalling the XMLObject
      • buildParserPool

        @Deprecated
        protected ParserPool buildParserPool()
        Deprecated.
        Build the internal parser pool instance used to parse decrypted XML.

        Note: When using a Xerces parser or derivative, the following feature must be set to false: http://apache.org/xml/features/dom/defer-node-expansion

        Returns:
        a new parser pool instance
      • validateAlgorithms

        protected void validateAlgorithms​(@Nonnull
                                          EncryptedKey encryptedKey)
                                   throws DecryptionException
        Validate the algorithms contained within an EncryptedKey.
        Parameters:
        encryptedKey - the encrypted key instance to validate
        Throws:
        DecryptionException - if any algorithms do not satisfy whitelist/blacklist policy
      • validateAlgorithms

        protected void validateAlgorithms​(@Nonnull
                                          EncryptedData encryptedData)
                                   throws DecryptionException
        Validate the algorithms contained within an EncryptedData.
        Parameters:
        encryptedData - the encrypted data instance to validate
        Throws:
        DecryptionException - if any algorithms do not satisfy whitelist/blacklist policy
      • validateAlgorithmURI

        protected void validateAlgorithmURI​(@Nonnull
                                            String algorithmURI)
                                     throws DecryptionException
        Validate the supplied algorithm URI against the configured whitelist and blacklist.
        Parameters:
        algorithmURI - the algorithm URI to evaluate
        Throws:
        DecryptionException - if the algorithm URI does not satisfy the whitelist/blacklist policy