Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

According to http://gaganpreet.in/blog/2013/07/24/kwallet-security-analysis/ , the KWallet password management system is quite weak, it uses key splitting, Blowfish 56, and no salt.

The key generation can be described as – break up user password into blocks of 16 characters each, and apply SHA1 2000 times on each of them. This is key stretching without a salt. These blocks are then trimmed and concatenated to fit into 56 bytes, the maximum key length allowed by the Blowfish cipher.

It also says that, although it uses CBC, the way it uses it it becomes ECB.

KWallet uses CBC, or to be accurate, it pretends to – the keysize used for CBC is the length of the string to be encrypted, which turns CBC into the less safe mode of cipher – ECB.

My issue is, I use the same password for root as I do for my KWallet. /etc/shadow is only readable by root, but my .kwl file is readable by anyone, so anyone can get the file and try to brute force it, with possible success.

So is there any way I can improve the security of KWallet? It's not just for my manually inputted passwords, it's also for web browsers and applications which rely on KWallet to store passwords (e.g. Chromium), so I can't just switch to another program. Perhaps I could edit the source code, or find a fork that's compatible?

My final questions are: Is there any way I can improve KWallet's security, and how much of a security concern is using it?

share|improve this question
add comment

3 Answers

The blog post you quote is quite imprecise in its formulation. However, by looking at the KWallet source code, especially this file (for the password hashing) and that file (for the invocation of the encryption code), we see the following:

The password is extended into a symmetric key of size 20, 40 or 56 bytes (160, 320 or 448 bits) by applying SHA-1 repeatedly. Namely:

  • If the password has length 0 to 16 characters, the key will have length 20 bytes and be the repeated application of SHA-1 (2000 times) on the password (the password is hashed, then the 20-byte output is hashed again, and again, for 2000 invocations of SHA-1).

  • If the password has length 17 to 32 characters, then the key will have length 40 bytes: the first 16 characters are processed as above, then the remaining characters are processed similarly, yielding 20 more bytes.

  • If the password has length 33 to 48 characters, then the key will have length 56 bytes: the first 16 characters are processed as above, the second chunk of 16 bytes of characters as well, and then the third chunk; the output for the first chunk is then truncated to 16 bytes, for a total of 56 bytes.

  • If the password has length 49 characters or more, then the 2000 SHA-1 invocations will happen four times. For the fourth chunk, the complete rest of the password will be used. The four 20-byte output are then each truncated to 14 bytes, and these are concatenated, yielding a 56-byte output.

As a password hashing function, it is quite poor. It is clunky and not regular. It is not salted, allowing for efficient parallel attacks, when several KWallet instances must be broken (as usual, "parallelism" also means that precomputed tables can be used, negating the slowing effect of the 2000 SHA-1 invocations). Moreover, it "splits" the password, so if an attacker finds a password hash, then he can attack each chunk independently of the others. This means that the security of the whole thing relies a lot on how well the Blowfish block cipher behaves when used as a hash function. This is, at best, a poorly studied property.

The encryption purports to use CBC, but does not. In CBC, you are supposed to encrypt a sequence of blocks (8 bytes per block with Blowfish); before encrypting a block, it is first XORed with the previous encrypted block. For the first block, we must conjure a formal "previous block" which is the Initialization Vector. CBC requires a random IV.

In the KWallet code, we see that the code indeed prepares a random IV of the right size.... then completely fails to do CBC. The call to encryption is:

int rc = bf.encrypt(wholeFile.data(), wholeFile.size());

(line 291 of backendpersisthandler.cpp)

Looking at the implementation for this encrypt() method, in cbc.cc, we see that it will create a temporary buffer of the same size of the whole file; then fill it with zeros; then XOR all these zeros with the data to encrypt (which won't change the data...); then proceed to encrypt each block independently of each other. This is, indeed, ECB mode, not CBC. It is quite obvious that this is a programming error; the lesson to learn, though, is that since KWallet appears to work, then the mistake was not detected: security cannot be tested through functionality.

(This implies that the random IV which was computed does nothing here; it is encrypted by itself but does not impact any other byte in the whole file.)

ECB mode is known to be weak in the following sense: it leaks information about what blocks are equal to each other. For an uncompressed picture, this is deadly, as demonstrated with the usual penguin image. For a KWallet, this is a source of worry: the internal structure has some redundancy, and this may be exploitable, although it would require some effort to ascertain the extent of the issue.

Note that since the password is not salted, two successive versions of the KWallet protected with the same password will use the same symmetric key, so block equalities leaked by ECB apply to all successive versions of the KWallet.

There is a homemade MAC. The last 20 bytes of the file (excluding some padding) contain a SHA-1 value computed over the rest. This is, generally speaking, not a good MAC. It would be an extremely bad MAC if the encryption used RC4 or a block cipher in CTR mode. With a block cipher in ECB mode (as used here), it is not as bad, but still poor.

The whole code reeks of homemade crypto slapped together by someone who did not master the concepts. This is bad. Also, I find the code to be atrocious in many respects (e.g. when the password chunks are hashed, the loop which invokes SHA-1 repeatedly is ruthlessly duplicated; that's a shooting offence). To "improve" KWallet, I suggest deleting the whole code and starting from scratch.

It seems that the code includes some optional support for not doing the password hashing and encryption itself (as we saw, it does it very poorly), but instead using GnuPG. Now THAT is a good idea. GnuPG implements the OpenPGP format which, for all its shortcomings, is at least decent cryptographically speaking (when properly used), and GnuPG is also known to be a tolerably good implementation. To improve storage of your KWallet, see if you can convince your computer to use this GnuPG support code and format.

share|improve this answer
add comment

I'm the one who wrote the original blog post in question. I also wrote a Python script to read KWallet files, which should be easier to understand than the original KWallet code.

Tom is spot on with his analysis though. I tried to write for an average user, and didn't dig into the technical details. The KWallet code is in a horrible state, and other than the security issues described, the code is very poorly documented. KDE 5 will to bring a completely new password store, which is still a while away.

KWallet with GnuPG is in development, but has not been released yet. It'll come with KDE 4.12.

share|improve this answer
add comment
  • First thing you should do is not use the same password as root. Root is sacred!
  • You could protect the the password database better by creating a TrueCrypt volume and dropping it in there.
  • You could edit the source code but only if you really know what you're doing. If you don't know exactly what to do in the source you could make it worse.
  • Lastly you should look at KeePass it's open source, cross platform and a great password generator/manager.
share|improve this answer
I like KeePass because too many other recommended password managers tend to be proprietary managers you don't control. –  LateralFractal Oct 17 '13 at 14:48
As I said in the OP, I'm not using this just as storage of manual passwords, for that I use Truecrypt. I use this because in KDE it integrates with Chromium and other applications so they don't have to store sensitive information in plaintext like it otherwise would have to do. Is KeePass able to integrate with the KWallet system? –  taree Oct 18 '13 at 3:47
add comment

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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