Zum Hauptinhalt springen

Getting Started on Windows

This is the Windows counterpart to Getting Started. The integration is identical in concept — Oracle keeps doing bulk table/tablespace encryption locally with AES-NI, and DuoKey is only on the master-key path via PKCS#11 — but three things are genuinely different on Windows and are easy to get wrong in ways that produce confusing, generic Oracle errors with no useful log output. Read this whole page before deploying; each of the three has been verified against a live Oracle Enterprise Edition instance on Windows.

Canonical configuration reference

The authoritative pkcs11.toml schema and every DKE_PKCS11_* override is documented once, in PKCS#11 Provider Configuration (pkcs11.toml).

Prerequisites​

Oracle Database​

  • Oracle Database 19c or 21c Enterprise Edition for Windows (the same version support as Linux — see Getting Started)
  • Oracle Advanced Security option licensed
  • DBA access with SYSDBA and the ADMINISTER KEY MANAGEMENT system privilege

DuoKey​

  • Access to your DuoKey Cockpit v2 web interface
  • The DuoKey PKCS#11 provider library for Windows (dke_pkcs11.dll), supplied by DuoKey
  • Network connectivity from the database server to the Cockpit host over HTTPS (port 443)
Build requirement — static C runtime

dke_pkcs11.dll must be built with a statically-linked C runtime:

RUSTFLAGS="-C target-feature=+crt-static" cargo build --release -p dke-pkcs11

A plain cargo build --release dynamically links VCRUNTIME140.dll / api-ms-win-crt-*.dll and fails to load (Win32 error 126) on any host without the matching Visual C++ Redistributable installed. Verify a given build with dumpbin /DEPENDENTS dke_pkcs11.dll — none of those DLLs should appear in the dependency list. DuoKey-supplied builds already do this; only relevant if you build the library yourself.

System​

  • Windows Server 2016+ or Windows 10/11, with the Oracle software already installed and a database created
  • Local Administrator access to place files and grant permissions

Step 1: Create the Oracle TDE app in Cockpit​

Identical to Linux — see Getting Started, Step 1. When exporting the deployment bundle, select the Windows platform option to get Windows paths and PowerShell install commands instead of Linux ones.

Step 2: Verify connectivity​

From the database server, confirm the Cockpit API host is reachable over HTTPS — not the frontend one. Cockpit v2 typically serves the two on different hostnames (for example cockpit-api-<env>.duokey.cloud for the API vs cockpit-<env>.duokey.cloud for the browser UI):

Invoke-WebRequest -Uri "https://<cockpit-api-host>/api/apps/<app_id>/tde/pkcs11/<access_guid>" -Headers @{ Authorization = "Bearer <access_token>" }

This should return JSON ({"ok":true,"status":"ready",...}). If it returns an HTML page with 200 OK instead, server_url in your pkcs11.toml points at the frontend, not the API — this is a very easy mistake to make and looks like a working connection until Oracle tries to parse the response as JSON and fails.

Step 3: Install the DuoKey PKCS#11 provider — use the fixed system-drive path​

Unlike Linux (/opt/oracle/extapi/..., which lives under ORACLE_BASE), Oracle's HSM library discovery on Windows scans a fixed path rooted at the system drive, independent of where the database software or ORACLE_HOME/ORACLE_BASE actually are:

C:\oracle\extapi\64\hsm\DuoKey\1.0\dke_pkcs11.dll
New-Item -ItemType Directory -Force -Path "C:\oracle\extapi\64\hsm\DuoKey\1.0"
Copy-Item dke_pkcs11.dll "C:\oracle\extapi\64\hsm\DuoKey\1.0\"
Do not deploy under ORACLE_HOME or ORACLE_BASE

Confirmed empirically: a library placed under %ORACLE_HOME%\extapi\... or %ORACLE_BASE%\extapi\... is never loaded by Oracle on Windows, regardless of how ORACLE_BASE is configured for the instance. Only the literal C:\oracle\extapi\... path (or the equivalent path on a non-C: system drive) is scanned. Deploying to the "obvious" per-instance location silently fails with ORA-28353 and no library log at all — because the library is never even found, let alone loaded.

Keep the vendor directory to exactly one file

More than one file under ...\DuoKey\1.0\ (for example, a .dll plus a leftover backup copy) can make Oracle's directory-discovery scan misbehave. Keep it to the single current library file.

Step 4: Place the configuration file — and grant the Oracle service account access​

