I'd go with the first system, there's no significant difference from the AES one; but still you need to consider other, possibly unrelated factors.
UPDATE: on second thoughts, you might want to use PKDBF2 as a "hash", in order to mitigate the chances of a successful bruteforcing.
Brute force attack
If the suffixes are known, or in general there is a known mapping between user ID and hash, then an attacker could simply enumerate all possible IDs.
For example, the attacker knows that IDs start at 1 and are at most 100,000; even using a CPU- and memory- hard algorithm, generating the hashes for all possible user-IDs and storing them into a database wouldn't take more than a few days. Using SHA1 or AES, it's a matter of minutes, perhaps even seconds. Afterwards, to know what ID hides behind a given hash, it's just a matter of looking for that hash in the list.
You might want to consider replacing sequential IDs with random ones (which can be a pain in the nether regions; and you need to handle the case where a random newId collides with a yet-to-be-replaced oldId). At that point the "possible IDs" are no longer one hundred thousand (from 1 to 100,000) but several billion trillions (from 0x00000000000000000000000000000000 to 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF). Bruteforcing will now take an impossible amount of time, and/or an impossibly large database to hold the hashes.
Correlations
Consider the possibility of non-trivial correlations between file1 and file2. While a trivial correlation would be both files containing a unique identifier, or worse still, a copy of the user ID, there might be information in both files that could allow determining the user ID, or the link between paired files; for example, a timestamp, or a invertible UUID for some resource.
This issue might extend to metadata such as mtime, or inode number, or position in the directory listing; two files created within the same second, or stored one after the other, could be tracked to the same user, even if one can't backcalculate the user ID.
You should consider archiving the files in a 2- or 3-deep structure, i.e.
/rootdir/ae/02/47/ae0247f19a8b52f.json
and using a non-atime-updating filesystem; and/or when you do change or create or delete a file, touch
the whole branch (here ae, ae/02, ae/02/47 and ae/02/47/ae0247f19a8b52f.json) to a fixed datetime, such as midnight January 1st, 1970.
Initialising the repo
When transferring the files to the repository, you might want to first produce a list:
000001-1.json aae3799a82b9fb8ccd34c1d5aa6565b2
000001-2.json 539c50984894084b3e3b1047eee187ae
...
Then you scramble the list. Once done this, for each pair on the list you move e.g. 000001-2.json
to repositoryRoot/53/9c/50/539c50984894084b3e3b1047eee187ae
. This way, there will be no correlation between the inodes, filesystem position or disk physical position of 000001-1.json
and 000001-2.json
.
Be warned that on most filesystems, this approach will appreciably increase the time required to do the copying.
Emails as IDs
This does not look very promising security-wise, because emails are often guessable and/or recycled. Much would depend on what exactly is stored on those JSON files and what the attack scenario actually is (the two cases of a hacker gaining access to a repository of embarrassing information and attempting to blackmail the owners - thus requiring to work back from the JSON to the email - and someone trying to acquire the information of a victim whose email is known, are to be handled very differently).
One possibility could be having an anonymisation table kept outside the repository:
ID RandomToken
[email protected] 5231b225ea0dbcced14c993523af4986
.... ....
At that point you could use token as the "secret" password.