2

I want to use pbkdf2 to generate a key for a symetric encryption (DES, 3DES, may be AES) algorith, that will be used to secure private data between an AS/400 and another computer (probably running Windows).

I've been "porting" the pbkdf2 c source code from a FreeBSD repository to an AS/400 (AKA as iSeries or Power system), which is BTW not a big deal.

I have also compiled the same code on a Windows system (with Visual Studio 2012) (For those who may be interested, an API which implements PBKDF2 exists in Windows 7 and Win2008R2: BCryptDeriveKeyPBKDF2())

The performance seems good enough on Windows (I admit that the Windows machine is not a "slow machine" at time of writing: Asus R751L, Intel Core i7-4500U, 16GB ram): With password = "abcd", salt = "some salt" (I will use a 64bit or more if required random value in the real application), here are some times for several iterations count (c):

  • c = 1000 => 31ms (not optimized), 15ms (optimized for speed)
  • c = 10000 => 320ms (not optimized), 94ms (optimized for speed)
  • c = 100000 => 3280ms (not optimized), 880ms (optimized for speed)

(FYI, the BCryptDeriveKeyPBKDF2() API gives slightly better results than the version I have compiled, but this is not my issue)

Now the problem is the execution speed I get with the AS/400 system:

  • c = 1000 => 12590ms (not optimized), 2946ms (optimized)
  • c = 10000 => 125889ms (not optimized), 29452ms (optimized)
  • c = 100000 => (have not tried...)

My AS/400 is not a very powerful system, but even the optimized version is really slow...

Up to now, I have read that the "c" (iterations count) parameter should be as high as possible, 1000 being the recommended minimum value for "c" in the 2000's..., and that one needs to find a trade-off between acceptable performance and security, according to the involved systems; in my case, c = 1000 takes already too much time to be computed in my opinion, for several reasons:

  • Application Reponsiveness,
  • possible DOS attacks,
  • ...

Now I am wondering: can a long and/or complicated shared secret be a solution to keep "c" as small as possible without "losing" too much "security"? (1000 for "c" is already far too slow, so I would like to use c = 100 may be...)

Is there some kind of rule, like "adding n characters to the password is somewhat equivalent increasing the number of iterations (c) of x?

Does increasing the size of the salt (e.g., 128 bits or more instead of 64 bits) increase the difficulty get back to the original data for a cracker?

ggo
  • 121
  • 2
  • Can the AS/400 run bcrypt? –  Sep 28 '14 at 17:16
  • I have searched in this direction, but did not find it was possible yet... PHP on iSeries may have this feature (I believe that recent versions of PHP have a PBKDF2 function), but PHP can't be a requirement for my application. – ggo Sep 29 '14 at 07:34
  • Slow hashes are a desperate measure to reduce the problems of weak passwords chosen by typical users. If you can use strong passwords that's much better than what an expensive hash can achieve. – CodesInChaos Sep 29 '14 at 09:08
  • Thank you for the comment. In my case it will be the responsibility of the Administrator to choose the shared secret, so it's not a problem for me (I mean: it can be explicitely written in the documentation that the shared secret *should* be "strong"). But please tell me: do you think that choosing a strong password (shared secret) is enough for my case, and that reducing the number of iteration count (e.g., to 100) for the PBKDF2 step is ok? – ggo Sep 29 '14 at 09:48

3 Answers3

1

The AS/400 line of machine has a long history. They normally use CPU from the PowerPC / POWER family, but the first models began with CPU clocked at 55 MHz, which you cannot expect to be fast... This might explain the abysmal performance that you get. Or perhaps there was some subtle issue in your porting process. For instance, aggressive loop unrolling may make a function code exceed L1 cache, which can kill performance big time (I already witnessed a 50x slowdown for such cases).

Anyway, the iterations in PBKDF2 are meant to compensate for the relatively low entropy of the input password (because the password is a password, fitting in a human brain). If you can arrange for the password to have high entropy, then you will get security with a low iteration count.

(Mind that entropy is not length. Entropy is randomness.)

Tom Leek
  • 168,808
  • 28
  • 337
  • 475
0

As the name says, a password-based-key-derivation-function (PBKDF) is used to get an encryption key from a password. Password are usually short (low entropy) and brute-forcing can be done in reasonable time. The PBKDF will then thwart brute-forcing with using a lot of time per guess.

It seems that you are in control over the key (not the user is choosing a password), in this case it is safe to do without the PBKDF and using the secret key directly. If your algorithm e.g. expects a key of 32 bytes, this key has a high entropy and cannot be brute-forced in reasonable time. Keep in mind that those 32 bytes are not an alphanumeric text, instead it is like an array of 32 random bytes.

EDIT:

From your comment i see that it is indeed a password, so the PBKDF is the correct way to go. Actually it is correct that a long password (a password with a high entropy) would allow to decrease the cost factor, though the difficulty is to ensure that the user really chooses such a strong password. The usual rules are not a good indicator, because a password like Password2014 or known proverbs fullfill most rules, but they are not strong passwords. One way out would be, that your application generates strong passwords on its own, and accepts only passwords of this form.

martinstoeckli
  • 5,149
  • 2
  • 27
  • 32
  • The "key" is a password (a shared secret); it should be (if possible) something that will be chosen by the Administrator of the application I'm writing, that users will have to type in once (or more if the shared secret changes). This is why PBKDF2 (or something equivalent) seemed to be the way to go to me in order to generate the actual key to secure sensitive data transmission over the network. – ggo Sep 29 '14 at 07:40
  • @ggo - Well then the PBKDF is indeed the way to go, i edited my answer accordingly. – martinstoeckli Sep 29 '14 at 08:06
  • Thank you for the comment. I will probably use a small iteration count then (e.g., 100), and it will be the responsibility of the system Administrator to choose a strong password. That's just fine for me. I believe I only need to insist on this in the documentation. – ggo Sep 29 '14 at 09:52
  • @ggo - Of course it depends on the importance of the data you want to protect, but at least you should explain it in the GUI where the administrator will enter his password. Even companies like Microsoft expect to tell them a generated token for activating their software, such a token would be a strong password. – martinstoeckli Sep 29 '14 at 10:02
0

Is there some kind of rule, like "adding n characters to the password is somewhat equivalent increasing the number of iterations (c) of x?

The tradeoff between Password strength and iteration count is id:log, where id is the identity, and log is the logarithm. So 1000 iterations would mean around 10 bits of additional password strength. One million iterations would mean 20 additional bits. There is however no strong 1:1 relation between the number of characters in a password, and its strength in bits, only for truly random passwords.

PBKDF is a very bad solution to a problem that would be otherwise even worse. It only adds logarithmically to the strength. Usually PBDKF doesn't create this much overall load as even for large services the number of people who log in for any given moment are small compared to the number of total users. But in your case the load problem PBDKF clearly applies.

user10008
  • 4,315
  • 21
  • 33