定制 hankit/keepassphp 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

hankit/keepassphp

Composer 安装命令:

composer require hankit/keepassphp

包简介

Library to parse .kdbx files in PHP

README 文档

README

KeePassPHP is a PHP library for reading and writing KeePass .kdbx databases.

It can:

  • inspect KDBX files without decrypting them
  • open KeePass 2.x databases and map them to PHP objects
  • read groups, entries, passwords, custom fields, and custom icons
  • write new KDBX 4.1 databases from the in-memory Database model
  • work with password keys, key files, and composite keys

It currently supports:

  • KDBX 3.x
  • KDBX 4.0 / 4.1 when the database uses:
    • outer cipher AES-256
    • KDF AES-KDF

It does not currently support:

  • KDBX 4 databases using Argon2d
  • KDBX 4 databases using Argon2id
  • KDBX 4 databases using outer ChaCha20

Requirements

  • PHP >= 8.4
  • ext-hash
  • ext-json
  • ext-openssl
  • ext-sodium
  • ext-xmlreader
  • ext-zlib

Installation

composer require hankit/keepassphp

Quick Start

Open a KeePass database directly:

<?php

use KeePassPHP\Database;
use KeePassPHP\Keys\KeyFromPassword;
use KeePassPHP\Readers\ResourceReader;

$reader = ResourceReader::openFile('/path/to/database.kdbx');
if ($reader === null) {
    throw new RuntimeException('Unable to open database file.');
}

try {
    $database = Database::fromKdbx(
        $reader,
        new KeyFromPassword('secret', 'SHA256'),
    );
} finally {
    $reader->close();
}

echo $database->getName();
echo $database->getPassword('entry-uuid');

Use a key file:

<?php

use KeePassPHP\Database;
use KeePassPHP\Keys\KeyFromFile;
use KeePassPHP\Readers\ResourceReader;

$reader = ResourceReader::openFile('/path/to/database.kdbx');
if ($reader === null) {
    throw new RuntimeException('Unable to open database file.');
}

$keyFileContent = file_get_contents('/path/to/database.keyx');
if ($keyFileContent === false) {
    throw new RuntimeException('Unable to read key file.');
}

try {
    $database = Database::fromKdbx(
        $reader,
        new KeyFromFile($keyFileContent),
    );
} finally {
    $reader->close();
}

Use a composite key:

<?php

use KeePassPHP\Database;
use KeePassPHP\Keys\CompositeKey;
use KeePassPHP\Keys\KeyFromFile;
use KeePassPHP\Keys\KeyFromPassword;
use KeePassPHP\Readers\ResourceReader;

$reader = ResourceReader::openFile('/path/to/database.kdbx');
if ($reader === null) {
    throw new RuntimeException('Unable to open database file.');
}

$keyFileContent = file_get_contents('/path/to/database.keyx');
if ($keyFileContent === false) {
    throw new RuntimeException('Unable to read key file.');
}

$key = new CompositeKey('SHA256');
$key->addKey(new KeyFromPassword('secret', 'SHA256'));
$key->addKey(new KeyFromFile($keyFileContent));

try {
    $database = Database::fromKdbx($reader, $key);
} finally {
    $reader->close();
}

Inspecting A Database

KdbxInspector can read the outer header and tell you what kind of database you are dealing with before you try to decrypt it.

<?php

use KeePassPHP\KdbxInspector;

$metadata = KdbxInspector::inspectFile('/path/to/database.kdbx');

var_dump([
    'format' => $metadata->formatLabel,
    'cipher' => $metadata->cipherName,
    'kdf' => $metadata->kdfName,
    'compressed' => $metadata->isCompressed,
    'decryptable_here' => $metadata->isDecryptableByCurrentLibrary,
]);

For KDBX 3.x this also reports the inner random stream. For KDBX 4.x it reports the outer header information that is available without decrypting the payload.

Reading Data

The Database model gives you access to the parsed tree:

<?php

foreach ($database->getGroups() as $group) {
    // Traverse groups and entries from here.
}

$password = $database->getPassword('entry-uuid');
$username = $database->getStringField('entry-uuid', 'UserName');
$customFields = $database->listCustomFields('entry-uuid');

You can also serialize the parsed database to arrays:

<?php

$data = $database->toArray();

Creating Databases

New databases are created by building a Database object graph in memory and then writing it as KDBX 4.1.

At a minimum you usually:

  1. create a Database
  2. create one or more Group objects
  3. create Entry objects and attach them to groups
  4. write the database with Database::toKdbx4()

Example:

<?php

use KeePassPHP\Database;
use KeePassPHP\Entry;
use KeePassPHP\Group;
use KeePassPHP\Keys\KeyFromPassword;
use KeePassPHP\Strings\UnprotectedString;

$database = new Database();
$database->setName('Company Vault');

$root = new Group();
$root->uuid = base64_encode(random_bytes(16));
$root->name = 'Root';

$servers = new Group();
$servers->uuid = base64_encode(random_bytes(16));
$servers->name = 'Servers';

