Problem
KeeForge does not recognize some valid KeePass OTP entries. In particular, the KeeOTP plugin stores TOTP configuration in the custom otp field as a query string instead of an otpauth:// URI:
otp=key=<secret>&type=TOTP&step=30&size=6&encoding=Base32&otpHashMode=SHA1
When this value is opened in KeeForge, no totpConfig is created and the OTP section is not shown.
First implementation slice
This change targets KeeOTP TOTP compatibility:
- custom fields named exactly
otp, OTP, or Otp;
- values beginning with
key=;
- URL-query decoding;
- strict support for the KeeOTP encodings
Base32, Base64, Hex, and UTF8;
- explicit validation of
type=TOTP, step, size, and otpHashMode;
- no decoder fallback or heuristic interpretation;
- preservation of existing OTP source precedence and behavior;
- regression coverage for malformed values, duplicate parameters, encoding boundaries, and lowercase Base32 keys.
HOTP is intentionally deferred to a separate change because it requires a mutable counter, persistence, conflict handling, and one-shot generation semantics.
Compatibility evidence
The KeeOtp2 implementation confirms:
- legacy data is stored in the
otp field;
- supported parameters include
key, type, step, size, encoding, counter, and otpHashMode;
- KeeOtp2 accepts Base32 keys in lowercase;
- HOTP uses a separate
counter lifecycle and is outside this first slice.
Reference: KeeOtp2
Verification
The implementation includes focused XCTest coverage. Local verification is pending because xcodebuild is unavailable on Linux. The repository CI workflow runs on macos-15 with Xcode and can validate the change there.
Follow-up candidates
- HOTP support with persistent
counter / HmacOtp-Counter.
- OTP URIs stored in the standard
URL field.
- Additional URI schemes such as
otp://, after establishing a verified compatibility baseline.
- Raw Base32-only values without explicit KeeOTP query metadata.
Problem
KeeForge does not recognize some valid KeePass OTP entries. In particular, the KeeOTP plugin stores TOTP configuration in the custom
otpfield as a query string instead of anotpauth://URI:When this value is opened in KeeForge, no
totpConfigis created and the OTP section is not shown.First implementation slice
This change targets KeeOTP TOTP compatibility:
otp,OTP, orOtp;key=;Base32,Base64,Hex, andUTF8;type=TOTP,step,size, andotpHashMode;HOTP is intentionally deferred to a separate change because it requires a mutable counter, persistence, conflict handling, and one-shot generation semantics.
Compatibility evidence
The KeeOtp2 implementation confirms:
otpfield;key,type,step,size,encoding,counter, andotpHashMode;counterlifecycle and is outside this first slice.Reference: KeeOtp2
Verification
The implementation includes focused XCTest coverage. Local verification is pending because
xcodebuildis unavailable on Linux. The repository CI workflow runs onmacos-15with Xcode and can validate the change there.Follow-up candidates
counter/HmacOtp-Counter.URLfield.otp://, after establishing a verified compatibility baseline.