4

It's probably dublicate but I can't figure out the correct keywords for search. You can help by just telling me those words, I'm rather good with Google :)

I want to develop somewhat like file storage with encryption of every file. There is only one user, and all the data (and code) is stored on his local machine. User is able to import some files in and read the formerly imported ones.

Requirements

Main attack vector is unauthorized data reading. No need to protect from illegal importing files.

In addition, I'd like to implement plausible deniability. It will look like this: there's two storage actually, one of them is encrypted with empty password and it's OK to expose it's contents to anyone. It is used to obscure the fact that there's something hidden. Just an additional shield.

The key that the whole system's security is based upon is that user's password is stored inside his head only, i. e. not reachable programmatically (unless there's keylogger, telepathic software, or satellite with hi-res camera that can see you typing).

Implementation

For now I've end up with the following scheme.

  1. User's password is a key for encrypting/decrypting the random generated level 2 password(s). Symmetric cypher is used (e. g. AES which is considered secure for the moment).

  2. Level 2 cryptography is asymmetric. Encryption (public) key is used when importing unencrypted files from external sources. Decription (private) key is used for reading files. As asymmetric algorythms are slow, these keys are actually used to protect the session key (unique for each file). Private key is available in memory as plain text only when encrypting session key.

  3. Level 3 uses symmectric cryptography, AES again or some secure stream cypher (only in case of much much better performance because security is preferred). It is used to actually encrypt/decrypt file contents.

You've finally read it to the end :) Here are the questions:

  1. How to simplify this scheme not harming the security?

    In short: remove middle level. Still have to use two levels though, to prevent cypher fatigue/enthropy exhausting and to satisfy my paranoia :)

  2. How to enhance it's security? I know there are bugs here, crypto is a tricky thing.

    Many thanks to @DeerHunter to point out potential flaws.

  3. What to google and to read about this? No fundamental things like Shneier please :)

    Well, I've got enough terms and concepts to dive into. For now, at least.

  4. I'm still not sure whether I should use asymmetric cyphers (in level one). I thought that it would help to split the risks: decryption (private) key is spawned as plaintext just for a moments, while encryption (public) key can even be exposed to everyone. But in comparison with symmetric syphers, I still have one key to secure in RAM, and there's additional (public) key to worry about.

EDIT1. I don't want to design my own standard, it's far beyond my knowledge. I'm gonna use things that are proved secure where possible. E. g. what I'll do by myself is just combine several classes from Crypto++ to work together. I only need the right design to do it. For now I don't think that full-disk encryption is suitable in my case. I've thought about TrueCrypt etc but it doesn't allow to hide the presence of the encrypted data. I'd prefer solution (crypto standard or protocol) for per-file encryption.

EDIT2. Rearranged text to split requrements and implementation, added deniable plausibility req.

EDIT3 There's one more question left about asymmetric crypto.

  • 2
    **Full-disk encryption** is what you're after. Encrypting individual files establishes side channels for a [**wily** attacker](https://en.wikipedia.org/wiki/Wile_E._Coyote_and_The_Road_Runner). – Deer Hunter Jul 10 '13 at 13:45
  • Could you please say in "plain text" what is wily attack? This cartoon is not meme for me, I didn't watch that. Also, encrypted files are stored in a single database file, not in the filesystem, if it matters. – Kirill Gamazkov Jul 10 '13 at 14:30
  • If you store content in a database file, the principle is the same as with Full-Disk Encryption containers. You want to avoid leaking metadata: when, what, how large etc. files exist, and what operations the user does on them (editing, deleting). – Deer Hunter Jul 10 '13 at 14:37
  • Kirill, I can see one problem with your question. You haven't stated all the requirements and jumped to announce your scheme. Please separate specification (with description of the threat you are protecting from) from implementation details. – Deer Hunter Jul 10 '13 at 14:42
  • Done. About metadata leaking. I don't use journaling by myself. I'm not sure whether database engine (SQLite) does. Thanks for the point to check. Could you provide me with some links/search keywords to learn more about that? – Kirill Gamazkov Jul 10 '13 at 15:03
  • http://security.stackexchange.com/questions/20595/plausible-deniability-with-truecrypt http://security.stackexchange.com/questions/11776/truecrypt-dataleaks-that-might-betray-the-deniable-file-system-option http://unix.stackexchange.com/questions/2791/portable-encrypted-container and many many others - search through IT Security, Server Fault, Unix and SuperUser SE sites. – Deer Hunter Jul 10 '13 at 15:19

3 Answers3

6

