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

4 Answers 4

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

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
  • 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

Oy! Enough with the cipher mumble jumble, lets start with some remedial security:

chmod 600 *kwl

Why the hell is your KWallet file visible to anyone but you?!?

Second, who else uses the computer or otherwise has access to your stuff? If you are sitting behind a half-way decent router at home on a wired network that includes your computer, the router and a printer, then you probably have other things more important than fretting over cipher strength.

Third, TrueCrypt is great, but can be a bit of a headache to set up. You can use the user home directory encryption built into your distro (in openSUSE I have an option to check a box to encrypt user home directory), although that will end up with a fixed size of your home directory (sort of--I think you can mount additional stuff in there and make it look as big as you wish).

If you have somewhat modern SSD it might come with built-in hardware encryption (and many laptop HDD used in business class products, esp. Hitachi had this in their 7200 RPM 2.5 drives) which would protect you if you are at risk of your computer growing legs. When you log into the bios (typically) the key gets put into the lock so anyone using the system wouldn't be terribly hindered, at least until they had to reset the machine. Still, good idea for all laptops, and hardware encryption means no CPU overhead.

Another option, a bit more risque, is to put your wallet (whether Keepass or KDE or even your generic bog-standard keyring) in a cloud-synced directory. While Microsoft and Apple have seem to have had some technical difficulties in figuring out how to deliver this to their Linux using customers, DropBox and Copy.com have decent Linux clients. I was favorably impressed with Copy.com's security measures, but they are a company run by humans, so something could possibly happen someday.

I have lost a few USB drives from my pockets over the years, so I am not too keen of keeping my keys on it without some serious protection. This is where the TrueCrypt level of paranoia is probably helpful. The drawback is that you cannot be assured that you can mount TrueCrypt on someone else's machine (Kinkos your brother-in-law, etc.) in any environment. An alternative would be encrypt (easy way: 7zip is portable and on most every OS and has built in support for 256AES encryption, harder way: GNU Privacy Guard (GPG, the open source alternative to PGP) which is also available on most platforms, and again I think you can run it under Windows from a USB drive. There are several other options for using AES, with some also doing Twofish or Serpent (more exotic, but probably just as good for this use).

If I was using a USB to carry around my passwords, I would be sure to run as much software as possible as a portable app (with either a subsequently deleted RAM drive or a directory that gets encrypted at the end). Most of the stuff from PortableApps.com runs great under WINE (except for that ugly Windows-look to them), although I have had problems w/ Chrome. If your aluminum foil hat is getting too tight, the kindly folk at Tor have a portable version of a semi-hardened Firefox hooked up to Tor that you can also download and run from a USB drive.

You just have to get disciplined about decryption of the key store, and when finished, using a secure wipe program to clean up traces off the USB (or whatever) drive. You also will leave copies in RAM, cache swap space, etc. so a reboot is probably needed to be sure all the keys are gone.

Again, if you do this off a USB drive, assume it will drop out of your pocket and be found by someone who really doesn't like you and/or is looking to exploit you. So no off-line files, delete history automatically, etc. and run bleachbit or whatever the portable eraser program that comes with PortableApps when you are done.

Whatever your solution, the best way to test it is to use it religiously for a few weeks and then stop (go back to whatever your previous bad habits were). Then, after you forgot all the details, try and hack into your own stuff w/ the usual and customary tools. Nose around a bit. Amazing where today's Linux distros will stick stuff you thought only lived inside the walled garden of your home.

Now my plea for others who might stumble on this years after the original post: we need Keepass integration in KDE. Maybe they need stuff like that in GNOME, Xfce, etc. but since I (and honestly, none of my cool friends either) wouldn't be caught dead running it, that just isn't as important.

I am trying to figure out how to use KeepassX as a replacement for KWallet. It is a bit more secure, and has the advantage of being portable when I am forced to used that damn'd Windows crap.

share|improve this answer

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.