Recently I was asked about using a CDATA section to transport encrypted data and quickly answered that is was fine to do this but I failed to qualify this answer. In most cases, encrypted data is simply binary data. CDATA sections are used to escape text containing characters that may be recognized as XML markup, so naturally many people believe that binary data could directly be used as content within a CDATA section. This is where the problem begins...
CDATA can contain almost any characters except the sequence "]]>", which indicates the end of the CDATA section. So what happens if binary data containing this character sequence is placed within a CDATA section? The answer is quite simple. You no longer have well formed XML. Although the chances of this happening might be slim, an application using this approach that may have worked for a long time may all of a sudden be unable to process a document and its off to debug land trying to find out the issue. So how can this potential headache be avoided?
Binary data should be encoded as hex or base64. Encoding data has both pros and cons, but in any event it is the only way to insure the data will not break an XML document. The upside to encoding is that the data is now more portable. It is not restricted to CDATA and can happily live as element content. The downside is that encoding introduces additional overhead. The document is larger than if the raw binary data were used directly and it must be decoded, adding additional required processing, in order to use it. Size wise, base64 encoding is your best bet. It increases the size of data on average about 30% compared to hex which roughly doubles the size of the data.
Another thing to be aware of is future compatibility. Take for example a Web service you might have developed that works with XML encryption or XML digital signatures. Its initial state is a small internal service, so you decide to on a custom homebrewed solution for these technologies. After some time the company decides that the service is extremely useful and wants to expose it for its clients, but would like it to be compatible with the W3C specifications for these technologies. According to the specs, base64 is the only required encoding algorithm. It is quite possible that if you are using hex encoding, your application will not inter-operate with other applications also based on these specifications.
In short, whether or not you decide to use CDATA to contain encrypted/binary data is up to you, but it should always be encoded (preferably using base64). Once encoded, there are no longer any special circumstances requiring it to live within a CDATA section and can happily live as element content.