The first and probably only way to make such things secure is not to do it yourself. Implementing properly a cryptographic protocol without leaking information everywhere is hard; designing a cryptographic protocol is harder.

Since the user imports the files himself, and reads it, then there is no need whatsoever to invoke asymmetric cryptography. Asymmetric cryptography is for when there are (at least) two players with distinct rights (e.g. a signer and a verifier; or a sender and a recipient); here, there is the user and himself: same guy, hence no need for asymmetry. Another way to see that is that asymmetric cryptography was designed to solve the problem of sharing secret information between several people. A user has no problem sharing secret information with himself.

So the basic structure is to encrypt files with a key derived from a secret which fits in the user's brain (the password). This points to tools for full disk encryption, which exist for many operating systems. Some recent Windows versions come with BitLocker. Good Linux distributions have their own system. An oft-recommended third party product for full disk encryption is TrueCrypt. Use one of these and you will live longer and happier.

Thomas Pornin
  • 322,884
  • 58
  • 787
  • 955
  • You're right, to invent my own cryptowheel is genereally bad idea. Acrually, I'll be happy just to know the name of the right crypto standard. I don't think that whole disk encryption is suitable here. TrueCrypt was my first idea, but it brings some problems. I'll edit the post to indicate this. – Kirill Gamazkov Jul 10 '13 at 14:07
  • @KirillGamazkov Please define "some problems". – Iszi Jul 10 '13 at 14:14
  • Why don't you think whole disk encryption is suitable here ? – Stephane Jul 10 '13 at 14:19
  • First of all, I don't want to reveal the sole presence of the secured data. The system will look like usual yet-another-file-organizer unless you hit the secret keystroke and input your password. – Kirill Gamazkov Jul 10 '13 at 14:22
  • 1
    @KirillGamazkov - this is called **plausibly deniable encryption**. Please add this requirement to the question - it's extremely important. – Deer Hunter Jul 10 '13 at 14:39
  • Done. @thomas-pornin, the reason to use asymmetric cypher is as follows. Tt's bad practice to keep the keys in memory "as is". In particular, I have to take care of my decryption key. On the other hand, encryption key is not so vulnerable. In other words, I'm trying to separate the risks. However, I don't know actually whether it adds security or just complicates things – Kirill Gamazkov Jul 10 '13 at 15:11
3

I didn't even finish reading your OP to determine the scheme is way too complex.

Feed the user's password into a key derivation function; PBKDF2, given the appropriate number of rounds of hashing, is fine. The value produced is now the symmetric encryption key for all data, using AES or whatever off-the-shelf encryption algorithm you choose. Once encrypted, it doesn't matter where each file is put; nobody can read the plain text contents without knowing the user's password (which is a true secret) and the specific settings for the PBKDF2 function (which is not) and the cipher mode (ditto).

If you want the ability for the user to change their password, without having to decrypt and re-encrypt the entire data store, then you need an intermediate. Generate a random key and IV for each file being secured. Store the filename, key and IV as one row of a master keyfile, the contents of which are encrypted using the user's password and a constant IV. Whenever the user changes their password, decrypt the keyfile using the user's old password-based key and the current IV, then derive the new key from the new password, generate a new random IV, and re-encrypt the keyfile.

If you want the user to be able to recover their data if they forget their password, then one of two things must happen; a copy of the master keyfile must be encrypted using a key known to the host system, or else the user's password or derived key must be encrypted in a similar way. This can be accomplished with public keys allowing the user's client software to handle this additional step securely. In the event a recovery is needed, the private key can be applied to decrypt the master keyfile (directly or indirectly depending on the exact method), which can then be re-encrypted with a replacement password supplied by the user.

Some additional things to consider:

  • At no time should the user's plain text password, or unencrypted versions of any file, especially the master keyfile, be persisted to the hard disk. If it's ever written to disk, then an attacker can dump the disk, examine its contents and discover the user's secrets.
    • This requires that you have enough control over the operating system to ensure that none of this data is ever swapped out from RAM to the virtual memory pagefile (or that it is removed promptly when no longer needed).
    • This also generally requires that such secrets never be in RAM for more than a transient period of time while actively deriving the password key or encrypting/decrypting secured files. Once you no longer need the plain text, destroy it.
  • Your program will be encrypting and decrypting a large amount of data. This could, over time, make the scheme vulnerable to cipher fatigue, where after a large enough amount of data has been encrypted, the entropy inherent in the cipher's secrets will be exhausted and the state of the cipher will be repeatable.
    • Typically, this isn't a concern for any one file, or even a large data store, but it could be problematic if you use one key for everything, forever.
    • So, don't. Every time your user updates an encrypted file, generate a new key and IV for that file, and update the master keyfile with the new info. Because that requires decrypting and reencrypting the master keyfile, it's also not a bad idea to generate a new random IV for the reencryption step (of course the key is relatively static, but these operations are also good opportunities to increase the strength of the KDF by increasing the number of hashing rounds).
