1
$\begingroup$

Assuming

  • We want to generate a password of 32 bytes, using a keyfile as source but not using it directly but via an intermediate step;

So:

  • We have a file of 100MB file with high entropy
  • We ask the user to give 2 values, (A) one is the offset into the file, the 2nd (B) is chunk size

We then:

  • Open the file and skip to offset (A)
  • Read as many chunks of size (B) until end of file
  • Per chunk scrypt it into value (scrypt set to take ~1 sec), crc the out block to a integer value and add it to the 32 byte array (increment index for each chunk, reset to 0 when at 32)

If I'm correct it would take an attacker ~10 years to go through the whole keyspace with a brute force attack. Would this be correct or am I missing something here (probably) - as in for each byte (offset) there are 100MB/32 possible variations in size (there are some details that are important which I'm skipping over - but it's the general idea I'm thinking of)

J

$\endgroup$
5
  • 1
    $\begingroup$ Welcome to crypto-SE. The real question here would be: What is the advantage of this compared to simply using scrypt with salt and pepper? Basically you have two integers as input, and need the file at hand. What the real problem could be: If you leave $A$ and $B$ up to the user, their entropy will be really bad (worse than in most passwords - large numbers are not intuitive). And if you choose them for them from all possible values, why do you need the file at all? $\endgroup$
    – tylo
    Jan 30, 2017 at 12:30
  • $\begingroup$ Thanks. The idea would be that the attacker would need both the file and the number. Basically a keyfile but with additional protection of a 'numeric' password. I agree that users will probably chose simple numbers, but even then - if there are 100 100MB files on the drive it would be infeasible for an attacker to try them all (assuming he has access to the files). Let's say those files are jpeg's, the user has to remember that 1 image, and two numbers (and let's assume they are bad numbers) - it would seem safer than just using default scrypt to expand a key. No? $\endgroup$
    – Jackson
    Jan 30, 2017 at 12:50
  • 1
    $\begingroup$ No, it would not. You have the constraint, that getting the key should be feasable for regular usage - e.g. 1 sec. That related to the attacker on 1-to-1 basis, 1 sec each try. You can set that parameter in scrypt already, iterating over just different (but also known) data of any size makes no difference at all. Any kind of assumption "infeasable to try out all" has to be based upon the distribution of those values - and if you let the user choose the numbers (this is bound to be really poor entropy), that is just a wrong assumption. More complexity does not automatically imply more security. $\endgroup$
    – tylo
    Jan 30, 2017 at 13:20
  • $\begingroup$ Is there a particular reason you want to derive passwords from files instead of just storing the passwords encrypted? $\endgroup$
    – Elias
    Jan 30, 2017 at 14:33
  • $\begingroup$ the main reason is that I've (and everybody) has 10k files on their harddrive. Using one (.jpg, .mp3 - with high entropy) would be a good source for a key - but just using it as a plain keyfile would make it very easy for an attacker - so how can you make it so that it would take large amounts of time for the attacker as to make it much more difficult to extract the key from (one of) those files. Encrypting the passwords would still leave me with having to have a master password. $\endgroup$
    – Jackson
    Jan 30, 2017 at 17:42

2 Answers 2

2
$\begingroup$

If I'm correct it would take an attacker ~10 years to go through the whole keyspace with a brute force attack. Would this be correct or am I missing something here

No

First let's consider simple fact: The more power you have the shorter attack will take. There is no such thing as "it would take attacker 10 years". Also, 10 years is very, very short compared to proper key, which is very far from measurement in life-times.

Also, you seem to imply that fact that attacker will have to try multiple files will make it hard. Imagine that I have botnet with 40 000 machines. I can assign one machine for each of your files. So it will just take me as long as it took you to decrypt it (if not better). I can then try most common choices of A and B which would me take maybe day if i'm unlucky (considering that your decryption takes you minute, which is massive amount of time for password-based encryption).

While when you had used password with just 6 characters, I would have somewhat harder time recovering those.

If you assume that attacker knows your file, your whole process is basically useless. There simply isn't enough entropy in A, B and file selection. If you assume attacker doesn't know your file then all you do is still useless, because you would be just as secure in getting first 256-bytes of that file (since you assume that this file is high-entropy, if it isn't consistently high-entropy then you simply hash that file and end in same thing).

Also, one advantage of using passwords is that user himself choose how secure he is. If he uses 4-character password, it will be broken. If he uses 20-character password then there is good chance it will never be broken. With your scheme everyone who doesn't have 20TB worth of storage for keys is limited to 4 characters of security (and with 20TB you won't be much better).

TL;DR: Use established best practices. With your scheme you are arguably worse than with md5.


Also speaking of your scheme, it seems to come from world of "security by obscurity". There is no point in using crc-16 to shorten your key. Scrypt returns high-entropy mixed key, which you can simply cut. But your scheme doesn't spread entropy trough your returned key (which is terrible - you can know part of key with part of file). Also, you use scrypt to convert key to key, which is something pointless, since your key generation will take longer with longer file. So long in fact that user will get bored. Just imagine 60bytes file with A=0, B=1. It will take one minute to get key. You would be far better with just scrypting hash of whole file (you would still be able to configure scrypt time to something reasonable).

$\endgroup$
3
  • $\begingroup$ Note that I'm not encrypting. Just generating a password. I understand that if somebody has a botnet of 40k machines they will have the key faster :) But if (for whatever reason) somebody gets standard keyfile they only need 1 machine. I understand that just using 2 values is way too little entropy though. Not sure where you get the 20TB from, 100 files of 100MB would be 1G. Good point of not spreading the entropy through the whole key. Also not sure why it is problematic that it takes longer - that is just the point of using scrypt. Thanks though, I'm a noob so trying to learn here! $\endgroup$
    – Jackson
    Jan 30, 2017 at 16:06
  • $\begingroup$ I did use "encryption" because of shortcut in my brain, obviously what you are doing is "key generation" aka KDF. I said 20TB of keys, when I meant that you had to store ridiculous amount of keys to just barely improve security (100 possible keys is nothing, so I went with 40 000 in my answer - still nothing). Why taking so long is bad: user will get bored of your KDF very quick with such long process! Just try using KDF with 1minute wait on daily basis :P. Also: 100 * 100Mb = ~10Gb, not 1G. $\endgroup$
    – axapaxa
    Jan 30, 2017 at 19:02
  • $\begingroup$ ok, maybe i'm still explaining it badly. For me to generate the key would be to specify the file, give the 2 values and it would generate the key in 1 second. That key is my master to key to whatever vault/container/etc. It would be good if it takes long for anybody else! They'd have to iterate each file, each byte, each chunk size - and it would at least take 1 sec for each time. That would take 1e+12 seconds, right? And indeed it's 10G and not 1G - also a brain shortcut here :) $\endgroup$
    – Jackson
    Jan 30, 2017 at 20:15
1
$\begingroup$

It seems you are mainly after two-factor authentication. In that case: perform scrypt (or any other password hashing scheme) and use the resulting symmetric key to wrap a pre-generated private key. Now you can store that private key on USB. Alternatively you could use a smart card or USB HSM.

Now you can authenticate using the private key instead of a passphrase. If private key authentication is not possible you could also encrypt a passphrase (making sure you do not leak the size of the pass-phrase).

PGP would come to mind as it encrypts your private key as described for file encryption. For transport security SSH can do something similar as well.

$\endgroup$
2
  • $\begingroup$ yes, good that you mention two-factor because that's basically what I'm after. Remembering a 32 byte high entropy password is difficult (if not impossible), using a keyfile is better, but if the attacker gets that (from cache, swapfile, etc) i'd want to have some more guards. You're saying wrap the private part of a key pair - I think I understand that, but what do you give to scrypt as input? not sure if I follow you there. Thanks! $\endgroup$
    – Jackson
    Jan 30, 2017 at 16:44
  • $\begingroup$ You'd require a medium strength password and the key together. You cannot guess the password without the key file. If that's not enough you'd have to either use hardware protection (smartcard, HSM, IronKey) or other factors such as biometry or smart phones (etc. etc. etc.). $\endgroup$
    – Maarten Bodewes
    Jan 30, 2017 at 17:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.