$entry = new Entry();
$entry->uuid = base64_encode(random_bytes(16));
$entry->tags = 'production;linux';
$entry->setStringField(Database::KEY_TITLE, new UnprotectedString('Web 01'));
$entry->setStringField(Database::KEY_USERNAME, new UnprotectedString('deploy'));
$entry->setStringField(Database::KEY_URL, new UnprotectedString('ssh://web-01.internal'));
$entry->setStringField('Environment', new UnprotectedString('production'));
$entry->setPassword(new UnprotectedString('secret-password'));

$servers->addEntry($entry);
$root->addGroup($servers);
$database->addGroup($root);

$payload = $database->toKdbx4(
    new KeyFromPassword('master-password', 'SHA256'),
);

Useful model methods:

  • Database::setName() sets the database name shown in KeePass
  • Database::addGroup() adds a top-level group
  • Database::setCustomIcon() registers a custom icon by UUID
  • Group::addGroup() adds a child group
  • Group::addEntry() adds an entry
  • Entry::setPassword() sets the password field
  • Entry::setStringField() sets standard or custom string fields
  • Entry::addHistoryEntry() adds a history item

Notes:

  • uuid, customIcon, and related UUID fields are expected to be base64-encoded 16-byte values, matching the KeePass XML format
  • if you do not set a UUID on a group or entry, the writer will generate a deterministic UUID from the current value or a random UUID if the field is empty
  • password values are written as protected values in KDBX 4 output
  • non-password string fields are written as plain string values unless you pass a protected boxed string yourself

You can control KDBX 4 writing with Kdbx4WriteOptions:

<?php

use KeePassPHP\Kdbx4WriteOptions;

$payload = $database->toKdbx4(
    new KeyFromPassword('master-password', 'SHA256'),
    new Kdbx4WriteOptions(
        rounds: 10000,
        compress: true,
    ),
);

Encryption Support

The low-level KdbxFile entrypoint can decrypt both supported KDBX 3 and KDBX 4 files and dispatches to the correct implementation automatically.

Creating encrypted files in the old KDBX 3 format is available through KdbxFile::forEncryption():

<?php

use KeePassPHP\KdbxFile;
use KeePassPHP\Keys\KeyFromPassword;

$file = KdbxFile::forEncryption(6000);
$payload = $file->encrypt('<KeePassFile />', new KeyFromPassword('secret', 'SHA256'));

Creating KDBX 4.1 databases is available through the Database model:

<?php

use KeePassPHP\Database;
use KeePassPHP\Entry;
use KeePassPHP\Group;
use KeePassPHP\Kdbx4WriteOptions;
use KeePassPHP\Keys\KeyFromPassword;
use KeePassPHP\Strings\UnprotectedString;

$database = new Database();
$database->setName('Generated Database');

$root = new Group();
$root->name = 'Root';

$entry = new Entry();
$entry->setStringField(Database::KEY_TITLE, new UnprotectedString('Example'));
$entry->setStringField(Database::KEY_USERNAME, new UnprotectedString('alice'));
$entry->setPassword(new UnprotectedString('secret-password'));

$root->addEntry($entry);
$database->addGroup($root);

$payload = $database->toKdbx4(
    new KeyFromPassword('master-password', 'SHA256'),
    new Kdbx4WriteOptions(),
);

Supported Formats

KDBX 3.x

Supported for reading and decryption.

Supported for low-level encryption through KdbxFile::forEncryption().

KDBX 4.0 / 4.1

Supported for reading and decryption when the outer header uses:

  • cipher AES-256
  • KDF AES-KDF

Inner protected values are supported for the current KDBX 4 read path, including KeePass files that use ChaCha20 as the inner random stream.

Supported for writing in KDBX 4.1 with:

  • outer cipher AES-256
  • KDF AES-KDF
  • inner random stream Salsa20 by default

Limitations

  • KDBX 4 with Argon2d throws an exception during decryption
  • KDBX 4 with Argon2id throws an exception during decryption
  • KDBX 4 with outer ChaCha20 throws an exception during decryption
  • KDBX 4 writing currently targets 4.1 with AES-KDF and outer AES-256 only
  • database name and other XML metadata are only available after successful decryption

Error Handling

The modernized API throws exceptions for invalid input, unsupported formats, and decryption failures.

The main exception type is:

  • KeePassPHP\Exceptions\KeePassPHPException

Development

composer test
composer stan
composer cs:check
composer cs:fix
composer check

There is also an opt-in local playground for manually testing real databases:

cp playground/keepass-databases.php.dist playground/keepass-databases.php
# edit playground/keepass-databases.php
composer test:playground

Breaking Changes

Recent API and behavior changes are documented in BREAKING_CHANGES.md.

License

MIT

hankit/keepassphp 适用场景与选型建议

hankit/keepassphp 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 612 次下载、GitHub Stars 达 1, 最近一次更新时间为 2021 年 02 月 19 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「password manager」 「keepass」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 hankit/keepassphp 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 hankit/keepassphp 我们能提供哪些服务?
定制开发 / 二次开发

基于 hankit/keepassphp 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 612
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 0
  • Forks: 23
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2021-02-19