KeithS
  • 6,758
  • 1
  • 22
  • 39
  • Is there any options except PBKDF2? Maybe combination PBKDF2 + scrypt to affect both CPU and RAM costs? – Kirill Gamazkov Jul 11 '13 at 06:35
  • sCrypt should be fine on its own; its computation is both EXPTIME and EXPSPACE when both are plentiful, and to use constant space requires exponentially *more* time. Most implementations generate a 512-bit digest; XOR-fold that into a 256-bit AES key, generate a random IV, and you'll have a scheme I'd trust (*if* properly implemented; use an authenticated mode for AES, watch out for possible oracle or timing attacks, and keep all sensitive data as volatile as feasible). – KeithS Jul 11 '13 at 14:57
  • Just don't get caught up in the new sweetness and use sCrypt for sCrypt's sake. Lots of amateur cryptographers, myself included, fall into the trap of overestimating the sophistication level of the average attacker by several orders of magnitude. Unless you're designing enterprise-level security to be used by large public corporations or government agencies with a lot of very valuable data to hide, the profile of your attacker is a twenty-something script kiddie with a GPU cracker looking for low-hanging fruit. – KeithS Jul 11 '13 at 15:45
1

I think you are talking about a few security measures that got mixed up.

1) Privileges - you need to secure no access to the folder wherever the file is (whether hidden or not). Use windows/Linux built in privilege system and allocate read/write/execute rights based on users. If someone planted you a virus or hacked your pc and obtained the root/Sys user rights..then you are in trouble.

2) Password/Password Key protection - AES 128 bit is a strong alogrithm that should be used to encrypt the content of a file. But remember that the key to the encryption lies inside the system..if the key is hijacked, the file can be decrypted.. keys are actually used to encrypt and decrypt data in symmetric encryption remember! So your job is to protect the key.

3) Encryption Strength- Encryption strength has got a few factors, you need to use an encryptions that arent predictable, and use good elements of diffusion, confusion, avalanche effect, Initialization Vectors (IV) and a strong Keystream generator to create a good strong keystream.

4) User password management- Users password must be strong, comprised of alphanumeric and non-alphanumeric characters. Also the panel of the password entry shouldnt be easy to brute force, use captcha or slow down the time each time an incorrect attempt was made, that would prevent brute force.

BlackFire27
  • 216
  • 2
  • 9
  • 1) In my case - little single-user file organizer - it's not worth the efforts. It gives no protection from the worst case - stealing the whole machine, while if I handle the worst case, I will also handle hacker's penetration. 2) That's it. AES keys lies inside the system. To protect them, I have to use some secret that lies outside - in the user's head. So, the question is: **how?** 3) Thanks for keywords to feed Google with. My task becomes more specific. 4) 1. Teaching people to use strong passwords is the separate story. 2. I'm about to use another method (see next comment) – Kirill Gamazkov Jul 11 '13 at 04:52
  • Once again, 4) 2. I won't tell user whether entered password is valid or not. In case of incorrect password the system will just create an empty "profile", which is fully functionally, but doesn't contain any file yet. I've described that in the OP near **plausible deniability**. In other words, initially there is one profile in the system, secured with empty password. When the user enters his secret, system swithes to a corresponding profile, which is created if it didn't exist. – Kirill Gamazkov Jul 11 '13 at 04:59
  • 1
    Yeah, but it still doesnt protect you from brute force. A hacker might enter 2 bad passwords and see a profile being created, and he will be suspicious. Then he will try many passwords until he gets a different response. The attacker will think it is weird that on entering any password a profile is created.. he will think that there is a specific password for a special account, which should open the true profile. The attacker may understand that there is a profile/role per password architecture. – BlackFire27 Jul 11 '13 at 05:54
  • Differential cryptoanalysis have here we. OK. Thanks for pointing out. There's no "true" profile. You've enter your secret - you've got profile. You can fill it with files or forget about it. There can be as many "true" profiles as you wish. Actually, I can store created "profile" to the disk as late as first file import occurs. Thus, attacker won't see any differece between entering right/wrong passwords... or will he? I should take care to minimize that difference. But, of course, I'll make BF slooow using scrypt. – Kirill Gamazkov Jul 11 '13 at 06:16