The following small fixtures were created by Microsoft’s DAO.DBEngine.120 on
2026-10-06, using the x64 COM server ACEDAO.DLL version 16.0.20430.20092.
They contain only synthetic test data: table T, Id = 7, and
Label = "Native encrypted row". Their test password is Native123.
The files are under tests/JetDatabaseWriter.Tests/Databases/Encrypted.
| File | Bytes | SHA-256 | Creation options |
|---|---|---|---|
| NativeJet4Password.mdb | 90112 | BE37E9AB6D80A1A1C2F796F1DD0039DF3516A50342938ECC431F0EE51D815CB8 | dbVersion40 (64), password, no dbEncrypt |
| NativeJet4Rc4.mdb | 90112 | B164F5B845BA9CA342AB85EE50B89831FA612D9E22C2D3DDB968CE08097207BF | dbVersion40 (64) plus dbEncrypt (2), password |
| NativeAceAgile.accdb | 184320 | 2CB842ECF476D360233303FE7148C7964DC47D076A799D1F120587CD7CE47FCA | dbVersion120 (128) plus dbEncrypt (2), password |
The creation locale was ;LANGID=0x0409;CP=1252;COUNTRY=0;pwd=Native123.
This records the installed producer, not a claim that this engine represents
all historical Microsoft providers.
NativeJet4Schema.mdb is the JET4 RC4 fixture above with an additional empty
Added table (Id LONG, primary key), created by the same DAO engine.
SHA-256: F6C3B19F5C73C4D0E8E99A598FE8100489E6A517A7EB682EDAE9AE28F71EA4E7.
DAO reopened both original T and new Added successfully. The fixture
pins native catalog ownership and ACL rows; library-generated schema
compatibility remains subject to the separate DAO regression.
The native schema oracle stores MSysDb.Owner = FA7B. Its Tables container
has an inheritable owner-placeholder SID FB7E with mask 0xF00FE, and an
inheritable Users SID FB7B with mask 0xFFEFF. DAO gives a new table owner
FA7B and those inherited permissions, substituting the real owner for the
placeholder and clearing FInheritable on the new rows. The system container’s
own owner is different and must not be copied as the table owner.
These bytes depend on the file. The library derives the masked 0204 owner
placeholder from the header’s creation-date/password region, takes the actual
owner from MSysDb, and preserves inherited principal bytes and permission
masks. The fixture unmasks Admin to 0301, Users to 0201, and the system
owner to 0203; fixed stored identities from another header are not plaintext
principals.
An independent DAO creation in the Access-authored testV2003.mdb fixture
confirms that an explicit inheritable owner SID takes precedence over the owner
placeholder. Its Tables container holds placeholder E4A6 with mask 0xF00FE and
owner E5A3 with mask 0xFFEFF; DAO emits one owner entry with 0xFFEFF. The masks
are not combined. Distinct stored identities may therefore legitimately
converge when the placeholder is resolved.
The regression pins the fixture’s placeholder and checks that deriving it does not modify page zero. The synthetic custom-owner workgroup oracle below supplies separate native evidence.
The password-only file has a zero unmasked encoding key; encrypted pages use an independent four-byte encoding key. The per-page RC4 key is that encoding key XOR the little-endian page number. The UTF-16 header password is masked by the creation-date value. Raw byte 0x62 was 233 in both native files and is not a standalone password/encryption flag.
Preserving the original key and password permits page updates. Changing the
header password alone was insufficient: native NewPassword also changed
security metadata on pages 17 and 18 in the characterization database.
The native maintenance implementation remasks MSysObjects.Owner and
MSysACEs.SID with the old and new header-derived RC4 keys. The decrypted data
pages match DAO NewPassword output byte for byte. Physical index descriptors
are validated before remasking; indexes containing Owner or SID are rebuilt from
the remasked rows. Synthetic index regressions check leaf keys and row references;
the ordinary and custom-owner fixtures do not establish every workgroup configuration.
NativeJet4PasswordChanged.mdb was produced on 2026-10-08 by DAO120
NewPassword("Native123", "Changed123") from NativeJet4Rc4.mdb.
SHA-256: 7954A11E0827B410BB7036A9DDB60B5538FEC842A789C0809F47985BCC2E2066.
Focused DAO tests authenticate, write and compact encrypted, decrypted and
rekeyed output on both target frameworks.
The native file is a flat Standard ACE DB database, not an Office compound
package. Page 0 contains a 1055-byte version 4.4 descriptor with flags 0x40,
AES-256-CBC, SHA-512 and spin count 100000. The descriptor has no
dataIntegrity element. These are observations of this fixture, not universal
requirements for all valid ACE files.
The page codec unlocks the provider key once, leaves page 0 unchanged, and uses the native encoding key and salt when deriving each data page’s IV. Reader and writer use normal page I/O and ownership. Regression tests cover native fixture reading, original-key mutation, wrong passwords and refusal of a spin budget below 100000 before data pages are read. Native fixture maintenance tests also require free-page scrubbing, actual tail shrink and unchanged page 0. On both target frameworks, DAO120 reads, writes and compacts the native JET4 RC4 and ACE Agile fixtures after this maintenance. Separate write, torn-write and flush fault tests restore the original Agile ciphertext and reuse the writer successfully; these are library rollback checks, not native crash-recovery evidence. Separate library subprocess tests now verify exact ciphertext restoration after process termination through the persistent sidecar protocol; this does not establish Access-native or power-loss recovery. Additional native algorithm fixtures and physical shrink fault coverage are described below.
Native maintenance streams pages into a unique adjacent staging file using
managed .NET APIs. Callers must protect the containing directory from untrusted
access: staged output or original backups can contain plaintext. Windows files
receive a protected owner-only ACL at creation through FileSystemAclExtensions.
The .NET 11 build requests Unix mode 0600; inherited macOS ACL grants are not
suppressed. The .NET Standard build uses host-default Unix creation permissions.
Unix confidentiality therefore depends on the directory permissions and ACLs,
not on FileShare.None, which is advisory there.
Pre-canceled operations stop before creating files. Conversion/cancellation before preparation cleans up only owned incomplete files. A fixed-size deterministic replacement intent binds immutable old/new copies, their exact lengths and hashes, and an append-only process commit decision. A separate publication copy leaves both selected generations available through interruption. Peak space includes up to three additional database-sized files.
Path writer open recovers a valid intent before requiring the destination to exist. Prepared selects old content; a complete valid Committed record selects new content. Surviving immutable copies and canonical content must match recorded old/new generations; an interrupted publication copy may instead be a validated prefix of a complete authorized image. Invalid metadata, conflicting copies, foreign ownership or mixed transaction/replacement evidence refuses. Readers and detection refuse a pending intent. Legacy random candidates have no automatic selection authority. Incomplete intent or recovery-lease acquisition can require conservative refusal even while complete database copies survive.
Both library targets use managed FileStream.Flush(true) and File.Replace/non-overwriting move, with no library P/Invoke, COM or native helper binary. .NET handles OS calls. The net11.0 asset on Windows checks parent-directory flush acknowledgements around preparation, publication and cleanup; standard/Linux/macOS have no directory adapter. Rename, bootstrap and cleanup persistence remain unqualified across physical power loss. Existing Windows destinations use File.Replace metadata semantics. A missing destination is restored under private maintenance-file creation permissions; no separate ACL, alternate-stream or timestamp recovery policy is claimed.
Commit errors identify complete retained copies through IOException.Data["JetDatabaseWriter.ReplacementFile"] and ["JetDatabaseWriter.OriginalFile"]. Recover through AccessWriter.OpenAsync(path) while preserving all intent/generation files. Actual process termination and repeated recovery tests exercise publication, decisions and cleanup; they do not establish physical power-loss durability. Other operations’ temporary files are retained.
Native maintenance holds a coordinated source lease and a generation-bound strict lock receipt where configured. Pending transaction journals are refused before staging; recover through the writer first. New encrypted creation transforms the bounded bootstrap in memory before its first destination write. A JET password-only source stays password-only after a password change; ACE password changes use fresh AES-256-CBC/SHA-512.
The built-in encryption support status covers JET3/JET4 RC4/password protection, ACE RC4 CryptoAPI, Standard/compatibility AES and Agile AES with the algorithms listed in the README. Third-party extensible modules and non-AES Agile ciphers remain unsupported. The Office extensible descriptor identifies an arbitrary module and opaque provider data; it is not a universal key derivation contract. A native ACE specimen and that provider’s implementation contract are required. See MS-OFFCRYPTO extensible encryption.
Workgroup identity preservation is not workgroup-user authentication. Native
engine evidence is specific to the pinned fixtures, not every possible custom
security configuration or every Cartesian product of algorithms. Directory-entry
power-loss durability, native crash semantics for physical shrink,
and complete hostile-input resistance remain separate gaps in PLAN.md
(E1, E2, F3, F6, S1 and I5). Library-generated round trips alone are not native
interoperability oracles.
UpstreamJet3Rc4.mdb is an unmodified 90112-byte fixture pinned to
jackcessencrypt commit 77a1d54db8fc71606f391d94adacae7e34b108ca.
SHA-256: 8939D5F541A69B5A195AAB512D65C88A4A2CA1FBA43D19C78CD3E2F673503AF9.
The adjacent attribution records its source URL and Apache 2.0 license.
Upstream classifies it as Access 97 and verifies Table1 rows
(1, hello, 0) and (2, world, 42) without a password.
The original producing Microsoft host is undocumented; it is an independent
format oracle, not a locally DAO-authored fixture.
Its unmasked encoding key is A7E0C0FE; its password region is empty.
The native per-page RC4 rule decodes it. Raw header byte 0x62 is 0x34,
and its unmasked value is zero; it is not an encryption flag. Library
read/write regressions use this fixture. A compatible x86 DAO.DBEngine.36 host
now verifies password changes, decryption, rekeying, library inserts, native
updates and compact/reopen. The producing DAO360.dll reports version
10.0.26100.5074. DAO120 continues to refuse Access 97 files; DAO36 is required.
| DAO36 fixture | Creation | SHA-256 |
|---|---|---|
| NativeJet3Password.mdb | Upstream fixture followed by NewPassword("", "Native123") |
66B7F57A8480F66548E7AFB71B5081E41B9A523E65FF9BE7FFB7CD90DACD9F04 |
| NativeJet3Rc4.mdb | DAO36 CreateDatabase, options 34, password Native123, then NewPassword to CP1252 password Pássword |
EFEE0E45A1438E68FCF1BAA18859375DB0E9CCE6ADE79585CAD328276092982E |
The first oracle changes only the password region and a page-zero open counter. JET3 passwords are encoded using the native database code page; embedded NUL, unrepresentable text and more than 20 encoded bytes are refused when writing.
These unchanged files are pinned to the same Jackcess Encrypt revision above. The original producing host is undocumented. DAO120 independently reads, writes and compacts each after library page mutation on both target frameworks.
| Fixture | Password | Provider | SHA-256 |
|---|---|---|---|
| Upstream-db2007-oldenc.accdb | Test123 | RC4 CryptoAPI | 174BA7FF6349D4F929ADF555F5035C0722923776662F30A523F2933827D9558E |
| Upstream-db2007-enc.accdb | Test123 | Agile AES-128-CBC/SHA-1 | FA6CD4ED7639DEE40AD288FF6C530356EA050BDE36DBDE5E4328FEE6AA07F306 |
| Upstream-db-nonstandard.accdb | password | Compatibility AES-256/SHA-1, zero iterations | 5E93BAD848E0262EA8952C14DB897D63F8588CA22870043AB7CF954D865B4B39 |
| Upstream-db2013-enc.accdb | 1234 | Agile AES-256-CBC/SHA-512 | 3E9EE219A7CA9BF7DEE261F6455F298887603D41C82EA0C5BC06D8831F09637A |
Native Standard uses AES ECB with a page-specific derived key; its page addressing
differs from Office package encryption. The pinned
Upstream-OfficeStandard.docx and its published plaintext validate AES Standard
primitives independently, and the separate native Standard fixture below validates the flat ACE provider. Attribution, source revision and hashes are in THIRD-PARTY-NOTICES.txt.
The implementation follows MS-OFFCRYPTO.
Agile additionally accepts AES-192, CFB8, SHA-256 and SHA-384, including distinct password and page algorithms. Independent specification vectors cover those combinations; the separately identified Microsoft-compacted fixtures below establish native output evidence. Password hashing checks cancellation within the loop and consumes an aggregate reader/linked-source iteration budget before deriving a key. Descriptor tests refuse duplicate roles, incorrect namespaces and inconsistent algorithm sizes.
These fixtures were emitted on 2026-10-08 by x64 DAO.DBEngine.120,
ACEDAO.DLL version 16.0.20430.20146. Their inputs were synthetic: native
NativeAceAgile.accdb plaintext/schema encrypted with an independently sourced
Standard verifier or an independent deterministic Agile builder. Library DML
was followed by a Microsoft DAO update and CompactDatabase into a new file.
The pinned bytes are those native compact outputs, not the synthetic seeds.
This establishes Microsoft acceptance and native output compatibility, without
claiming that the Access UI created the original provider configuration.
| Fixture | Password | Provider | Bytes | SHA-256 |
|---|---|---|---|---|
| NativeAceStandard.accdb | Password1234_ | Standard AES-128/SHA-1, 50,000 iterations, descriptor 4.2/fAES | 184320 | 349745691382E10D8F5E5946378FAFD2BA20FF33B616082E65742F45B288E1BA |
| NativeAceAgileMixedCbc.accdb | vector | Password AES-192-CBC/SHA-256; pages AES-256-CBC/SHA-384 | 200704 | FB86804BD61188FDE4C684BC538D75E3ECE4FD7998BAC045D371B532B56A313E |
| NativeAceAgileMixedCfb8.accdb | vector | Password AES-128-CFB8/SHA-384; pages AES-192-CFB8/SHA-512 | 200704 | 18D9535FD1C8AD88435669B659397B9BC7099C2E468A505D1DA8275F658A6DD5 |
The mixed Agile fixtures use seven password iterations solely to keep the
synthetic test bootstrap inexpensive; new production encryption still uses
100,000. They contain T rows 7 (“Native encrypted row”) and 8 (“DAO updated”),
and Added row 1. Standard contains T rows 7 (“Native encrypted row”) and
8 (“DAO Standard row”). Native compact retains the requested provider and
algorithms; Standard changes descriptor version 3.2 to 4.2. Ordinary library
updates preserve page zero exactly. The guarded producer regressions verify
native reads, writes and compacted rows; unguarded fixture tests run in CI.
Public password change, decrypt and re-encrypt tests also reopen through DAO.
NativeJet4Workgroup.mdb and NativeJet4WorkgroupChanged.mdb are 77824-byte
DAO36 outputs (DAO360.dll version 10.0.26100.5074) from a synthetic workgroup
user NativeOwner, PID NativeOwnerPID, user password Owner123. Database
passwords are Native123 and Changed123. Only synthetic data and identities
are committed. The bundled NativeJetWorkgroup.mdw is created from scratch by
ADOX with Jet OLEDB:Create System Database=True; it contains only the built-in
admin, Creator, Engine, Admins and Users principals plus NativeOwner.
scripts/create-native-workgroup-encryption-fixtures.ps1 reproduces the corpus
with x86 Windows PowerShell, Microsoft Jet OLE DB and DAO36.
| Fixture | SHA-256 |
|---|---|
| NativeJet4Workgroup.mdb | A84688D1EE0F394C8C1B36AC8996749B662DD8268AB0A099F5DE69B507FC5D10 |
| NativeJet4WorkgroupChanged.mdb | 6FE02A19F4F24F299EF908F40D1A87F3A1952BF375B2F4B144647D98EC29DDFB |
| NativeJetWorkgroup.mdw | D89E1574E8A1F764746244A3D28CD3161EC893790560F4B403E75B0CC36C7F24 |
DAO reports the custom owner before and after NewPassword; the stored owner
identity is longer than the built-in two-byte principals. Library password
maintenance matches every decrypted page of the native password-change oracle.
Indexed Owner/SID tests additionally validate rebuilt entry counts, page ownership and key ordering;
they are synthetic index cases, not a claim that DAO created those indexes.
Physical tail shrink keeps raw before-images of the removed pages and spills them to a temporary undo file above the bounded memory threshold. Secure erase, truncate and flush failures restore the original bytes and length; encrypted ciphertext is restored exactly. Tests cover write refusal, torn writes, erase flush, post-truncate flush and failure before or after truncation for CBC/SHA-256 and CFB8/SHA-384 variants. The writer remains usable after successful undo and is faulted if undo fails. File-backed shrinking additionally persists a page-hash manifest, original raw pages, write intents and its intended retained length before truncation. Writer reopen restores an undecided shrink, including encrypted ciphertext, or retains the hash-validated committed image. This process-crash protocol does not establish power-loss or Access-native recovery.