New-Item -ItemType Directory -Force -Path "C:\oracle\dke"
Copy-Item pkcs11.toml "C:\oracle\dke\pkcs11.toml"
[System.Environment]::SetEnvironmentVariable("DKE_PKCS11_CONF", "C:\oracle\dke\pkcs11.toml", "Machine")
The single most common failure on Windows: file permissions

Oracle on Windows runs as a per-service virtual account — NT SERVICE\OracleService<SID> — which is a distinct security principal from whatever account you used to place these files. Find the exact account for your instance and grant it explicit access:

Get-WmiObject Win32_Service -Filter "Name='OracleService<SID>'" | Select-Object StartName
icacls "C:\oracle\dke" /grant "NT SERVICE\OracleService<SID>:(OI)(CI)(F)"

If you skip this, the library cannot read its own configuration and returns a generic CKR_GENERAL_ERROR from C_Initialize — before its own logger is even set up, so the provider's log file stays completely empty. Oracle surfaces this as ORA-28407/ORA-28353 with nothing useful in the alert log. This looks exactly like "Oracle silently refuses to load the library" and is very easy to spend hours misdiagnosing as an Oracle bug. If you hit a graceful keystore-open failure with an empty provider log, check this first — then check the plain (non-incident) trace file for the failing session under <ORACLE_BASE>\diag\rdbms\<db_unique_name>\<instance>\trace\ for a kzthsminit/C_Initialize/PKCS#11 error code line, which has more detail than the alert log ever will.

A restart of OracleService<SID> after installing multiple Oracle Homes on the same box can also leave stale service-account groups from an older install (ORA_OraDB<n>Home<m>_SVCACCTS) that don't match your current instance — don't assume an existing ACL entry that "looks like an Oracle group" is actually the right one; verify with the Get-WmiObject command above and grant the exact account name it prints.

Step 5: Configure Oracle for HSM-based TDE​

Connect as SYSDBA and run the SQL from the deployment bundle — identical to Linux, only the WALLET_ROOT path differs:

ALTER SYSTEM SET WALLET_ROOT='C:\oracle\admin\<sid>\wallet' SCOPE=SPFILE;
-- Restart to apply WALLET_ROOT
SHUTDOWN IMMEDIATE;
STARTUP;

ALTER SYSTEM SET TDE_CONFIGURATION='KEYSTORE_CONFIGURATION=HSM' SCOPE=BOTH;
Create the wallet directory first

Oracle does not always create the WALLET_ROOT directory for you on Windows. A missing directory produces a wallet-open failure later (ORA-28353) that looks completely unrelated to this step — create it explicitly before restarting:

New-Item -ItemType Directory -Force -Path "C:\oracle\admin\<sid>\wallet"

Then open the keystore and set the master key exactly as on Linux — see Getting Started, Step 5.2–5.3 (the SQL is identical on both platforms).

Step 6: Verify​

Identical to Linux — see Getting Started, Step 6. This has been confirmed end-to-end on Windows: SET KEYSTORE OPEN, SET KEY, CREATE TABLESPACE ... ENCRYPTION, and a real insert/select round trip, with data confirmed inaccessible (ORA-28365) when the keystore is closed.

A known, rare, non-blocking Oracle-side crash​

During validation, SET KEYSTORE OPEN/ALTER SYSTEM SET TDE_CONFIGURATION=... occasionally crashed the instance with ORA-07445 [kzthsminit_discover_load_pkcs_lib] — an internal Oracle access violation via a corrupted register, reproduced independently against this provider's library, a third-party OpenSC module, and a genuine Securosys Primus binary, with no pattern tied to any specific PKCS#11 library. It is non-deterministic — the exact same configuration that crashed once later completed normally — and did not prevent a full successful deployment. If you hit this exact ORA-07445 signature, it is very likely this same rare Oracle-side issue rather than a configuration problem on your end: simply retry the statement. See Troubleshooting for the full incident-trace analysis if you want to confirm the signature matches.

Next steps​

Troubleshooting​

Library never loads, ORA-28353, empty provider log — almost always one of: (1) the library isn't at the fixed C:\oracle\extapi\64\hsm\DuoKey\1.0\ path (see Step 3), or (2) the Oracle service account can't read pkcs11.toml (see Step 4). Check the session's own trace file (not just the alert log) for a kzthsminit/PKCS#11 error code line before assuming an Oracle defect.

Connectivity returns HTML instead of JSON — server_url points at the frontend hostname, not the API one (see Step 2).

ORA-07445 [kzthsminit_discover_load_pkcs_lib] — see "A known, rare, non-blocking Oracle-side crash" above. Retry.

For every other error code and the full Windows investigation notes, see Troubleshooting.

Support​