FubarDev.Lexware.Passwords
0.5.2
Prefix Reserved
dotnet add package FubarDev.Lexware.Passwords --version 0.5.2
NuGet\Install-Package FubarDev.Lexware.Passwords -Version 0.5.2
<PackageReference Include="FubarDev.Lexware.Passwords" Version="0.5.2" />
<PackageVersion Include="FubarDev.Lexware.Passwords" Version="0.5.2" />
<PackageReference Include="FubarDev.Lexware.Passwords" />
paket add FubarDev.Lexware.Passwords --version 0.5.2
#r "nuget: FubarDev.Lexware.Passwords, 0.5.2"
#:package FubarDev.Lexware.Passwords@0.5.2
#addin nuget:?package=FubarDev.Lexware.Passwords&version=0.5.2
#tool nuget:?package=FubarDev.Lexware.Passwords&version=0.5.2
FubarDev.Lexware.Passwords
A cross-platform .NET library for encrypting and decrypting Lexware passwords.
Overview
Lexware products store user passwords in several encrypted formats that have evolved over time. This library provides a unified API to encrypt and decrypt these stored password values across all known schemes:
- Legacy / V0: DES-CBC encryption, stored as lowercase hex ASCII bytes, no version prefix. V0 is the formalized variant of the legacy scheme and is fully equivalent to it.
- V1:
'1'prefix + AES-192-ECB with minimal escape encoding - V2:
'2'prefix + AES-192-ECB with escape encoding and cyclic XOR - V3:
'3'prefix + AES-192-ECB with random-byte interleaving (non-deterministic) - V4:
'4'prefix + AES-192-ECB with full escape encoding - V5:
'5'prefix + Base64 wrapper around the V4-style AES payload (current Lexware default)
The library also supports double encryption (used for migration scenarios) and provides a date-based service password generator (PasswordForToday).
Features
- Encrypt and decrypt passwords for all Lexware encryption schemes (Legacy, V0--V5)
- Auto-detect the encryption scheme during decryption via a multiplexer
- Interface-based design with a static factory for easy consumption
- Built-in DES key presets for all known Lexware versions (
DesKeyV1,DesKeyV2) - Version-aware DES key and write-scheme resolution via
LexwareVersionResolver - Optional double encryption support for migration scenarios
- Date-based service password generation
- Thread-safe, cross-platform, Native AOT and trimming compatible
- No external runtime dependencies beyond the .NET Base Class Library
- Optional delegation to the original
LxEncrDecr.dll(requires a valid, locally installed Lexware license)
CLI Tool
A standalone command-line tool is available separately for ad-hoc encryption and decryption without writing any code. The tool is published to the Codeberg package registry.
First, add the Codeberg package source (requires a Codeberg account and access token):
dotnet nuget add source --name fubar-dev \
https://codeberg.org/api/packages/fubar-dev/nuget/index.json
Then install the tool:
dotnet tool install -g lx-password --add-source fubar-dev
lx-password decrypt <db-value>
lx-password decrypt --decode-hex <hex-encoded-db-value>
lx-password analyze <db-value>
lx-password encrypt "MyPassword"
lx-password encrypt --des-key "2c2u" "MyPassword"
lx-password encrypt-des "MyPassword"
lx-password decrypt-des <hex-ciphertext>
lx-password decrypt-from-file <path>
lx-password encrypt-to-file "MyPassword"
lx-password decrypt-pin <pin>
lx-password decrypt-superuser-password <instance-id>
lx-password info
Target Framework
- .NET 10 / C# 14
Installation
dotnet add package FubarDev.Lexware.Passwords
Or via the NuGet Package Manager in Visual Studio by searching for FubarDev.Lexware.Passwords.
Usage
All types live in the FubarDev.Lexware.Passwords namespace. The main entry
point is the static LxCryptoApi class.
The API is structured in two layers:
ILxCryptoApi— pure AES engine; exposesMaxAlgorithmVersion,AesEncrypt, andAesDecrypt.ILxPasswordApi— extendsILxCryptoApiwith a configured DES key and the version-keyed encryptor factory. Obtain one via.WithDesKey()or.ForLexware().
Choose the right DES key
Lexware uses different DES keys depending on the installation's version and database backend:
| Lexware version | Database | Key constant |
|---|---|---|
| < 26.0 (e.g. 2021) | SQL Anywhere | DesEncryption.DesKeyV1 |
| ≥ 26.0 (e.g. 2026) | SQL Anywhere | DesEncryption.DesKeyV1 |
| ≥ 26.0 (e.g. 2026) | PostgreSQL | DesEncryption.DesKeyV2 |
Use ForLexware to resolve the key automatically from a LexwareVersionOptions:
using FubarDev.Lexware.Passwords;
// Lexware 2026 with PostgreSQL → DesKeyV2
ILxPasswordApi api = LxCryptoApi.Managed.ForLexware(
LexwareVersionOptions.ForPostgreSql(new Version(26, 0)));
// Lexware 2026 with SQL Anywhere → DesKeyV1
ILxPasswordApi api = LxCryptoApi.Managed.ForLexware(
LexwareVersionOptions.ForSqlAnywhere(new Version(26, 0)));
// Lexware 2021 with SQL Anywhere → DesKeyV1
ILxPasswordApi api = LxCryptoApi.Managed.ForLexware(
LexwareVersionOptions.ForSqlAnywhere(new Version(21, 0)));
Or supply the key directly if you already know it:
using FubarDev.Lexware.Passwords;
ILxPasswordApi api = LxCryptoApi.Managed.WithDesKey(DesEncryption.DesKeyV1);
Use LexwareVersionResolver when you also need the write scheme version — for example
to encrypt a password for direct SQL comparison, exactly as Lexware itself does:
using FubarDev.Lexware.Passwords;
var options = LexwareVersionOptions.ForPostgreSql(new Version(26, 0));
if (LexwareVersionResolver.Default.TryResolve(options, out var profile))
{
ILxPasswordApi api = LxCryptoApi.Managed.WithDesKey(profile.DesKey, profile.LatestAlgorithmVersion);
// Encrypt with the scheme Lexware uses for this installation
byte[] stored = api[-1].Encrypt("MyPassword");
// → Use stored as a parameter in a WHERE clause for password validation
}
To support a future Lexware version not yet covered by the built-in rules, replace the default resolver at application startup:
using FubarDev.Lexware.Passwords;
LexwareVersionResolver.Default = new LexwareVersionResolver(
[
new(new Version(27, 0), LexwareDatabaseSystem.PostgreSql, myNewDesKey, writeSchemeVersion: 6),
.. LexwareVersionResolver.BuiltInRules,
]);
Decrypt a stored password (auto-detect scheme)
The most common use case: read a raw stored value from the database and decrypt it without knowing the scheme in advance.
using FubarDev.Lexware.Passwords;
ILxPasswordApi api = LxCryptoApi.Managed.ForLexware(
LexwareVersionOptions.ForPostgreSql(new Version(26, 0)));
// Works for Legacy DES (V0), V1, V2, V3, V4, and V5.
// Automatically falls back through all known DES keys if the configured key fails.
string plaintext = api.DecryptAny(storedBytes);
Decrypt a corrupted stored password
Some Lexware databases contain values that were corrupted by a codepage
mismatch during import or migration. DecryptAnyCorrupted tries all
known corruption variants and returns the first successfully decrypted
plaintext.
using FubarDev.Lexware.Passwords;
ILxPasswordApi api = LxCryptoApi.Managed.ForLexware(
LexwareVersionOptions.ForPostgreSql(new Version(26, 0)));
// Tries all known corruption variants to recover the plaintext.
string plaintext = api.DecryptAnyCorrupted(storedBytes);
If you want to branch explicitly before decrypting:
using FubarDev.Lexware.Passwords;
ILxPasswordApi api = LxCryptoApi.Managed.ForLexware(
LexwareVersionOptions.ForPostgreSql(new Version(26, 0)));
string plaintext = LxCodepageCorruption.MightBeCorrupted(storedBytes)
? api.DecryptAnyCorrupted(storedBytes)
: api.DecryptAny(storedBytes);
To reproduce the corruption (e.g. for tests or tooling):
using FubarDev.Lexware.Passwords;
byte[] corrupted = LxCodepageCorruption.CorruptEncoding(aesEncryptedBytes);
Encrypt a password using the installation's default scheme
using FubarDev.Lexware.Passwords;
var options = LexwareVersionOptions.ForPostgreSql(new Version(26, 0));
LexwareVersionResolver.Default.TryResolve(options, out var profile);
ILxPasswordApi api = LxCryptoApi.Managed.WithDesKey(profile!.DesKey, profile.LatestAlgorithmVersion);
byte[] stored = api[-1].Encrypt("MyPassword");
// Lexware 2026 / PostgreSQL → V5; Lexware 2021 / SQL Anywhere → V4
Round-trip for a specific scheme version
using FubarDev.Lexware.Passwords;
ILxPasswordApi api = LxCryptoApi.Managed.ForLexware(
LexwareVersionOptions.ForPostgreSql(new Version(26, 0)));
ILxPasswordEncryptor encryptor = api[4];
byte[] stored = encryptor.Encrypt("MyPassword");
string plaintext = encryptor.Decrypt(stored);
Use the original Lexware DLL (optional, Windows x86 only)
The Native implementation delegates to LxEncrDecr.dll from a local
Lexware installation and falls back to the managed implementation
automatically when the DLL is unavailable or the process is not x86.
using FubarDev.Lexware.Passwords;
ILxPasswordApi api = LxCryptoApi.Native.ForLexware(
LexwareVersionOptions.ForPostgreSql(new Version(26, 0)));
// Transparent fallback: uses LxEncrDecr.dll if available, managed otherwise.
// Note: V2 always uses the managed fallback regardless of DLL availability.
string plaintext = api.DecryptAny(storedBytes);
If you need an explicit guard before using native mode:
using FubarDev.Lexware.Passwords;
ILxCryptoApi cryptoApi = LxCryptoApi.IsNativeSupported
? LxCryptoApi.Native
: LxCryptoApi.Managed;
ILxPasswordApi api = cryptoApi.ForLexware(
LexwareVersionOptions.ForPostgreSql(new Version(26, 0)));
string plaintext = api.DecryptAny(storedBytes);
For direct native access without any managed fallback, use NativeDirect
— but only after confirming IsNativeSupported:
using FubarDev.Lexware.Passwords;
if (LxCryptoApi.IsNativeSupported)
{
ILxPasswordApi api = LxCryptoApi.NativeDirect.ForLexware(
LexwareVersionOptions.ForPostgreSql(new Version(26, 0)));
string plaintext = api.DecryptAny(storedBytes);
}
Requirements for native mode:
- Windows operating system
- x86 (32-bit) process
LxEncrDecr.dllresolvable at runtime from your local Lexware installationThe
LxEncrDecr.dllis not included in this package and is not redistributed. It is loaded at runtime from the locally installed, licensed Lexware application.
Low-level DES operations
For direct access to the legacy DES layer:
using FubarDev.Lexware.Passwords;
// Encrypt
byte[] cipherBytes = DesEncryption.EncryptCbc(DesEncryption.PasswordEncoding.GetBytes("MyPassword"), DesEncryption.DesKeyV1);
string hexCiphertext = Convert.ToHexStringLower(cipherBytes);
// Decrypt
byte[] raw = Convert.FromHexString(hexCiphertext);
Span<byte> plainBytes = DesEncryption.DecryptCbc(raw, DesEncryption.DesKeyV1);
string plaintext = DesEncryption.PasswordEncoding.GetString(plainBytes);
Date-based service password
using FubarDev.Lexware.Passwords;
string todayPassword = PasswordForToday.Generate(); // uses today's date
string specificDay = PasswordForToday.Generate(new DateOnly(2026, 3, 14)); // specific date
Purpose and Intended Use
This library was developed exclusively to enable third-party applications to interoperate with locally installed, licensed Lexware Financial Office installations.
Lexware Financial Office does not provide a machine-readable data export for all data categories. Where only human-readable reports are available, programmatic access to the underlying database is the only viable approach. This library allows such third-party applications to authenticate using the same credentials already established in Lexware, rather than relying on known default credentials or other publicly documented access paths.
This library is intended solely for use by licensed Lexware users who wish to access their own data from their own licensed installation.
Legal Notice
Interoperability
The algorithms implemented in this library were obtained by means of reverse engineering for the sole purpose of achieving interoperability with Lexware Financial Office, as expressly permitted under § 69e UrhG (German Copyright Act) and § 3 GeschGehG (German Trade Secrets Act). The necessity of this approach was established by the absence of any machine-readable data export covering the required data categories.
Contractual clauses that purport to prohibit reverse engineering for interoperability purposes are void by operation of law under § 69g Abs. 2 UrhG.
Scope of Use
This library is provided for interoperability purposes only. It is intended exclusively for use with licensed Lexware installations by the respective licensee to access their own data. Any use that exceeds this scope — in particular unauthorized access to third-party systems — is not a supported or intended use case and is the sole responsibility of the user.
No Redistribution of Lexware Components
This library does not include, embed, or redistribute any component,
binary, or asset owned by Lexware or Haufe Group. The optional
LxEncrDecr.dll integration requires the user to provide the path to a DLL
from their own licensed Lexware installation.
Liability Disclaimer
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Use of this library is at your own risk. The authors assume no liability for any consequences arising from use outside the intended interoperability scope described above.
Security Note
The encryption schemes documented and implemented in this library reflect security design decisions made by Lexware / Haufe Group. The authors of this library make no representation regarding the security of these schemes and expressly note that reversible password storage does not conform to current security best practices (e.g., NIST SP 800-63B, BSI TR-02102). Users should be aware of the inherent limitations of the underlying Lexware security architecture.
License
Copyright (c) 2026 Fubar Development Junker
This project is licensed under the MIT License.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on FubarDev.Lexware.Passwords:
| Package | Downloads |
|---|---|
|
FubarDev.Lexware.Database.Abstractions
NHibernate abstractions and credential generation for Lexware database access. |
GitHub repositories
This package is not used by any popular GitHub repositories.