Multiple XML files and known-plaintext attack I have created an app which collects data in sets which may contain up to 20000 XML files of an average size of about 5 KB, and all with the same header and XML structure, so that only the data they contain differ.  

For certain reasons I've decided to encrypt these XML files so that the data they contain cannot be exported without my consent. Problem is that the current users of the app already have a lot of unencrypted XML files and after these have been encrypted (they're required to be in order to use future versions of the app) they may still have backups of the unencrypted XML files, which I can't do anything about. 

But that also means that they have the means for doing a known plain-text attack, in order to extract the key and thereby have access to also export the content of encrypted XML files added in the future. So I want to ensure that they're encrypted in a way that makes this if not impossible then at least very difficult.

As I understand from reading posts here, AES should be safe against known-plaintext attacks in a case like this, if it's correctly implemented. So I'm trying to encrypt the files using AES. I just want to be sure if I'm doing it correct, and hope someone here can tell me. 

I'm using the code listed here:

Simple AES byte encryption and decryption routines in C#

and a 64 byte key with a 32 byte salt/IV. Same key and salt for each file. I've set iterations to 4096 as a higher number will slow things down too much. 

I can create a unique key or salt/IV for each file as there is a unique ID connected with each XML file but it will complicate things a lot and in rare cases the ID for a file may change (beyond my control), so I want to avoid it if possible.
First, don't use AES directly.  AES itself is a pseudorandom permutation family, and if you don't understand what that means, then it's not a good fit for your application.

What you should do is use an authenticated encryption scheme (with associated data), or AE(AD) scheme for short.  Popular examples are AES-GCM, NaCl crypto_secretbox_xsalsa20poly1305, and AES-SIV.  Then pay attention to the security contract so that you understand what your obligations are in the application, and what security properties it affords you in exchange:


With AES-GCM, you are obligated (a) to choose a secret key uniformly at random, (b) to provide a unique 96-bit nonce for each message you want to encrypt, and (c) to never reuse the nonce with the same key.

The nonce must be derived from context, e.g. a message sequence number, or stored alongside the message, so that the decryption side of your protocol knows it.  You must not pick the nonce at random, or you must use the key for no more than than $2^{32}$ messages.  Messages must be no longer than one terabyte, $2^{40}$ bytes.

In exchange, you are guaranteed that an adversary without knowledge of the secret key learns nothing about the plaintext of each encrypted message (even if they know all but a single bit of the plaintext, the ciphertext does not inform them of that single bit) and cannot forge ciphertexts you did not already furnish.  If you reuse a nonce, all is lost.

(The exact bound on the safe number of messages is squishy.  A panel of crypto nerds could litigate endlessly over what the limit should be.  Do you want to play games with squishy balls of crypto you don't understand, or just play it safe?)
With NaCl crypto_secretbox_xsalsa20poly1305, you are obligated (a) to choose a secret key uniformly at random, (b) to provide a unique 192-bit nonce for each message you want to encrypt, and (c) to never reuse the nonce with the same key.

The nonce must be derived from contxt, e.g. a message sequence number, or stored alongside the message, so that the decryption side of your protocol knows it.  You may pick the nonce uniformly at random.  You may encrypt up to $2^{64}$ messages each of up to $2^{72}$ bytes apiece, which is more bytes than you will ever have in your lifetime even if you never bother to chew.

In exchange, you are guaranteed that an adversary without knowledge of the secret key learns nothing about the plaintext of each encrypted message (even if they know all but a single bit of the plaintext, the ciphertext does not inform them of that single bit) and cannot forge ciphertexts you did not already furnish.  If you reuse a nonce, all is lost.
With AES-SIV, you are obligated to choose a secret key uniformly at random.  You may additionally supply a 128-bit nonce, even at random.  You must not use the key for a total of more than $2^{48}$ bytes.

In exchange, you are guaranteed that an adversary without knowledge of the secret key learns nothing about the plaintext of each encrypted message (even if they know all but a single bit of the plaintext, the ciphertext does not inform them of that single bit) except that if the nonce is repeated or not supplied, the adversary will learn when a message is repeated or not.  You are also guaranteed that the adversary cannot forge ciphertexts you did not already furnish.

(The limit on bytes here is also squishy.  What have we learned about squishy balls of crypto?)


There are other considerations about the AES ones versus the XSalsa20/Poly1305 choice: software implementations of AES and GCM are either vulnerable to cache-timing attacks (vast majority), or unusably slow (you are not likely to encounter these); guaranteeing that you can rely on a hardware implementation of AES and guaranteeing that your software stack uses the hardware implementation of AES that is available is a nontrivial auditing task.