I will try and make this idea as detailed as possible, to help the community in assisting and possibility helping others with the same problem.

Background Info

My system has 60 users. Each user has a 8 digit password, ranging from 00000001-99999999. These are generated randomly to be unique by admins. This password is only used as a "check" access to my program, its not used for anything else. The program and password are both stored locally.

My Idea

I would compile a database of passwords in this fashion

Password = UsersPassword
Data = Randomly generated 128bit string (So every encryption is unique)
NewPassword = ""
For I to 20
  NewPassword = NewPassword & Hash(Password, SHA_512)
EncryptFile(Data, UserPassword, ALG)

This means, though the user password only has 10 billion guesses the password for encryption is 536870960 keys long. This becomes my stretch. As on my computer trying to decrypt such a file takes 60 seconds (this is just for concept i would make it a little faster for use).

This also means passwords are never stored in the file, but rather its the password itself which is the "check". This means a rainbowtable doesn't work, brute-forcing does and 10billion isn't huge but if it takes a second per guess the time / effort value comes into the play.

Here are the encryption/encryption I can use;

  • CALG_3DES 0x00006603 Triple DES encryption algorithm.
  • CALG_3DES_112 0x00006609 Two-key triple DES encryption with effective key length equal to 112 bits.
  • CALG_AES 0x00006611 Advanced Encryption Standard (AES).
  • CALG_AES_128 0x0000660e 128 bit AES.
  • CALG_AES_192 0x0000660f 192 bit AES.
  • CALG_AES_256 0x00006610 256 bit AES.
  • CALG_AGREEDKEY_ANY 0x0000aa03 Temporary algorithm identifier for handles of Diffie-Hellman–agreed keys.
  • CALG_CYLINK_MEK 0x0000660c An algorithm to create a 40-bit DES key that has parity bits and zeroed key bits to make its key length 64 bits.
  • CALG_DES 0x00006601 DES encryption algorithm.
  • CALG_DESX 0x00006604 DESX encryption algorithm.

I know CALG_AES_256 is extremely strong but from my tests runs very fast. I need a slow one, CALG_AES_192 seams to take longer and from my research is equally unbreakable.

Is this a valid idea?

  • 4
    I honestly think that you are asking the wrong question. To my mind it isn't so much as whether the technique is valid but why you would want to do this rather than use an existing and well tested library? I can't think of a good reason myself. – Julian Knight Sep 13 '16 at 11:43
  • 3
    Also, if you are limiting passwords to numeric only, you've constrained them too much already, reducing the address space by a very large amount and you've made the passwords harder for users to remember. – Julian Knight Sep 13 '16 at 11:45
  • Hi Jullian, 1. I agree on the password length but that is something i have no control over, its issued by their admins. 2. Mostly because i cant integrate these into my programs, that said though i am using existing librarys? as i am using recognized hash / encryption / decryption ALGS – ian smith Sep 13 '16 at 12:02

So much wrong, it's hard to know where to start.

To sum up: your idea is crap. Throw it out and start over using a proven library.

First: your passwords suck. 8 random characters can be brute-forced with many password hashing algorithms. You chose a nice fast hash and further limit passwords to 8 digits. These will fall quickly. And as a side note, your admin-assigned scheme makes passwords harder to change and has a nice built-in compromise in the form of the admin who will know the password already.

Second: your key stretching sucks. Your password hash is based on 20 rounds of a fast hash (SHA-256). Good use of a fast hash (in PBKDF-2) requires tens or hundreds of thousands of iterations at a minimum. Your hash either does a bitwise AND or concatenation, I'm not clear on your terminology. Either way you're hashing the same thing every time because you did not include the counter in your hash. If it's an AND then your iterations actually do nothing at all because anding something with itself is a no-op. If it's concatenation then you could just do one hash and repeat it several times. And your encryption won't use such a long key. You can't fix this just by throwing the counter into the hash either. ANDing so many random numbers together will lead to numbers which are always nearly zero.

Finally, you're relying on the time to decrypt the whole file for the security of the system. This won't work. An attacker will instead decrypt only a small portion of the file to check each password. They will decrypt just far enough that the text would look reasonable, or some "magic string" for the file type would be revealed, if the password were correct. Then move on to the next password if this one is not feasible.

With a good key you're correct that 192 bit AES is perfectly strong enough. But your key sucks because you've rolled your own crypto. Don't do that.

| improve this answer | |
  • First Point: 100% agree but i cant change that. Second Point: This part isn't meant to be the key stretching, its meant to be used with decryption to archive stretching. So it turns a 8 "in length" password into a 5202 "in length" password. This leads to a single encrypted file being massive – ian smith Sep 13 '16 at 12:46
  • As this means an encrypted file might be almost 200MB+ in size for a single password. Decryting that much data takes time, that would be my stretch? – ian smith Sep 13 '16 at 12:47
  • 2
    @iansmith As Ben explained in the fifth paragraph, the attacker has no obligation to decrypt the entire file. Almost all block cipher modes of operation or stream ciphers will allow you to decrypt/bruteforce the first bit of the file and since the hash is simply repeated, decrypting the first occurance is enough. – billc.cn Sep 13 '16 at 13:15
  • @billc.cn so taking that point onboard, lets say i make the "data" to be encrypted 1 char long. "A" for example but the password string would be the result of 10,000 of hashes resulting in a encryption key of 1073741824 in length. Now the attacker would have to "decrypt" the password file, which only has 1 letter using a key that is 1073741824 in length. Yes the attacker can brute force it, using the 10 bill combinations but as i am guessing decryting with such a large key takes a fix time that becomes my stretch? – ian smith Sep 13 '16 at 13:19
  • 2
    But there's no cipher that takes an "encryption key of 1073741824 in length". AES-192 uses a 192-bit key, for example. Your library may allow a longer password but will internally either hash or truncate the input to match the cipher. So effectively, at best, your whole setup has the strength of 1 SHA512 + unknown hash used by your lib to shrink the key + AES192. This is very weak in terms of bruteforce cost. – billc.cn Sep 13 '16 at 13:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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