You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
antelle 4a7b57e1e5
Merge pull request #30 from keeweb/dependabot/npm_and_yarn/js-yaml-3.13.1
1 week ago
.github Update FUNDING.yml 2 weeks ago
build/config fix #26: library usage issues in node.js 1 month ago
dist generating missing ids while reading files 2 weeks ago
lib generating missing ids while reading files 2 weeks ago
resources generating missing ids while reading files 2 weeks ago
scripts default encryption rounds increased to 300000 1 month ago
test generating missing ids while reading files 2 weeks ago
.eslintrc added eslintrc 2 years ago
.gitignore building minified and unminified versions 1 month ago
.jshintignore support IE11 3 years ago
.jshintrc Fix jshint and code style errors 3 years ago
.travis.yml build only master 4 years ago
MIT-LICENSE.txt year 3 years ago better argon2 docs 1 month ago
package-lock.json Bump js-yaml from 3.6.1 to 3.13.1 1 week ago
package.json generating missing ids while reading files 2 weeks ago generating missing ids while reading files 2 weeks ago

KdbxWeb Build status Coverage Status

KdbxWeb is a high-performance javascript library for reading/writing KeePass v2 databases (kdbx) in node.js or browser.


  • runs in browser or node.js
  • no native addons
  • fast encryption with WebCrypto
  • total ≈150kB with dependencies
  • full support of Kdbx features
  • protected values are stored in memory XOR’ed
  • conflict-free merge support
  • high code coverage

Browser support

  • modern browsers: Chrome, Firefox, Safari, Opera, Edge
  • node.js


Supported formats are Kdbx3 and Kdbx4, current KeePass file format. Old kdb files (for KeePass v1) are out of scope of this library.


Kdbx4 has introduced Argon2, a new hashing function. Due to complex calculations, you have to implement it manually and export to kdbxweb, if you want to support such files. Here’s how:

kdbxweb.CryptoEngine.argon2 = (password, salt,
    memory, iterations, length, parallelism, type, version
) => {
    // your implementation makes hash (Uint32Array, 'length' bytes)
    return Promise.resolve(hash);

You can find implementation example in tests.

It’s not compiled into the library because there’s no universal way to provide a fast implementation, so it’s up to you, to choose the best one.


let credentials = new kdbxweb.Credentials(kdbxweb.ProtectedValue.fromString('demo'), keyFileArrayBuffer);
kdbxweb.Kdbx.load(dataAsArrayBuffer, credentials).then(db => ...);
kdbxweb.Kdbx.loadXml(dataAsString, credentials).then(db => ...);
Saving => ...);
db.saveXml().then(xmlAsString => ...);

You can also pretty-print XML:

db.saveXml(true).then(xmlAsString => ...);
File info

Header object fields
Meta object fields

Changing credentials
kdbxweb.Kdbx.load(data, credentials).then(db => {
    let randomKeyFile = kdbxweb.Credentials.createRandomKeyFile();
let newDb = kdbxweb.Kdbx.create(credentials, 'My new db');
let group = newDb.createGroup(newDb.getDefaultGroup(), 'subgroup');
let entry = newDb.createEntry(group);
    historyRules: true,
    customIcons: true,
    binaries: true

// upgrade the db to latest version (currently KDBX4)

// downgrade to KDBX3

// set KDF to AES

Entries, groups and meta are consistent against merging in any direction with any state.
Due to format limitations, p2p entry history merging and some non-critical fields in meta can produce phantom records or deletions, so correct entry history merging is supported only with one central replica. Items order is not guaranteed but the algorithm tries to preserve it.

let db = await kdbxweb.Kdbx.load(data, credentials); // load local db
// work with db; // save local db
let editStateBeforeSave = db.getLocalEditState(); // save local editing state (serializable to JSON)
db.close(); // close local db
db = kdbxweb.Kdbx.load(data, credentials); // reopen it again
db.setLocalEditState(editStateBeforeSave); // assign edit state obtained before save
// work with db
let remoteDb = await kdbxweb.Kdbx.load(remoteData, credentials); // load remote db
db.merge(remoteDb); // merge remote into local
delete remoteDb; // don't use remoteDb anymore
let saved = await; // save local db
editStateBeforeSave = db.getLocalEditState(); // save local editing state again
let pushedOk = pushToUpstream(saved); { // push db to upstream
if (pushedOk) {
    db.removeLocalEditState(); // clear local editing state
    editStateBeforeSave = null; // and discard it

Group object fields

let defaultGroup = db.getDefaultGroup();
let anotherGroup = db.getGroup(uuid);
let deepGroup = defaultGroup.groups[1].groups[2];
Group creation
let group = db.createGroup(db.getDefaultGroup(), 'New group');
let anotherGroup = db.createGroup(group, 'Subgroup');
Group deletion
Group move
db.move(group, toGroup);
db.move(group, toGroup, atIndex);
Recycle Bin
let recycleBin = db.getGroup(db.meta.recycleBinUuid);
if (!recycleBin) {
Recursive traverse
group.forEach((entry, group) => { /* will be called for each entry or group */ });

Entry object fields
Entry.times fields

let entry = db.getDefaultGroup().entries[0];
entry.fields.AccountNumber = '1234 5678';
entry.fields.Pin = kdbxweb.ProtectedValue.fromString('4321');
Entry creation
let entry = db.createEntry(group);
Entry modification
// push current state to history stack
// change something
entry.fgColor = '#ff0000';
// update entry modification and access time
// remove states from entry history
entry.removeHistory(index, count);

Important: don’t modify history states directly, this will break merge.

Entry deletion
Entry move
db.move(entry, toGroup);

If you’re moving an entry from another file, this is called import:

db.importEntry(entry, toGroup, sourceFile);

Used for passwords and custom fields, stored the value in memory XOR’ed

let value = new kdbxweb.ProtectedValue(xoredByted, saltBytes);
let valueFromString = kdbxweb.ProtectedValue.fromString('str');
let valueFromBinary = kdbxweb.ProtectedValue.fromBinary(data);
let textString = value.getText();
let binaryData = value.getBinary();
let includesSubString = value.includes('foo');
kdbxweb.Kdbx.load(data, credentials).then(...)
    .catch(e => {
        if (e.code === kdbxweb.Consts.ErrorCodes.BadSignature) { /* ... */ }

Consts definition

kdbxweb.Consts.ErrorCodes // all thrown errors have code property
kdbxweb.Consts.Defaults // default db settings
kdbxweb.Consts.Icons // icons map
let randomArray = kdbxweb.Random.getBytes(/* desired length */ 100);


Use npm to build this project:
> npm run build
> npm run build:debug

To run tests:
> npm test

3rd party libs

kdbxweb includes these 3rd party libraries:

See it in action

This library is used in KeeWeb