C++17 library for importing and exporting KeePass password databases.
This project is a fork of libkeepass by Christian Kindahl.
The API documentation is available at https://dkruempe.github.io/libkeepass/.
- Formats: KDB (Legacy) and KDBX (KeePass2)
- Unified API: One
KeePassclass with format auto-detection and in-memory stream support - Ciphers: AES, Twofish, ChaCha20
- KDFs: AES-KDF, Argon2d, Argon2id
- Keys: Password, Keyfile, Composite Keys
- Platforms: Linux, macOS, Windows
- C++17 compatible compiler (GCC 10+, Clang 12+, MSVC 19.20+)
- CMake >= 3.16
- Conan package manager
- OpenSSL
- zlib
- pugixml
- Argon2
- Google Test (for unit tests)
# Install dependencies
conan install . --output-folder=build --build=missing
# Configure CMake (Release)
cmake -B build -DCMAKE_TOOLCHAIN_FILE=build/Release/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
# Build
cmake --build build --config Releasecd build
ctest --output-on-failureThe public API is documented with Doxygen. To generate the HTML documentation locally:
# If Doxygen is installed, the 'doc' CMake target builds it
cmake --build build --target docAlternatively, run Doxygen directly:
doxygen Doxyfile # output goes to docs/htmlA hosted version of the documentation is auto-generated and published to GitHub Pages on every push to main.
After building (see Build), install the library and its CMake package to a prefix:
cmake --install build --prefix /usr/localThis installs the shared library, the public headers and a CMake package configuration, so consumers can use find_package(libkeepass).
cmake_minimum_required(VERSION 3.16)
project(my_app LANGUAGES CXX)
# Point CMake at the install prefix (only needed for non-standard prefixes)
list(APPEND CMAKE_PREFIX_PATH "/usr/local")
find_package(libkeepass REQUIRED)
add_executable(my_app main.cc)
target_link_libraries(my_app PRIVATE kruempelmann::libkeepass)The imported target kruempelmann::libkeepass provides all required include paths and link dependencies (OpenSSL, zlib, pugixml, Argon2) transitively, so most consumers only need the find_package call.
Alternatively, add this repository as a submodule and include it directly in your build tree. The target kruempelmann::libkeepass is available for both find_package and add_subdirectory style integration:
git submodule add https://github.com/dkruempe/libkeepass.git third_party/libkeepassadd_subdirectory(third_party/libkeepass/src)
add_executable(my_app main.cc)
target_link_libraries(my_app PRIVATE kruempelmann::libkeepass)Note:
add_subdirectoryrequires the same dependencies (OpenSSL, zlib, pugixml, Argon2) to be resolvable in your build tree, e.g. via Conan, as described under Prerequisites.
The KDB and KDBX codecs are optional (LIBKEEPASS_COMPONENT_KDB,
LIBKEEPASS_COMPONENT_KDBX). The installed package reports
libkeepass_<component>_FOUND and provides
kruempelmann::libkeepass::model/kdb/kdbx/capi interface targets:
find_package(libkeepass REQUIRED COMPONENTS kdbx)
target_link_libraries(my_app PRIVATE kruempelmann::libkeepass::kdbx)The repository ships a Conan 2 recipe (conanfile.py) that builds and packages the library. To create the package from the current sources:
conan create . --build=missingThe version is read from CMakeLists.txt such that conan create always matches the current release. To build a specific variant pass -o libkeepass/*:shared=True for a shared library (static is the default).
Consumers declare the package in their conanfile.txt / conanfile.py:
[requires]
libkeepass/0.2.0
and use it from CMake as before:
find_package(libkeepass CONFIG REQUIRED)
target_link_libraries(my_app PRIVATE kruempelmann::libkeepass)An in-tree vcpkg port is available under
ports/libkeepass/, and an optional Homebrew formula is in
Formula/libkeepass.rb:
vcpkg install libkeepass --overlay-ports=portsCPack generates installable packages from the install rules. After building the project, run:
cmake --build build --target packageThe generated packages are written to the build directory:
TGZandZIParchives on all platformsDEBandRPMpackages on Linux
To produce Linux packages for a specific target distribution, set the base install prefix accordingly:
cmake -B build -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
cmake --build build --target packageNote: The DEB/RPM dependency lists (
libssl3,zlib1g,libpugixml1.12,libargon2-1/openssl-libs,zlib,libpugixml,argon2-libs) are defaults and may need adjusting for your target distribution. Override them as needed, e.g.-DCPACK_DEBIAN_PACKAGE_DEPENDS="...".
Release assets are signed keylessly with Sigstore. Verify an artifact with:
cosign verify-blob \
--certificate artifact.pem \
--signature artifact.sig \
--certificate-identity-regexp 'https://github.com/dkruempe/libkeepass/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
artifactwasm/ contains an Emscripten build of the C ABI and a client-side-only demo
page. Decryption happens in the browser tab; no database bytes leave the
machine. See wasm/README.md for the dependency/toolchain
notes.
The kpx binary (in cli/) is a full command line tool built on top of the library and serves as a complete usage example:
kpx --help
# Print all entries as text (default), JSON or CSV
kpx -p password database.kdbx
kpx -p password -f json database.kdbx
kpx -p password -f csv --with-passwords database.kdbx
# Search and filter the output
kpx -p password --search alice database.kdbx
kpx -p password --search "^mail" --regex database.kdbx
kpx -p password --group Internet database.kdbx
# Generate a random password (default length 16, max 256)
kpx --generate
kpx --generate 32
# Create a database, change its credentials, and inspect its group tree
kpx -p password create database.kdbx
kpx -p password --new-password "$NEW_SECRET" passwd database.kdbx
kpx -p password groups database.kdbx
# Move an entry (or a group with --group) to another group
kpx -p password --search alice --to Archive move database.kdbx
# Merge another database (same master password/keyfile) into this one
kpx -p password --from old-backup.kdbx merge database.kdbx
# Edit the database in place
kpx -p password add --title "New" --user alice --pass secret --group Internet database.kdbx
kpx -p password update --search alice --notes "changed" database.kdbx
kpx -p password rm --title "Obsolete" database.kdbx
# Export to a new KeePass file (.kdb / .kdbx)
kpx -p password -e output.kdbx database.kdb
# Audit the password quality and reuse of all entries (or of one subtree)
kpx -p password --audit database.kdbx
kpx -p password --audit --group Internet database.kdbx
kpx -p password --audit -f json --with-passwords database.kdbx
# Show stored TOTP seeds, or generate the current codes
kpx -p password otp database.kdbx
kpx -p password --code otp database.kdbx
# Trim history to the newest N versions instead of clearing it
kpx -p password --all --keep 10 purge database.kdbx
# Keep the password out of argv and the environment
printf '%s\n' "$SECRET" | kpx --password-stdin database.kdbx
kpx --password-file /run/secrets/keepass database.kdbx
# Passwords can also come from an environment variable or an interactive prompt
KEEPASS_PASSWORD=secret kpx database.kdbxThe password is read from --password, --password-file <path> (or - for
stdin), --password-stdin, KEEPASS_PASSWORD, or an interactive prompt (POSIX
terminals and Windows consoles). --password and KEEPASS_PASSWORD are
convenient but expose the secret through the process list or environment; use
the file/stdin variants for scripts and services. Keyfiles are supported via
--keyfile <path> and can also be passed as bytes through
Key::FromBytes/Key::FromStream. Exit codes are stable per category (0
success, 1 command/usage error, 3 wrong password/key, 4 corrupt or
unsupported database, 5 I/O or missing file); with --format json errors are
printed as {"error":{"category":...,"message":...}}. See
docs/cli-output.md for the output schemas and
kpx --help for the full option and command reference.
The KeePass class is the single entry point for opening and saving databases.
The input format is auto-detected; the output format is derived from the file
extension and the database KDF/cipher, or can be forced explicitly:
#include "libkeepass/keepass.hh"
// Open with a password (and optionally a keyfile).
keepass::KeePass keeper("password", "/path/to/keyfile.key");
std::unique_ptr<keepass::Database> db = keeper.Open("database.kdbx");
// Manipulate the database...
auto root = db->root();
for (const auto& entry : root->Entries()) {
std::cout << entry->path() << std::endl;
}
// Save back.
keeper.Save("output.kdbx", *db);
// Save encrypted with a different password.
keeper.SaveAs("output.kdbx", *db, "new_password");
// Force the output format.
keeper.SetFormat(keepass::KeePass::Format::kKdb); // kKdb, kKdbx3, kKdbx4Both Open and Save work with in-memory streams:
std::ostringstream out;
keeper.Save(out, *db);
std::istringstream in(out.str());
std::unique_ptr<keepass::Database> reopened = keeper.Open(in);Create brand-new databases with generated cryptographic material:
auto db = keepass::KeePass::Create(
"password", keepass::KeePass::Format::kKdbx4,
keepass::Database::Cipher::kAes, keepass::Database::Kdf::kArgon2id);Database, Group and Entry provide helpers for common operations:
// Database-level lookups (case-insensitive substring, or regex).
for (const auto& entry : db->FindEntries("github"))
std::cout << entry->path() << std::endl;
auto group = db->FindGroup("Work");
auto entry = db->FindEntry("Home Banking");
// Build and modify the hierarchy.
auto new_entry = Database::NewEntry("A New Login");
Database::AddEntry(group, new_entry);
Database::MoveEntry(new_entry, other_group);
db->DeleteEntry(new_entry->uuid());
// Move groups, entries or a whole subtree into the recycle bin.
db->EnableRecycleBin(true);
db->TrashEntry(entry);
db->EmptyRecycleBin();
// Serialize the whole database to JSON or traverse it with a visitor.
std::string json = db->ToJson();
class CountingVisitor : public keepass::Visitor {
void Visit(keepass::Group&) override { ++groups_; }
void Visit(keepass::Entry&) override { ++entries_; }
std::size_t groups_ = 0, entries_ = 0;
};
CountingVisitor visitor;
db->Visit(visitor);libkeepass-c is a stable C surface for FFI consumers
(capi/include/libkeepass-c.h). It exposes opaque handles, open/save,
JSON/CSV export, entry lookup and simple editing:
#include <libkeepass-c.h>
kp_keepass* kp = kp_keepass_create("password", NULL);
kp_database* db = NULL;
if (kp_keepass_open(kp, "database.kdbx", &db) == KP_STATUS_OK) {
char* json = NULL;
kp_database_to_json(db, 0, &json);
puts(json);
kp_free_string(json);
}
kp_database_destroy(db);
kp_keepass_destroy(kp);The wrapper is built by default; disable it with
-DLIBKEEPASS_BUILD_C_API=OFF. Errors use the categories from the C++ API and
are also available through kp_last_error().
The format-specific classes remain available for low-level access:
KDBX (KeePass2):
#include "libkeepass/kdbx.hh"
#include "libkeepass/key.hh"
keepass::Key key("password");
keepass::KdbxFile file;
std::unique_ptr<keepass::Database> db = file.Import("database.kdbx", key);
file.Export("output.kdbx", *db, key);KDB (Legacy):
#include "libkeepass/kdb.hh"
#include "libkeepass/key.hh"
keepass::Key key("password");
std::unique_ptr<keepass::Database> db = keepass::KdbFile::Import("database.kdb", key);
keepass::KdbFile::Export("output.kdb", *db, key);The Database class provides access to:
root()- Root group of the databasecipher()/set_cipher()- Encryption algorithmkdf()/set_kdf()- Key Derivation Functioncompress()/set_compress()- XML compression
auto root = db->root();
// Add a new group
auto group = Database::NewGroup("My Group");
Database::AddGroup(root, group);
// Add a new entry
auto entry = Database::NewEntry("My Entry");
entry->set_username(keepass::protect<std::string>("user", true));
entry->set_password(keepass::protect<std::string>("secret", true));
entry->set_url(keepass::protect<std::string>("https://example.com", false));
Database::AddEntry(group, entry);Parent links are maintained automatically, so group->path(), entry->path()
and parent() are available throughout the tree.
libkeepass/
├── src/ # Library source code
│ ├── include/libkeepass/ # Public headers
│ ├── keepass.cc # Unified KeePass API
│ ├── kdb.cc # KDB format implementation
│ ├── kdbx_import.cc # KDBX format implementation
│ ├── kdbx_export.cc # KDBX format implementation
│ ├── database.cc # Database convenience API
│ ├── entry.cc # Entry convenience API
│ ├── group.cc # Group convenience API
│ ├── key.cc # Key management
│ ├── visitor.cc # Visitor pattern
│ ├── cipher.cc # Encryption
│ └── ...
├── test/ # Unit tests
├── cli/ # kpx command line tool
├── cmake/ # CMake configuration
└── .github/workflows/ # CI/CD
GitHub Actions automatically builds and tests on the following platforms:
- Ubuntu (GCC)
- macOS (Clang)
- Windows (MSVC)
Each platform is tested in both Debug and Release configurations. Additionally, dedicated workflows enforce clang-format formatting and clang-tidy static analysis on every push and pull request, and run CodeQL (including the security-and-quality query suite) plus a nightly security scan on the C++ code base.
libkeepass stores secret material (keys, entry passwords, protected strings) in wiped, best-effort locked memory:
secure_zeroscrubs buffers through a volatile write so the compiler cannot elide the wipe.secure_alloc/secure_freeusemlock/VirtualLock(best effort) and always zero the allocation before freeing it.SecureBuffer<N>is a move-only, automatically zeroized buffer used for keys and derived key material.secure_stringholds strings without SSO in wiped, locked memory and is used for all secret entry fields.- Transient transformed keys, HMAC keys, master keys and inner random stream keys are zeroized immediately after their last use in both import and export.
Wiping is deterministic, but locking is best effort: systems that restrict
mlock/VirtualLock (or where it fails) allow pages to be swapped out.
For supported versions and how to report a vulnerability, please see SECURITY.md.
Contributions are welcome! Please see CONTRIBUTING.md for build instructions, the code style guide, and the pull request process.
This project is based on libkeepass by Christian Kindahl.
Copyright (C) 2014 Christian Kindahl Copyright (C) 2024 Dominik Kruempelmann
Licensed under the GNU General Public License v3.0.