# CryptKey.bin — independent derivation

**Question.** `CryptKey.bin` is a 144-byte file Analysis Services expects
inside the ABF when `SvrEncryptPwdFlag` is on (the server default). Earlier
builds shipped a fixed 144-byte value copied out of a working PBIX, described
in docs as a "Microsoft RSA key BLOB [that] requires `rskeymgmt` to generate."
Can we produce a valid one ourselves, using no Microsoft key material?

**Method (clean-room, differential observation of lawfully generated files).**
The corpus is 25 `.pbix` files generated by ordinary authorized use of Power
BI Desktop. For each, the `DataModel` was XPress9-decompressed and the ABF's
`0.CryptKey.bin` extracted (read-only). Two analyses:

1. *Cross-file structure.* All 25 keys are 144 bytes. Bytes 0–15 equal bytes
   128–143 in every file — a 16-byte GUID (`5d21bc98-8d2d-4ee6-a8e5-d038aac94441`
   in mixed-endian) bookending the structure. That GUID is **identical across
   all 25 files**, so it is a format constant, not a per-database value (each
   file's database GUID differs). A per-byte variance map shows offsets 0–59
   and 122–143 are byte-identical across the corpus (the "scaffold"), while
   offsets 60–121 (except a constant 0x00 at 84) differ per file (the
   "variable region", 61 bytes).

2. *Acceptance experiment.* Starting from the observed scaffold, the variable
   region was filled four ways and each file was opened in Power BI Desktop
   (March 2026), then queried through the workspace `msmdsrv`:

   | variable region | result |
   |---|---|
   | our `os.urandom(61)`, sample #1 | opens, `EVALUATE` returns data |
   | our `os.urandom(61)`, sample #2 | opens, `EVALUATE` returns data |
   | `sha512("pbix-mcp cryptkey v1")[:61]` (self-authored, deterministic) | opens, `EVALUATE` returns data |
   | all-zero (degenerate) | **rejected** (workspace never loads) |

**Independently derived conclusions.**

- The variable region is **not** a checksum of the model (our single fixed
  value from one file loads unchanged in files with different database GUIDs
  and different data — a content checksum would be rejected), and **not** a
  value Desktop validates against anything file-specific.
- Desktop requires the **scaffold** (a public format constant, observed
  identical across many lawfully generated files) and a **non-degenerate**
  variable region. Our own random or hash-derived bytes satisfy it; all-zero
  does not.
- The earlier "Microsoft RSA key BLOB / requires `rskeymgmt`" description was
  unverified: an actual RSA-key validation would reject arbitrary random
  bytes in the key region, and Desktop accepts them.

**Implementation.** `pbix_mcp/formats/abf_from_scratch.py::build_cryptkey()`
composes the observed scaffold constant with a self-authored SHA-512 keystream
(default seed `b"pbix-mcp cryptkey v1"`; an optional per-file seed varies it as
Microsoft does). It is used by the from-scratch builder
(`builder_v2.CRYPTKEY_BYTES`) and the rebuild path (`abf_rebuild`). No bytes
lifted from a Microsoft file remain in the package. Regression:
`tests/test_cryptkey.py`. Desktop load of a builder-produced file carrying the
generated key: verified (returns the expected measure value).

**Sources.** Lawfully generated PBIX files (ordinary Power BI Desktop use);
black-box observation of Desktop load behavior; our own differential
experiments. No Microsoft source, decompiled code, confidential docs, or
key material were used.
