📜 ⬆️ ⬇️

How I did the web version of KeePass

Somehow I had to add a list of passwords to the admin panel. The database was stored on the server in the KeePass format (kdbx v2), the server was on the node - without thinking twice, I took the first available packet and did it. And then it took the same thing, but directly from the user in the browser, without a server. Nothing found. The first desire was to fork the lib and replace the use of node api, but from the first viewing of the code the desire disappeared, I decided to do it myself.



Under the cut I will talk about the problems that I encountered, and how to solve them

Reading kdbx format in a browser


I had to study the kdbx format, which, unfortunately, was not described anywhere except in the source code and this small article. But he is quite simple. To read kdbx, you need:
  1. read binary header ( what's in it? )
  2. initialize encryption algorithm and random value generator (salsa-20)
  3. calculate password hash and key, get credentials hash
  4. N times (the value from the header) encrypt the hash, having received the master key - this is the most computationally laborious operation
  5. decrypt data
  6. check the correctness of the decryption by comparing the data block with the block from the header
  7. GZIP times
  8. parse xml
  9. generate salt for protected fields
  10. on demand, when they are needed, protected fields can now be expanded
  11. read xml metadata ( what's in them? )
  12. read groups and records

Of the algorithms, AES for symmetric encryption and SHA256 for hashing are used there. The fastest implementation for the web I found is asmCrypto , it is written in asm.js, it works faster than other browser alternatives and, importantly, it can assemble in pieces, including only the necessary modules with algorithms. Having patched it so that all key transformation cycles took place inside asm.js, without additional data copying, I managed to achieve a speed of 4..7 times less than that of the native implementation (if you put a 1 second delay in KeePass, the seconds file will open for 6). With default settings, the file opening time is on average about 200 ms. WebAssembly will save us all, but for now.
UPD: in the comments suggested about WebCrypto, now the opening time in browsers with its support is almost as good as KeePass.
')
To work with gzip, pako took it - it is small, fast and MIT. Compared to encryption, he did not notice any significant decompression costs.

The result is kdbxweb , which works in node.js and modern browsers. Because of the need to work with the binary format, there are no older versions in the list of supported browsers. Library + dependencies turned out to be 150kb.

application


So, there is liba. Why not write a web interface for it now? A good password manager for the web should:

Most of this has been achieved.
The application was written on backbone + zepto (at first I wanted to try Angular2, but somehow it didn’t go, the generated code of the framework itself is so far obtained in more than 1MB, probably still too beta and then it will be better).
The versions of browsers that support the reader of the format are not so far from the latter, so there are practically no cross-browser crutches.

input type = password


When you enter text in any input, all entered values, even with input history, can be stored in the browser's memory indefinitely. And if in the desktop application you can clean the memory, then in the browser you do not have control over the memory occupied by strings: when the GC wants it, then it will clean it, but it may or may not memory it:



Some applications believe that the memory can not be cleaned even after the file is closed, although for applications this is, of course, not as critical as for the web:



It will not work like this, if the application hasn’t got anywhere, then in the browser I wouldn’t enter the master password in such an input, so I had to make a bicycle: when entering, the XOR-characters with a random sequence chosen so that the output would be some unused unicode block. They are shown by the input, thinking that this value is (all the same, there are asterisks), the value itself is thus character-by-character stored in the buffer. Of course, you can add the value to the key with full memory access, but this is another level of complexity:



Saving files


Saving the file generated in the browser is not so easy, but you need to:



There is FileSaver.js, but there is an ambush in Safari, here is a thread with interesting comments , where the author asks to buy him a macbook. Almost all browsers now support
<a href="" download="file-name.ext">
. download ( webkit.org), Blob, , . base64, . , FileSaver , Unknown. - — , .


, , , electron. , API , :



- , . node-webkit, electron-builder electron-packager, .
, dmg mac os x exe installer windows ( deb linux ):
{
  "osx" : {
    "title": "KeeWeb",
    "background": "../graphics/dmg-bg.png",
    "icon": "../graphics/app.icns",
    "icon-size": 80,
    "contents": [
      { "x": 438, "y": 344, "type": "link", "path": "/Applications" },
      { "x": 192, "y": 344, "type": "file" }
    ]
  },
  "win" : {
    "title": "KeeWeb",
    "icon": "graphics/app.ico"
  }
}


Electron . , File path, . , fs.writeFile.




KeePass . -, 2015, -, , . , , font awesome :




, KeePass , - . - (, — ) — .



, :



, , , Hue. KeePass .

Dropbox


, SPA dropbox-js «» secret key , . popup-, ( ).


API : chrome , firefox — , IE , . , - . . , Copy, input. , - , :




, , , . , , . . All Items ( Ctrl/Cmd-A, .. ), -, , :



: , , . , , , :



, UI . , , . , .


sourceforge KeePass, Dominik Reichl ( KeePass) , , , , .


, . , . XML, , . , , .

, , MIT.


keeweb — -
releases — -
github
keeweb.info
kdbxweb — kdbx node.js
kee_web — twitter

Source: https://habr.com/ru/post/269895/


All Articles