1
$\begingroup$

Problem. I want a longer key out of password than my hashing function provide.

Idea. I want to hash password multiple times rotating chars one position each time and use composite key.

Question. Do I really weaken the password?

Example:

Password=carphagen

  • Key1= BCrypt("carphagen")=OZrxJo..IAwipd8hHm69IGFiPz/Y/veK

  • Key2= BCrypt("ncarphage")=PiG1Qndv8kOHDFoEwhbM.rqtM4O5XNR2

  • Key3= BCrypt("encarphag")=Hbrz35n4pwOLsWnMdyuQ7Ze1XMH/QnmC

  • . . .

  • KeyN= BCrypt("rphagenca")=OapAj6P0OS5P0m20f5oAKY482hEvfLhy

N < less password length

Key = Key1 + Key2 + . . . + KeyN

Question. The attacker knows Key, does he get help with password?

Small Update: BCrypt Salt is the same and is known. It is removed from the hash and not used as a part of the Key

$\endgroup$
7
  • $\begingroup$ Hmm, this has flavours of a counter based pseudo random number generator or perhaps CryptGenRandom speculatively. And BCrypt itself is secure... $\endgroup$
    – Paul Uszak
    Jun 29, 2017 at 12:04
  • $\begingroup$ You could use something like PBKDF2 which offers variable output length $\endgroup$
    – hunter
    Jun 29, 2017 at 12:22
  • $\begingroup$ hunter, thanks. I might take your advice if the Idea is vulnerable. At this point I have invested time in BCrypt and like it $\endgroup$
    – Evgeny
    Jun 29, 2017 at 12:38
  • 1
    $\begingroup$ I can't say I trivially see how it could weaken the password, but on the other hand, I must say that I do not see any benefits when comparing it with PBKDF2, or even better Argon2 $\endgroup$
    – Lery
    Jun 29, 2017 at 12:40
  • $\begingroup$ I like BCrypt JavaScript implementation, which I can verify and use in a web page. PBKDF2 can be brute forced with small circuit hardware. In my case I can afford luxury of 15-60 seconds of BCrypt hashing, which would protect from brute force. $\endgroup$
    – Evgeny
    Jun 29, 2017 at 13:13

2 Answers 2

6
$\begingroup$

Do I really weaken the password?

To some degree, yes.

The function is considered public, and the attacker can test random passwords with it and check the output and compare it to your key. Then he finds the correct password, even if he actually just guessed one of those permutations you defined. In your example:

  • Actual password is carphagen
  • The key is: key is $Key = Key1 + Key2 + . . . + KeyN$
  • The attacker tries the password ncarphage, which is the passwords permutation to generate $Key2$.
  • The attacker gets as output: $Key2+\dots$.
  • He still can easily detect that the partial key is the same as in the given output, even if it's not at the same location.

One more thing to consider: Your idea takes $N$ times the computation time of a single BCrypt call. But an attacker can actually check one password with a single call to BCrypt (if he's not interested in checking the permutated passwords). And that's quite bad - testing a password for the attacker surely should not be less than regular usage.


Here's an alternative idea:

  • Use BCrypt to generate $k_0$ from your password - with enough iterations that it fits your requirements.
  • Use a different key derivation function to generate values $k_1,k_2,k_3,\dots$, by using $k_0$ and a counter as input. If the function utilizes iterations, just use one.
  • If you want to increase the computation time, increase the number of iterations to generate $k_0$, don't apply them to the computation of $k_1,k_2,\dots$ .

For the second step, there are various possibilities for a KDF. For example you could use a keyed hash function (also called MAC), a CSPRNG seeded with $k_0$, a PRF, ...

A second alternative: Use another password-based KDF, which supports variable length output. BCrypt is quite old and there are more recent alternatives, two examples would be Argon2 or scrypt.

$\endgroup$
4
  • $\begingroup$ But BCrypt adds salt to every hashed password, so testing ncarphage using the salt for Key1 won't give you any useful information unless Key1 and Key2 use the same salt (which is highly unlikely). $\endgroup$
    – r3mainer
    Jun 29, 2017 at 13:04
  • $\begingroup$ The salt is known — it's right there in the hash. What I'm saying is that computing the hash of carphagen with salt A tells you nothing about the hash of ncarphage with salt B. $\endgroup$
    – r3mainer
    Jun 29, 2017 at 13:11
  • 1
    $\begingroup$ @squeamishossifrage You're right about that. But the question didn't mention using different salts for the different BCrypt calls. And the point about the attacker only needing to evaluate one BCrypt call to exclude a possible password is still valid. $\endgroup$
    – tylo
    Jun 29, 2017 at 13:13
  • $\begingroup$ Yes, the salt is the same and is known, though it is not used as a part of the key (the salt is removed from the hash) $\endgroup$
    – Evgeny
    Jun 29, 2017 at 13:42
1
$\begingroup$

An idea I had ( not sure how cryptographically secure it is ) : If $ x $ is your password and $ k $ is your key then you would compute $ hash(x) $ and append that to $k$ then you would compute $ hash(x + the previous hash) $ and append that to your key and so on until your key is of adequate length and this system would solve the vulnerability explained in the other answer ( I think 😂 )

$\endgroup$

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.