57 min read

DPAPI and DPAPI-NG: The Credential Vault Under Everything

A 25-year tour of Windows Data Protection API: the four-stage classic chain, the 2012 DPAPI-NG redesign, the KDS root key, and the five structural ceilings the design cannot close.

Permalink

1. A Thumb Drive, a Profile Directory, and Three Mimikatz Commands

A DFIR analyst slides a stolen laptop's drive into a write-blocker. The volume mounts because BitLocker's recovery key was already in the corporate KMS. Six files in C:\Users\alice\AppData\Roaming\Microsoft\Protect\S-1-5-21-... -- five GUIDs and a Preferred pointer -- are the only thing standing between the analyst and a decade of Alice's saved Windows secrets.

Three Mimikatz commands later (dpapi::masterkey /in:&lt;GUID&gt; /sid:S-1-5-21-... /password:<known>, then dpapi::cred /in:<credfile> /masterkey:<unwrapped>, then dpapi::chrome /in:"Login Data") the analyst has Alice's saved RDP password to the production jump host, her Microsoft 365 session cookie, the home WiFi PSK, the KeePass "Windows User Account" master password, and the EFS keys for her protected documents (each item is itemised with primary citations in §5's eleven-row credential-vault inventory). No kernel exploit. No live login. Just one (account-password, SID) pair recovered offline from last week's NTDS.dit backup.

The trick that makes that scene possible is older than most working engineers. It shipped in Windows 2000 GA on February 17, 2000, it has been the same shape for 25 years, and its single-secret design assumption has been public and tractable since February 3, 2010. The trick has a name: the Data Protection API, or DPAPI.

This article walks the API end-to-end at the level of detail an academic survey would, but with the working-engineer's framing the topic deserves. We open the four-stage classic-DPAPI chain at the SHA-1-of-NT-hash-into-PBKDF2-with-the-SID-as-UTF-16LE-salt level. We open the 2012 DPAPI-NG redesign and the Microsoft Key Distribution Service's L0/L1/L2 derivation chain at the same level of precision.

We name the four production consumers that ride the new chain in 2026: gMSAs, dMSAs, Windows Hello for Business software-KSP credentials, and Credential Guard's isolated-secret persistence. We name the five structural ceilings the 2022 Golden gMSA, 2024 Chromium app-bound encryption, and 2025 Golden dMSA disclosures all admit out loud. And we close with what a 2026 practitioner -- developer, defender, red-teamer, platform engineer -- actually does with all of it.

A note on adjacent topics: the companion Credential Guard article in this series covers the LSAISO trustlet's isolation boundary; the companion VBS Trustlets article covers the trustlet model itself; the TPM in Windows article covers TPM-bound key storage providers; the BitLocker on Windows article covers full-volume encryption; the NTLMless article covers Kerberoasting and Golden Ticket disambiguation. Where we touch those topics, we touch them briefly and refer out -- the goal here is to make DPAPI's chain legible from CryptProtectData all the way to the four-phase GoldenDMSA pipeline.

If you can read those six files in Alice's Protect directory and you have her password's SHA-1 hash, you have everything Windows ever encrypted for her. The next eleven sections explain why -- and why the 2012 redesign that was supposed to fix it produced a new ceiling that, by 2022, turned out to be even harder to live with.

2. Why Windows 2000 Needed a Credential Vault: Generation 0 and Generation 1

Three years before DPAPI shipped, an attacker with a logged-in user's session could read every Internet Explorer auto-complete password, every Outlook Express account password, every saved-FTP credential, and every dial-up RAS phonebook entry on the machine -- without breaking any cryptography. The late-1990s reversing tradition (the original pwdump, L0phtCrack, Cain & Abel's "Protected Storage PassView," the ad-hoc Outlook Express and IE 4 form-fill stealers documented across Bugtraq and ntbugtraq mailing lists at the time) defeated all of it uniformly. The "encryption" applications used was honoured by the OS, faithfully, for the attacker's process as for the legitimate one -- because there was no system primitive that distinguished one from the other. Each application baked its own key into the binary; every reverser who pulled the binary apart pulled the key out with it.

Data Protection API (DPAPI)

The system-provided per-user and per-machine secret-storage primitive that ships in every Windows release from Windows 2000 onward. The classic API surface is two flat-C functions -- CryptProtectData and CryptUnprotectData -- that take a plaintext, an optional caller entropy parameter, and return a self-contained opaque BLOB. The cryptographic chain inside those two functions is rooted at the user's login password and is what every "encrypted" Windows secret of the next 25 years sits on top of.

If the attacker is the user's session, what does "encrypt this for the user" even mean? That is the question every Generation 0 design dodged and every modern credential-vault design has to answer head-on. The 1990s answer (XOR-with-a-baked-in-key) and Microsoft's first attempt at a real system primitive (Protected Storage / PStore) both missed the same point in different ways.

Generation 1: Protected Storage

Protected Storage shipped with Internet Explorer 4 and stayed in the OS until Microsoft formally deprecated it. The pstore.dll item taxonomy is a four-tuple (Key, Type, Subtype, Name) -- a folder hierarchy of named secret entries. The API was the first system-level secret store on Windows that any application could use without writing its own key derivation; the conceptual contribution survived even after the implementation was abandoned.

PStore had two ideas the post-Vista world kept and one it dropped. The two it kept: secrets live in a system primitive, not in each application; secrets are addressed by name, not by raw key handle. The one it dropped: an Authenticode access-rule clause that would have bound a stored item to the signing identity of the application that created it. No application ever used the access-rule clause in production. Microsoft's developer notes are blunt about how the story ended: "Pstore uses an older implementation of data protection. Developers are strongly encouraged to take advantage of the stronger data protection provided by the CryptProtectData and CryptUnprotectData functions"; PStore is "only available for read-only operations in Windows Server 2008 and Windows Vista, but may be unavailable in subsequent versions."

The PStore code-identity-pinning idea (Authenticode access rules) was abandoned in 2000 and re-invented twenty-six years later by Chromium 2024 app-bound encryption, which we will reach in §10.3.

What survived into DPAPI

The Generation 2 design that shipped with Windows 2000 in February 2000 made four moves at once. It kept the two PStore ideas worth keeping ("system-level, not per-application" and "secret addressed by structured name"). It dropped the unused Authenticode access-rule clause. It pushed the cryptographic chain down to a key derived directly from the user's login password. And it added a domain-recovery sidecar (the BackupKey Remote Protocol, which we open in §5) so managed enterprises would adopt it.

The canonical first public design document -- NAI Labs / Network Associates' "Windows Data Protection" whitepaper, MSDN ms995355, October 2001 -- is unambiguous about the layering: "DPAPI initially generates a strong key called a MasterKey, which is protected by the user's password. DPAPI uses a standard cryptographic process called Password-Based Key Derivation, described in PKCS #5, to generate a key from the password." And: "DPAPI is a password-based data protection service. It requires a password to provide protection."

Some secondary sources attribute a "Microsoft Windows Data Protection API" whitepaper to Niels Ferguson at niels.ferguson.com/research/dpapi.html. That URL has been TCP-unreachable for years, has zero Wayback captures across four candidate variants, and the Wikipedia Niels Ferguson article lists no DPAPI publication for him -- his named Microsoft paper is the 2006 BitLocker / Elephant-diffuser paper, not anything DPAPI-related. The verifiable Microsoft-blessed first design document is the NAI Labs ms995355 whitepaper.

The two-function flat-C API Microsoft shipped with Windows 2000 in February 2000 is what every Windows secret of the next 25 years has been encrypted with. The four-stage chain it hides behind those two function names is what we open up next.

3. The Four-Stage Chain: How CryptProtectData Actually Encrypts

A CryptProtectData call goes in with a plaintext buffer and an optional entropy parameter; out comes a self-contained opaque BLOB whose header adds roughly 100-150 bytes to the plaintext (the exact size depends on the algorithm choice and the master-key GUID encoding; the field-by-field BLOB layout is documented in the Bursztein-Picod 2010 paper and parsed by the Mimikatz dpapi::blob module). There is no pszProvider argument, no hKey, no algorithm choice exposed to the caller. Behind those two parameters is a four-stage cryptographic chain that has been the same shape for a quarter-century. Each stage takes the previous stage's output and one new input; the only secret in the entire chain that an offline attacker has to guess is the user's password.

Ctrl + scroll to zoom
The four-stage classic-DPAPI chain: pre-key, master key, session key, BLOB wrap.

Stage 1: Pre-key derivation

The pre-key is a function of three values. The user-account password (or its NT-hash equivalent, supplied by LSASS to the local DPAPI provider) is hashed with SHA-1; the SHA-1 result is fed into PBKDF2 as the input keying material; the user's security identifier (SID) UTF-16LE-encoded is the salt; and a Windows-version-dependent iteration count completes the call. The output is a fixed-width pre-key that Stage 2 will use to wrap the master key.

The chain has changed parameters across Windows versions but has kept the four-stage shape since 2000. The Passcape master-key analysis table records the migration verbatim:

Windows versionSymmetric cipherHMACPBKDF2 iterations
Windows 2000RC4SHA-11
Windows XP3DESSHA-14 000
Windows Vista3DESSHA-124 000
Windows 7AES-256SHA-5125 600
Windows 10 / 11AES-256SHA-5128 000

The shift from PBKDF2-HMAC-SHA1 / 3DES (Windows 2000 -- Vista) to PBKDF2-HMAC-SHA512 / AES-256 (Windows 7 onward) happened at Windows 7, not Windows 10; Bursztein and Picod's 2010 USENIX WOOT paper documented the SHA-1 / 3DES / 4 000-iteration era because their study predated Windows 7's release.

Stage 2: The master key

The master key is a 64-byte cryptographically random secret; one is generated per user, on first use of DPAPI, and a fresh one is generated every 90 days by default. Master keys live as files inside %APPDATA%\Microsoft\Protect\&lt;SID&gt;\&lt;GUID&gt;, where the GUID is the master-key identifier embedded in every BLOB that uses it. The file is divided into four slots: a header (with the iteration count and algorithm IDs), the user-master-key blob (encrypted under the Stage 1 pre-key with AES-CBC), the local-encryption-key or CREDHIST GUID, and the domain-backup-key blob (encrypted to the DC's backup public key, see §5).

Master key (DPAPI)

A 64-byte random secret per user, persisted as a file under %APPDATA%\Microsoft\Protect\&lt;SID&gt;\&lt;GUID&gt;, encrypted under a pre-key derived from the user's password and SID. Every DPAPI BLOB the user ever creates is wrapped under a session key derived from one of these master keys. Master keys rotate every 90 days by default per the NAI Labs design document and the Passcape master-key analysis, but old master keys remain on disk so old BLOBs can still be decrypted.

Stage 3: The per-call session key

For every call to CryptProtectData, DPAPI generates a fresh per-blob salt, computes an HMAC of the master key with the salt and the optional caller entropy, and uses that HMAC as the session key for the actual symmetric encryption. The session key is never stored; it is derivable from (master key, salt, entropy) at unwrap time per the Bursztein-Picod 2010 paper §3.3 and the Mimikatz dpapi::blob parser. The salt is in the BLOB header; the entropy, if any, must be supplied by the caller at unwrap time.

Stage 4: The BLOB wrap

The output BLOB is a self-describing structure with a fixed header. The provider GUID {df9d8cd0-1501-11d1-8c7a-00c04fc297eb} identifies it as a classic-DPAPI blob; the master-key GUID names the master key under which it was wrapped; an algCrypt algorithm identifier records which symmetric cipher was used (0x6603 for CALG_3DES on legacy builds, 0x6610 for CALG_AES_256 on later builds); the salt, ciphertext, and HMAC fill the rest. The Mimikatz dpapi module wiki documents the verbatim field layout that every offline DPAPI tool parses to this day.

algCrypt and the BLOB provider GUID

The algCrypt field in the DPAPI BLOB header is a CryptoAPI algorithm identifier from wincrypt.h: 0x6603 is CALG_3DES (the historical default, encoded as ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_3DES); 0x6610 is CALG_AES_256 (used on Windows 7 and later, encoded as ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_256). The provider GUID {df9d8cd0-1501-11d1-8c7a-00c04fc297eb} is the magic constant that marks every classic-DPAPI BLOB and is the same value the Mimikatz dpapi::blob module and the Bursztein-Picod 2010 paper §3.3.1 print when they parse one.

Python Stage 1 PBKDF2 pre-key derivation (synthetic inputs)
import hashlib

# Synthetic inputs (not real credentials)
nt_hash_hex = "8846f7eaee8fb117ad06bdd830b7586c"  # MD4("password") -- example only
sid_text    = "S-1-5-21-1234567890-1234567890-1234567890-1001"
iterations  = 8000  # Windows 10/11 default per Passcape table

# Stage 1: SHA-1 of the NT hash, then PBKDF2-HMAC-SHA512 with the SID as UTF-16LE salt
nt_hash       = bytes.fromhex(nt_hash_hex)
sha1_of_nt    = hashlib.sha1(nt_hash).digest()
salt_utf16le  = sid_text.encode("utf-16le")

pre_key = hashlib.pbkdf2_hmac(
  "sha512", sha1_of_nt, salt_utf16le, iterations, dklen=64
)

print("Pre-key:", pre_key.hex())
# This pre-key is what Stage 2 (AES-CBC wrap of the master key) consumes.

Press Run to execute.

The chain is honest about its single secret. The pre-key is a function of (NT hash, SID, iteration count). The first two are public to the OS at every login; the iteration count is in the master-key file. The only thing the offline attacker needs to guess is the password. Bursztein and Picod published the algorithm that proved it -- and that is the next section.

4. The 2010 Disclosure: Bursztein, Picod, and Why DPAPI's Strength Is Exactly the User's Password's Strength

On Wednesday, February 3, 2010, in Washington DC, two researchers released a slide deck titled Decrypting DPAPI data and an open-source Python toolkit named DPAPIck. The talk was Black Hat DC 2010 -- not Black Hat USA, which is held in Las Vegas in late July; the actual venue is on Bursztein's elie.net talk page tagged "Black Hat DC - 2010" and the slide-deck cover page is dated "Wednesday, February 3, 2010." They did not break a cryptographic primitive. They published the algorithm.

The two-author record is verifiable from four independent primary sources. The USENIX WOOT 10 page for Recovering Windows Secrets and EFS Certificates Offline lists exactly two authors via its <meta name="citation_author"> tags: "Elie Burzstein" and "Jean Michel Picod." The author's own BibTeX page lists the same two: "author = {Bursztein, Elie and Picod, Jean-Michel}, booktitle = {Workshop On Offensive Technologies}, year = {2010}, organization = {Usenix}." The slide-deck PDF cover reads "Jean-Michel Picod, Elie Bursztein; EADS, Stanford University." And the Wikipedia Data Protection API article cites the paper as "published in 2011 by Bursztein et al." with the same two-author byline. The "Aussel" attribution that circulates in some secondary sources for this paper does not appear in any of the canonical records.

The "Bursztein, Picod & Aussel" three-author attribution is widespread enough on the secondary web that it is worth saying once, plainly, with citations: it is wrong. Two authors, no third name. The same secondary chain often misremembers the venue as Black Hat USA 2010; the verifiable record is Black Hat DC 2010, February 3, 2010, Washington DC.

What the contribution actually was

What Bursztein and Picod published was a complete public algorithm description for offline DPAPI master-key recovery, plus a tool that exercised it. The talk page is verbatim about the tool: "We will demonstrate and release DPAPick (...) which we believe, is the first tool that allows to decrypt offline data encrypted with DPAPI." The paper itself ran six pages and documented the PBKDF2 chain, the master-key file layout, the CREDHIST chain, and the offline EFS-certificate recovery path that follows from holding the master key.

Passcape's prior art -- the DPAPI Black Box paper from 2003 and the 2005 commercial Outlook Password Recovery product -- predated the academic disclosure by seven years. Passcape's own write-up is verbatim: "For the first time, DPAPI was analyzed by Passcape Software in 2003. In 2005, the company released the first commercial application (Outlook Password Recovery) based on that recovery, which could decrypt DPAPI blobs offline, i.e. without logging on to owner's account." The academic community treats Bursztein-Picod 2010 as the canonical reference rather than Passcape 2003 because of three differences: peer review, an open-source tool, and acceptance into a USENIX workshop.

What it did not do

The 2010 disclosure did not weaken DPAPI's cryptography. The cryptography was already sound; the master-key chain was already what it had been since 2000. What the disclosure made operationally true is that any attacker with the master-key file plus the user's password (or NT hash) could now decrypt every BLOB. This had been the design intent since the Windows 2000 release. The chain was never stronger than the password.

The 2010 Bursztein-Picod disclosure did not make DPAPI weaker. It made the strength of DPAPI legible: as strong as the user's password is, no more, no less.

The 2014-2018 toolchain wave

From Bursztein-Picod the operational chain progressed through three distinct waves. The first was Mimikatz's dpapi::* module family, pushed by Benjamin Delpy when the GitHub repository went public on April 6, 2014; the GitHub API record preserves the timestamp to the second ("created_at":"2014-04-06T18:30:02Z"). Mimikatz's DPAPI wiki page enumerates the twelve sub-modules that emerged from this work: blob, protect, masterkey, credhist, cache, capi, cng, cred, vault, wifi, wwan, chrome. Each one is a parser for a different artefact in the credential vault inventory we open in §5.

The second wave was Will Schroeder's SharpDPAPI, a C# port of the Mimikatz DPAPI logic that survived the mimikatz.exe-by-name AV blocks of the 2017-2018 era. Its triage, masterkeys, credentials, vaults, rdg, keepass, certificates, machinemasterkeys, machinecredentials, machinevaults, machinetriage, backupkey, blob, search, and SCCM commands form the operational vocabulary every red team uses today. Schroeder's companion harmj0y blog documents the four scenarios the toolchain has to handle: "user-with-password," "user-without-password-but-with-NT-hash," "offline disk image," and "domain backup-key path."

The third wave was the conference-talk corridor that closed the public-documentation gap: Bartosz Inglot at OPCDE Dubai 2017 with The Blackbox of DPAPI: the gift that keeps on giving (a 40-page deck out of Mandiant's incident-response practice), and Jean-Christophe Delaunay at UniverShell 2017 with the first open-source DPAPI master-key brute-forcer.

The first public Mimikatz release was actually May 2011 as a closed-source binary; the open-source GitHub repository on April 6, 2014 is the history-of-Windows-security marker that downstream tools cite. Delpy's own framing, recorded by Wired: "Because you don't want to fix it, I'll show it to the world to make people aware of it."

The 2010 paper closed the file on classic-DPAPI's secrecy. By 2014 every operator had Mimikatz dpapi::*; by 2018 every operator had SharpDPAPI. The next question was no longer "how does it work" but "what is in the vault, and which sidecars rescue or expose it after a password change."

5. What Lives in the Vault, the [MS-BKRP] Sidecar, and the CREDHIST Cliff

When you save a WiFi network's pre-shared key, that PSK is wrapped in a DPAPI BLOB. When Outlook caches your Exchange account password, that password is wrapped in a DPAPI BLOB. When Chrome stores a cookie, the per-cookie AES-GCM key is wrapped under a DPAPI-protected state-key BLOB. EFS's per-file encryption keys are wrapped by per-user RSA private keys that are themselves wrapped by DPAPI. Twenty-five years of "encrypted" Windows secrets all walk the same four-stage chain.

The credential-vault inventory

Schroeder's operational guide is the most-cited inventory: "At a high level, for the user scenario, a user's password is used to derive a user-specific 'master key'. These keys are located at C:\Users\<USER>\AppData\Roaming\Microsoft\Protect\<SID>\<GUID>"; the operational scope he names is "Chrome Cookies/Login Data, the Windows Credential Manager/Vault (e.g. saved IE/Edge logins and file share/RDP passwords), and Remote Desktop". Walking outward from the master-key directory:

File-system or store pathWhat lives thereWho can decrypt
%APPDATA%\Microsoft\Protect\&lt;SID&gt;\&lt;GUID&gt;The user's master keys (one per 90-day period)Any process holding the user's password / NT hash
%APPDATA%\Microsoft\Protect\CREDHISTSHA-1 chain of previous passwordsAny holder of the current password walks the chain backward
%APPDATA%\Microsoft\Credentials\ (and %LOCALAPPDATA%\...)Credential Manager generic / domain credentialsAny process running as the user
%LOCALAPPDATA%\Microsoft\Vault\Windows Vault items (web credentials, app credentials)Same
%LOCALAPPDATA%\Google\Chrome\User Data\<profile>\Cookies, Login DataDPAPI-wrapped state key wraps per-row AES-256-GCM keysSame (until July 2024 app-bound encryption)
EFS per-file FEKsWrapped by user RSA private key, itself DPAPI-protectedSame
WiFi profile EAP / PSK secretsDPAPI-protected per-system or per-userSYSTEM or the profile owner
Outlook PST / OST account passwordsDPAPI-protectedSame
RDP saved credentialsCredential Manager generic credential, DPAPI-wrappedSame
KeePass Windows User Account key optionComposite key includes a DPAPI-protected blobSame
LSASS (in-memory)Cached DPAPI_SYSTEM secret used by SYSTEM-context unprotectAny code running in or able to dump lsass.exe

For the offline path, the Mimikatz DPAPI wiki documents the full set of unwrap inputs the operator can supply: "masterkey via SID + (password SHA1 OR previous SHA1 from CREDHIST OR NTLM hash OR domain backup key OR DPAPI_SYSTEM secret)." Five paths to the same place.

The two sidecars that rescue and expose

Two sidecars exist because the master-key chain has two recovery problems. The first is the enterprise problem: an admin needs to be able to recover a user's secrets when the user forgets the password. The second is the user problem: a user needs to keep their secrets across self-initiated password changes.

[MS-BKRP] BackupKey Remote Protocol

The LSASS-hosted RPC interface (UUID {3dde7c30-165d-11d1-ab8f-00805f14db40} over \PIPE\protected_storage, per the [MS-BKRP] specification PDF §1.9 Standards Assignments) that lets a member computer hand its master key to a domain controller for RSA-public-key wrap. On first creation of any user master key in a domain-joined environment, the master key is encrypted both under the user's password-derived pre-key and to the DC's RSA backup public key, then both wraps are stored in the master-key file. The RSA-backup wrap is the recoverability path for password resets; it is also the universal-decryption primitive any Domain Admin can use against any user in the forest. See the [MS-BKRP] landing page (revision 27.0, April 2024).

CREDHIST

The previous-password hash chain stored in %APPDATA%\Microsoft\Protect\CREDHIST. One entry per self-initiated password change; SHA-1 hashes of every previous password; chained backwards so that a master key wrapped under password P_n-1 can be re-derived after a self-initiated change to P_n. Self-initiated change appends; administrative reset and Microsoft Account online reset break the chain irrecoverably for any master key that depended on a pre-reset password.

Ctrl + scroll to zoom
The [MS-BKRP] BackupKey flow: first-creation dual-wrap so any DA holding the DC RSA private key can recover any user master key.

The Microsoft Learn DPAPI backup-keys page is verbatim explicit about the lifecycle ceiling: "There currently is no officially supported way of changing or rotating these DPAPI backup keys on the domain controllers... Should the DPAPI Backup keys for the domain be compromised, the recommendation is to create a new domain and migrate users to that new domain." Burn-the-forest-and-rebuild is the documented remediation.

Classic DPAPI's two sidecars -- [MS-BKRP] for the enterprise, CREDHIST for the user -- save secrets that would otherwise be lost on a password change. The [MS-BKRP] sidecar is also, structurally, the universal-decryption primitive any Domain Admin can use against any user in the forest. Microsoft documents both halves of that trade-off plainly. The 2012 redesign tried to escape it -- and gave us a new universal-decryption primitive in exchange.

6. DPAPI-NG: From "User on Machine" to "Whoever Satisfies the Descriptor"

With Windows 8 / Server 2012 (RTM August 1, 2012), Microsoft did not patch classic DPAPI. They added a parallel API. NCryptProtectSecret takes a protection descriptor like "SID=S-1-5-21-...XYZ AND SID=S-1-5-21-...ABC" or "CERTIFICATE=HashID:abc123..." instead of an implicit (user, machine) binding. The blob it returns is self-describing; any device that can satisfy the descriptor can decrypt without out-of-band knowledge.

The CNG DPAPI overview page is verbatim about the design intent: "This new API, called DPAPI-NG, enables you to securely share secrets (keys, passwords, key material) and messages by protecting them to a set of principals that can be used to remove protection from them on different computers after proper authentication and authorization." The two halves of that sentence -- "set of principals," "different computers" -- are exactly the two things classic DPAPI cannot do.

The descriptor grammar

The protection-descriptors page is the verbatim source for the grammar. "the left side of the equals sign (=) must be SID, SDDL, LOCAL, WEBCREDENTIALS, or CERTIFICATE." Five descriptor keywords; three logical authorisation classes; a small set of well-shaped rule strings.

Descriptor keywordAuthorisation classExample rule string
SIDActive Directory groupSID=S-1-5-21-4392301 AND SID=S-1-5-21-3101812
SDDLAD security descriptorSDDL=O:BAG:BAD:(A;;CCDC;;;BA)
LOCALPer-user / per-machine localLOCAL=user, LOCAL=machine
WEBCREDENTIALSCredential brokerWEBCREDENTIALS=MyPasswordName
CERTIFICATECertificate storeCERTIFICATE=HashID:sha1_of_cert, CERTIFICATE=CertBlob:base64String
Protection descriptor (DPAPI-NG)

A short ABNF-defined string that names the set of principals permitted to remove protection from a DPAPI-NG-protected blob. The descriptor is self-describing -- it travels with the blob -- and is parsed at unwrap time to select a protection provider and resolve the wrapping key. Five keywords (SID, SDDL, LOCAL, WEBCREDENTIALS, CERTIFICATE) cover three authorisation classes (AD-forest principal, web credential, certificate store).

Provider selection: the descriptor is the contract; the provider is the implementation

The descriptor type drives provider selection. Microsoft's protection-providers reference is verbatim: "The Microsoft Key Protection provider is chosen for rule strings that begin with SID, SDDL, and LOCAL. The Microsoft Client Key Protection provider parses rule strings that begin with WEBCREDENTIALS."

So SID=, SDDL=, and LOCAL= route to the Microsoft Key Protection Provider, which talks to the local Microsoft Key Distribution Service (kdssvc.dll). This is the path we open in §7 because it is what made gMSAs, dMSAs, Hello for Business software-KSP, and Credential Guard's persistence story possible. CERTIFICATE= selects the certificate's Key Storage Provider, which can be TPM-backed if the certificate's private key lives in a TPM-bound KSP (the TPM in Windows article in this series covers the TPM-bound case in detail). WEBCREDENTIALS= selects the Microsoft Client Key Protection Provider, which resolves through the Windows credential broker.

Ctrl + scroll to zoom
DPAPI-NG: descriptor parses to provider, provider derives wrapping key, blob emitted self-describing.

The output blob is self-describing per the protected-data-format reference: descriptor, provider info, key identifier, ciphertext, HMAC. Any device with a CNG implementation that can satisfy the descriptor decrypts. There is no out-of-band key shipping. There is no "encrypt the blob and ship the key separately." The descriptor is the key-distribution policy.

DPAPI-NG separates who can decrypt (the descriptor) from where the key material lives (the provider). The descriptor is the contract; the provider is the implementation. This is the structural innovation that lets a blob protected on one machine be decrypted on another without any application-layer key-management code.

The CNG DPAPI overview page lists only two principal classes -- AD group and web credentials -- whereas the protection-descriptors page enumerates three (adding the certificate-store class). Both are correct: the certificate descriptor maps to a different provider, hence the two-principal framing on the higher-level overview page and the three-keyword framing on the descriptors-grammar page.

The LOCAL=user and CERTIFICATE= cases are interesting but mostly variations on themes that classic DPAPI or the Windows certificate store could already do. The case that required Microsoft to ship a new DC-side daemon -- the case that turned DPAPI-NG into the substrate for gMSAs, dMSAs, Hello for Business, and Credential Guard's persistence layer -- is the SID= AD-group descriptor. The next section opens its substrate: the Microsoft Key Distribution Service and the [MS-GKDI] protocol.

7. The Microsoft Key Distribution Service: How [MS-GKDI] Computes the Same Group Key on Every DC Without Talking to Any of Them

Imagine a forest with seven writable domain controllers. A laptop in Singapore protects a DPAPI-NG blob with SID=S-1-5-21-...XYZ (some AD group). Three months later, a phone in Seoul -- a member of the same group, on a different DC -- needs to decrypt it. Neither DC has ever heard of the blob. Both DCs derive exactly the same group key and hand it to the requesting member. No inter-DC synchronisation. No key-distribution code in either application. The mechanism is one forest-wide root key plus a deterministic key-derivation function.

Microsoft Key Distribution Service (kdssvc.dll)

The DC-side daemon that ships in every writable domain controller from Windows Server 2012 onward. Implements the [MS-GKDI] Group Key Distribution Protocol (current revision class 10.0, April 2024) and is the substrate for every DPAPI-NG SID= blob, every gMSA password, every dMSA password, and the TPM-less software-KSP path of Windows Hello for Business. The service has one job: given a (group, time-period) request from a member computer, derive and return the per-(group, period) key from a single forest-wide root key.

Provisioning the root key

Every forest needs exactly one KDS root key before any DPAPI-NG SID= consumer can use it. The PowerShell cmdlet Add-KdsRootKey is the provisioning entry point. The Microsoft Learn page is verbatim about the constraints: "The Add-KdsRootKey cmdlet generates a new root key for the Microsoft Group Key Distribution Service (KdsSvc) within Active Directory... It is required to run this only once per forest." The default EffectiveTime is "10 days after the current date" to allow Active Directory replication to converge across all writable DCs before any consumer tries to derive against the new key.

The Add-KdsRootKey -EffectiveTime ((Get-Date).AddHours(-10)) override is for single-DC test forests only. Production forests should let the 10-day default replicate; using the back-dated override means the first consumer to call into the KDS may target a DC that has not yet received the new root key from replication.

The root key lives at CN=Master Root Keys,CN=Group Key Distribution Service,CN=Services,CN=Configuration,<forest-DN> and carries four attributes that downstream offensive-research tools enumerate: msKds-RootKeyData (the actual key bytes), msKds-KDFAlgorithmID (the KDF identifier, currently SP800-108 HMAC-SHA512), msKds-KDFParam (the KDF parameter block), and msKds-PrivateKeyLength. These four attributes, together, are everything a deterministic-KDF derivation needs to recompute every group key the forest will ever produce.

KDS root key

The single forest-wide secret that anchors every per-(group, period) key the Microsoft Key Distribution Service will ever derive, for every DPAPI-NG SID= blob, every gMSA, every dMSA, every Hello-for-Business software-KSP container, and every Credential-Guard isolated-secret persistence wrap. Provisioned with Add-KdsRootKey, exactly once per forest. Stored as four attributes (msKds-RootKeyData, msKds-KDFAlgorithmID, msKds-KDFParam, msKds-PrivateKeyLength) under CN=Master Root Keys,CN=Group Key Distribution Service,CN=Services,CN=Configuration,<forest-DN>. Currently, Microsoft documents no rotation procedure; see §9.3.

The L0 / L1 / L2 derivation chain

The [MS-GKDI] specification (current revision class 10.0, April 23 2024) describes the protocol. Internally, the KDS computes a three-level derivation:

  • L0 seed key: derived from the root key and a label that includes the period-in-hours-thousands tier and the group-related input, via a NIST SP 800-108 KDF in counter mode using HMAC-SHA-512 (see NIST SP 800-108r1, August 2022).
  • L1 seed key: derived from L0 with a second-tier label.
  • L2 seed key: derived from L1 with the third-tier label. This is the actual symmetric key the DPAPI-NG blob's content key wraps under (or the seed for a per-period group ECDH key pair, in the public-key DPAPI-NG mode).
L0 seed key

The first level of the [MS-GKDI] three-tier derivation chain. Computed deterministically from the KDS root key and a label that combines the time-period tier (in units of period-in-hours / 1000) and a group-related input. The whole point of the chain is that any DC that holds the same root key, given the same label, derives the same L0 seed key without coordination with any other DC -- which is also the whole reason a single root-key compromise compromises every key the forest will ever derive.

Ctrl + scroll to zoom
The KDS L0/L1/L2 chain. One forest-wide root key plus a deterministic SP800-108 KDF means every DC computes the same per-(group, period) key with no inter-DC traffic.

The GetKey round trip

A member computer's local KDS-NG provider calls the GetKey RPC (the primary opnum of [MS-GKDI]) against any reachable writable DC. The DC computes the L0/L1/L2 chain on demand and returns the per-(group, period) key material. No inter-DC synchronisation is needed because the KDF is deterministic.

Ctrl + scroll to zoom
GetKey round trip: any member, any DC, same answer.

Every DC in the forest runs the same kdssvc.dll over the same root key with the same KDF; every authorised member of the named group can ask any DC for the per-(group, period) key and receive the same answer. The architecture is elegant. It is also, by structural necessity, the architecture that makes a one-shot read of the root key into a one-shot compromise of every key the forest will ever derive. Hold that thought; it is what §10 is built on. First we look at what actually rides on this substrate today.

8. The Four Things That Ride DPAPI-NG in 2026

One protocol, four production consumers. The same KDS root key that protects a SID= DPAPI-NG blob is also the root from which every gMSA password, every dMSA password, every TPM-less Windows Hello private key, and every Credential Guard isolated NT-hash is derived.

Group Managed Service Account (gMSA)

A Windows-Server-2012-introduced Active Directory account class whose password is computed automatically by the Microsoft Key Distribution Service on the DC, rotated every 30 days, 256 bytes long, and shared across multiple service hosts via the msDS-GroupMSAMembership SDDL gate. From the Microsoft Learn overview verbatim: "For a gMSA, the domain controller computes the password on the key that the Key Distribution Services provides, along with other attributes of the gMSA." Install-ADServiceAccount on each member computer caches the derivation locally so the service can boot under the account.

Ctrl + scroll to zoom
One root key, four production consumers: every shipping multi-host or multi-cycle Windows credential primitive sits on the same KDS substrate.

8.1 Group Managed Service Accounts

gMSAs shipped in Windows Server 2012 (October 2012). The model: one AD account, multiple service hosts, no admin-managed password rotation, no per-service password file. The Microsoft Learn overview is verbatim about the chain: "The Microsoft Key Distribution Service (kdssvc.dll) lets you securely obtain the latest key or a specific key with a key identifier for an Active Directory account... For a gMSA, the domain controller computes the password on the key that the Key Distribution Services provides, along with other attributes of the gMSA."

The constructed attribute that surfaces the password to authorised member computers is msDS-ManagedPassword; it is computed on demand by the DC from the KDS chain when an authorised member queries it. The authorisation gate is the msDS-GroupMSAMembership security descriptor on the gMSA object: only principals whose SIDs satisfy that SDDL get the password back. Rotation is every 30 days. The password length is 256 bytes -- "a randomly generated password of 256 bytes, making it infeasible to crack" per the Semperis Golden gMSA write-up, which is true if and only if the KDS root key is intact. We come back to that if and only if in §10.

8.2 Delegated Managed Service Accounts

dMSAs shipped in Windows Server 2025 (GA November 1, 2024). The same KDS chain; a different authorisation gate. Rather than binding to AD group membership, dMSA authentication binds to machine identity: the Microsoft Learn overview describes dMSAs as "a machine account with managed and fully randomized keys, while disabling original service account passwords. Authentication for dMSA is linked to the device identity, which means that only specified machine identities mapped in Active Directory (AD) can access the account." The msDS-ManagedPasswordId attribute carries a machine-binding component. Microsoft's marketing framing positions dMSA as the "Kerberoast-immune" replacement for static service accounts.

The Server 2025 dMSA design has its own §10 footnote: the July 2025 Semperis Golden dMSA disclosure found that the msDS-ManagedPasswordId time-component has predictable structure with only ~1 024 plausible values, making offline brute-forcing tractable once the KDS root key is in hand.

8.3 Windows Hello for Business software-KSP credentials

The Hello for Business how it works page describes the credential as a per-user per-device asymmetric key pair. On TPM-equipped devices the private key lives in the TPM and DPAPI-NG is not in the wrap path. On TPM-less devices (the structural worst case) the WHfB private key sits in a CNG software Key Storage Provider container persisted as a DPAPI-NG-protected file whose protection descriptor binds it to the user SID + device. The TPM in Windows article in this series covers the TPM-bound case; here we record only that the software-KSP fallback rides on DPAPI-NG and inherits the KDS root-key dependency for the SID-bound branch.

Software KSP (CNG Software Key Storage Provider)

A non-hardware-bound CNG key-storage provider that persists key material in DPAPI-NG-protected files in the user profile. Used by Windows Hello for Business on TPM-less devices and as the fallback when no hardware-bound KSP (TPM, smart card, Secure Enclave equivalent) is available. The structural worst case for the WHfB credential, because the private key lives in a file the OS can read in any user-context process, wrapped under a DPAPI-NG blob whose protection descriptor reduces back to the KDS root key for SID-anchored bindings.

8.4 Credential Guard isolated-secret persistence

The companion Credential Guard article in this series covers LsaIso.exe and the LSAISO trustlet's isolation boundary in depth; what matters here is that the trustlet's persistence layer is DPAPI-NG. LsaIso.exe, running in VTL1 IUM, stores the isolated NT one-way function outputs and Kerberos session keys in DPAPI-NG blobs whose protection descriptor binds them to the trustlet's own identity. The VSM master key (TPM-bound on TPM-2.0 systems per Microsoft Learn's Credential Guard overview, which describes how Credential Guard "uses Virtualization-based security (VBS) to isolate secrets") is what the trustlet seals its DPAPI-NG protection state under across reboots. The end result is that even though the Credential Guard model puts the credential outside lsass.exe, the persistence of that isolated secret rides on the same KDS-rooted DPAPI-NG chain every other consumer in this section uses.

ConsumerRotationAuthorisation gateOn-disk artefactRecovery story
gMSA30 daysmsDS-GroupMSAMembership SDDLCached on member via Install-ADServiceAccountRecompute via KDS at any time
dMSAManaged by KDSMachine identity in ADCached on member; msDS-ManagedPasswordId carries machine bindingRecompute via KDS
WHfB software-KSPPer-credential lifetimeUser SID + deviceDPAPI-NG-wrapped key container in user profileNew enrollment if lost
LsaIso DPAPI-NG persistenceBoot-cycle boundTrustlet identityTrustlet-managed VTL1 store, sealed under VSM master keyRe-derive on next logon

Every shipping Windows credential primitive that just works across multiple devices, multiple service hosts, or multiple cold-boot cycles -- without per-application key-management code -- is sitting on the same KDS root key. The architectural bet is that the root key never leaks. The next two sections are about what happens when it does.

9. The Five Structural Ceilings DPAPI Cannot Close

A reader who has followed the chain through §§3-8 has earned the right to a sharp question: where does this whole architecture fail? Not where does it have bugs (it has very few cryptographic ones); where does the design draw a line that no implementation patch can move? There are exactly five such lines.

9.1 The user-context ceiling

Any process running as the user can call CryptUnprotectData or NCryptUnprotectSecret against any blob the user could decrypt. The chain binds the secret to the user identity, not the consuming process identity. This is the structural reason every modern browser-cookie-stealer family (Lokibot, Vidar, RedLine, Lumma, StealC) works against DPAPI-protected Chrome state keys; it is also the reason Google introduced Chrome app-bound encryption in July 2024 outside DPAPI. Will Harris of the Chrome security team is verbatim about why the patch had to live outside DPAPI rather than inside it: "On Windows, Chrome uses the Data Protection API (...). However, the DPAPI does not protect against malicious applications able to execute code as the logged in user -- which info-stealers take advantage of."

"On Windows, Chrome uses the Data Protection API (DPAPI). However, the DPAPI does not protect against malicious applications able to execute code as the logged in user -- which info-stealers take advantage of." -- Will Harris, Chrome security team, July 2024

9.2 The single-password-derivation ceiling

The classic-DPAPI master-key wrap is PBKDF2-HMAC-SHA512(SHA1(NT-hash), SID-as-UTF16LE, ~8000 iterations) in the modern (Windows 10/11) era per the Passcape table. 8 000 iterations of HMAC-SHA-512 is not strong against a modern wordlist attack on a leaked NT hash. The structural limit is the user's password, not the cryptographic primitive. The KDF parameter is tunable; the single secret in the chain is not -- a strong password makes the chain strong, a weak password makes the chain weak, and there is no architectural way to recover from a weak password short of re-deriving every user's master key under a stronger one.

9.3 The KDS-root-key irrotability ceiling

Once a KDS root key is in production use, rotating it would invalidate every gMSA msDS-ManagedPassword, every dMSA password, every SID= blob, every Hello-for-Business software-KSP container, and every Credential-Guard isolated-secret blob ever produced under it. Microsoft's documented mitigation is preventative (a system access control list on msKds-RootKeyData), not recoverable. This is the same structural ceiling that the Microsoft Learn DPAPI-backup-keys page admits for the older [MS-BKRP] keys, in identical language: "There currently is no officially supported way of changing or rotating these DPAPI backup keys on the domain controllers." Burn-the-forest-and-rebuild for [MS-BKRP]; SACL-the-attribute-and-hope for KDS root keys.

9.4 The hibernation / S4 ceiling

CryptProtectMemory / CryptUnprotectMemory provide an in-memory scrub primitive that scopes a secret across same-process / cross-process / cross-session lifetimes. They cannot scrub RAM written to hiberfil.sys on suspend-to-disk. On resume the master key is in plaintext in the page cache. The structural defence is BitLocker on the system volume (the BitLocker on Windows article in this series covers full-volume encryption end-to-end); within DPAPI itself the ceiling cannot move because the OS has to be able to resume.

9.5 The domain-backup-key concentration ceiling

The [MS-BKRP] backup key is the recoverability story for the password-reset case -- and it is also the structural reason any DA who can dump LSASS on a writable DC has every user's master key in the forest. mimikatz "lsadump::backupkeys /system:dc.contoso.local /export" is the canonical primitive, documented in the Mimikatz DPAPI wiki. The architectural answer (HSM-backing the DC's RSA private key) is not in Microsoft's mainline guidance; the recommendation when these keys are compromised is the burn-the-forest-and-rebuild line we just quoted.

These five ceilings are not bugs. They are the design's price for the design's other guarantees. The user-context ceiling buys ubiquitous adoption. The single-password ceiling buys a usable recovery path. The KDS-root-key ceiling buys cross-DC determinism. The hibernation ceiling buys process performance and resumability. The domain-backup-key ceiling buys enterprise recovery. Every one of the next five years' DPAPI incidents will hit one of these five ceilings.

The 2022-2025 disclosures are not five surprises. They are five different attackers naming five different ceilings out loud. The next section walks the named incidents one ceiling at a time.

10. The 2022-2025 Residual Class: Golden gMSA, Golden dMSA, and Chromium App-Bound Encryption

In March 2022, Yuval Gordon at Semperis published Introducing the Golden GMSA Attack and the GoldenGMSA C# tool. In July 2024, Google announced Chrome's app-bound encryption. In July 2025, Adi Malyanker (also Semperis) published Golden dMSA: What Is dMSA Authentication Bypass? and the GoldenDMSA tool, mirrored on PR Newswire with a July 16, 2025 dateline. Three disclosures in three years, three different ceilings -- but the same underlying pattern: each one is an admission that the structural ceiling cannot be patched inside DPAPI.

Ctrl + scroll to zoom
The five ceilings -> the named 2022-2025 incidents.

10.1 Golden gMSA (Yuval Gordon, Semperis, March 2022)

Targets the §9.3 KDS-root-key irrotability ceiling. Gordon is verbatim about the two-step nature of the attack: "An attacker with high privileges can obtain all the ingredients for generating the password of any gMSA in the domain at any time with two steps: Retrieve several attributes from the KDS root key in the domain... Use the GoldenGMSA tool to generate the password of any gMSA associated with the key, without a privileged account." Step 1 is a one-shot read of the KDS root key attributes. Step 2 is offline derivation. There is no further DC interaction, ever, because the [MS-GKDI] chain is deterministic by NIST SP 800-108r1 design.

The defensive answer is in the GoldenGMSA repository: "configure a SACL on the KDS root key objects for everyone reading the msKds-RootKeyData attribute. Once the system access control list (SACL) is configured, any attempt to dump the key data of a KDS root key will generate security event 4662 on the DC where the object type is msKds-ProvRootKey and the account name is not a DC." Plus the cross-trust SACL on msDS-ManagedPasswordId with property GUID {0e78295a-c6d3-0a40-b491-d62251ffa0a6}. This is a detective control, not a recovery control. Once the root key has been read, every gMSA password the forest has ever issued or will ever issue under that root key is offline-derivable.

"An attacker with high privileges can obtain all the ingredients for generating the password of any gMSA in the domain at any time with two steps." -- Yuval Gordon, Semperis, March 2022

The Golden gMSA SACL detects same-trust reads only. Cross-trust reads of msDS-ManagedPasswordId from a forest the auditing forest does not control are the documented detection blind-spot. If your gMSA-using forest has a one-way trust from a forest you do not own, you cannot see its reads.

10.2 Golden dMSA (Adi Malyanker, Semperis, July 2025)

Targets the §9.3 ceiling, plus a fresh dMSA-specific surface. Malyanker is verbatim about the structural flaw: "a critical design flaw: a structure that's used for the password-generation computation contains predictable time-based components with only 1,024 possible combinations, making brute-force password generation computationally trivial." The four-phase pipeline is enumerated in the GoldenDMSA repository: "Phase 1: Key Material Extraction (pre requirement of the attack) -- Dump the KDS Root Key from the DC. Phase 2: Enumerate dMSA accounts ... Phase 3: ManagedPasswordID guessing ... Phase 4: Password Generation." The tool exposes commands wordlist, info, kds, bruteforce, compute, and convert -- the operational vocabulary the four-phase pipeline needs.

Semperis' own rating is MODERATE with the explicit caveat "to exploit it, attackers must possess a KDS root key available only to only the most privileged accounts: root Domain Admins, Enterprise Admins, and SYSTEM." That is exactly the §9.3 ceiling re-stated. The novelty in dMSA is the 1 024-combination time-component flaw -- a design weakness on top of the structural ceiling, not a substitute for it.

10.3 Chromium app-bound encryption (Will Harris, Google Chrome, July 30, 2024)

Targets the §9.1 user-context ceiling. The Google Security Blog announcement describes a COM-elevation service that wraps the Chrome state key with both DPAPI and a per-binary identity check the COM service enforces. The verbatim quote, mirrored via The Hacker News: "Because the app-bound service is running with system privileges, attackers need to do more than just coax a user into running a malicious app. Now, the malware has to gain system privileges, or inject code into Chrome, something that legitimate software shouldn't be doing."

The architecturally important word is "app-bound." Chromium's response to the user-context ceiling lives outside DPAPI. DPAPI itself is unchanged. The 2024 patch is application-layer code-identity pinning -- exactly what Generation-1 Protected Storage's abandoned Authenticode-access-rule clause was supposed to be in 2000, exactly what Apple Keychain has shipped on macOS for over two decades, exactly what the §11 wishlist asks for.

10.4 The recurring pattern

Each disclosure does not break a cryptographic primitive. Each is a re-statement of "the design's ceiling is the design's ceiling." The defensive answers are detection (SACL audit; cross-trust read alerting; binary-identity check) and workaround at a higher layer (the COM-elevation service Chrome wraps DPAPI in), never cryptographic strengthening of DPAPI itself. The 2026 reader's job is to recognise which ceiling each new incident hits.

YearDisclosureCeiling hitTool referenceDefensive answer
2022Golden gMSA (Y. Gordon, Semperis)§9.3 KDS irrotabilityGoldenGMSASACL on msKds-RootKeyData; Event 4662
2024Chromium app-bound encryption (W. Harris, Google)§9.1 user-contextChrome 127 release notesCOM-elevation per-binary identity check, outside DPAPI
2025Golden dMSA (A. Malyanker, Semperis)§9.3 + dMSA msDS-ManagedPasswordId predictabilityGoldenDMSASACL plus monitoring msDS-ManagedPasswordId brute-force

By 2026 the pattern is clear: DPAPI's structural ceilings produce a steady drip of disclosures, each defensively answerable but none cryptographically fixable inside DPAPI itself. The open question is what the successor would even look like -- and that is the next section.

11. Open Problems

A few sharp open problems remain at the design layer -- problems that a future Generation 4 of the credential-vault tradition would have to solve. None of them is in Microsoft's published roadmap as of 2026.

KDS root-key rotation

A hybrid wrap-then-re-wrap-on-first-decrypt-under-new-root scheme could in principle restore rotation without invalidating existing blobs: every consumer would carry a tag indicating which root-key generation last unwrapped it; on first unwrap under a generation-N+1 root the system would re-wrap the consumer-side cache. No standard or product implements this today; no public proposal revises [MS-GKDI] to add it.

Code-identity pinning

Apple Keychain enforces "keychain items can be shared only between apps from the same developer ... enforced through code signing, provisioning profiles, and the Apple Developer Program." DPAPI / DPAPI-NG have no equivalent. A CALLER_ATTRIBUTION=Publisher:<wdac-rule-hash> descriptor would, in principle, give Windows the same property -- the SHA-256 hash of the WDAC rule that authorises the calling binary, baked into the descriptor, checked at unwrap time. No one is shipping it. The 2024 Chromium app-bound encryption response is the application-layer workaround that proves the design gap is real.

Post-quantum migration

DPAPI-NG today uses RSA-OAEP (CERTIFICATE= with RSA private keys) or ECDH P-256 / P-384 (SID= group descriptors) per the protected-data-format reference. Both wrap algorithms are vulnerable to Shor's algorithm on a sufficiently large quantum computer, and the persistent on-disk blob format is the harvest-now-decrypt-later target -- a framing surfaced across NIST's broader post-quantum migration corpus, including the NIST PQC project page and the linked NIST IR 8547 migration-timeline document. The migration story for the symmetric chain is comparatively easy (the SP800-108 KDF is parameterised; HMAC-SHA-512 has no quantum-cliff weakness for the relevant key sizes). The migration story for the public-key wrap is the hard part. NIST published FIPS 203 (ML-KEM) and FIPS 204 (ML-DSA) in August 2024; OpenSSH 9.9 (September 2024) and TLS deployments shipped hybrid post-quantum key exchange. Windows added experimental post-quantum TLS support in 2024 but has not yet announced ML-KEM CNG-DPAPI providers; see the companion Post-Quantum Cryptography on Windows article in this series for the broader Windows migration story. The shape that fits DPAPI's ceiling-laden design is hybrid wrap-then-re-wrap-on-first-decrypt: a hybrid wrap (RSA-OAEP || ML-KEM or ECDH || ML-KEM) -- protect under (RSA+ML-KEM) or (ECDH+ML-KEM) today; let consumers re-wrap to the new combiner on first unwrap; phase out the classical half on a long horizon -- is the only forward-compatible answer; Microsoft's published DPAPI-NG protection-providers have not yet announced one.

Credential roaming for Entra-joined-only / unmanaged-device estates

Classic DPAPI's cross-device story has always been "use roaming profiles" (deprecated) or "use the [MS-BKRP] backup key" (admin-recovery, not user-driven). DPAPI-NG's SID= solves it cleanly for AD-joined estates but the modern Entra-only estate has no native equivalent -- the LOCAL=user descriptor is per-machine. An ENTRAGROUP=<object-id> descriptor that resolved through Entra ID Token Service the way SID= resolves through KDS would close the gap. No public roadmap announces this.

Hibernation / S4

BitLocker on the system volume defends the disk; suspending fully to ROM (or refusing S4 entirely) defends the in-RAM master key. Hardware-bound key derivation (TPM-released-only-while-PCRs-stable) would close more of the gap; the TPM in Windows article in this series covers TPM-bound primitives that approximate this property.

Every one of these is a design gap -- a property the architecture would need a new primitive to satisfy. None is on Microsoft's announced roadmap. The architecture we have is the architecture we will have for at least the next five years; the practitioner's job is to know which ceilings their estate is exposed to and how to detect each of them.

12. Practical Guide and Closing

The four-audience guide for the 2026 practitioner.

12.1 For a developer

Use CryptProtectData / CryptUnprotectData for per-user-on-this-device secrets. Pass pOptionalEntropy to bind the blob to a per-application secret -- but understand it is security-by-obscurity, not a code-identity check; any reader of the SharpDPAPI source who knows your constant entropy can reproduce the unprotect call as the user.

Use NCryptProtectSecret with the appropriate descriptor for cross-device or multi-principal cases. LOCAL=user mirrors classic DPAPI on a single machine. SID=<group-sid> reaches AD groups via KDS. CERTIFICATE=HashID:<sha1> reaches a named certificate (TPM-backed for the high-security case). Use the WebAuthn / FIDO2 path for authentication secrets; do not store passwords in DPAPI when WHfB / passkey paths are available.

JavaScript DPAPI-NG descriptor selection logic (no real credentials)
// Returns the appropriate DPAPI-NG protection-descriptor string for a use case.
// Reference: learn.microsoft.com windows win32 seccng protection-descriptors
function descriptorFor(useCase, ctx) {
switch (useCase) {
  case "single-device-single-user":
    return "LOCAL=user";

  case "ad-group":
    // Multiple machines, AD-authorized group members can decrypt.
    return "SID=" + ctx.groupSid;

  case "tpm-backed-cert":
    // Decrypter must hold the named certificate's private key (TPM-bound KSP).
    return "CERTIFICATE=HashID:" + ctx.certThumbprintSha1;

  case "web-credential":
    // Resolves through the Windows credential broker.
    return "WEBCREDENTIALS=" + ctx.credName;

  default:
    throw new Error("Unknown use case: " + useCase);
}
}

console.log(descriptorFor("single-device-single-user"));
console.log(descriptorFor("ad-group", { groupSid: "S-1-5-21-...-5101" }));

Press Run to execute.

12.2 For a defender or DFIR analyst

Triage the credential-vault inventory in §5 first. The high-value paths are %APPDATA%\Microsoft\Protect\&lt;SID&gt;\, %APPDATA%\Microsoft\Protect\CREDHIST, %APPDATA%\Microsoft\Credentials\, %LOCALAPPDATA%\Microsoft\Vault\, the Chromium / Edge profile databases, and the AD CN=Master Root Keys,... container.

The SACL guidance from the GoldenGMSA repository is the only detective control today: "configure a SACL on the KDS root key objects for everyone reading the msKds-RootKeyData attribute. Once the system access control list (SACL) is configured, any attempt to dump the key data of a KDS root key will generate security event 4662 on the DC where the object type is msKds-ProvRootKey and the account name is not a DC." Plus the cross-trust SACL on msDS-ManagedPasswordId with property GUID {0e78295a-c6d3-0a40-b491-d62251ffa0a6}.

Tooling: Mimikatz dpapi::* modules, SharpDPAPI, DPAPIck (Bursztein-Picod 2010), GoldenGMSA, GoldenDMSA, and the Volatility lsadump / cachedump / hashdump plugins for live-memory extraction of DPAPI_SYSTEM and the other LSA secrets that seed SYSTEM-context master-key derivation.

Python Synthetic credential-vault triage walker (no real disk image)
# Walk a synthetic profile-directory layout and emit a DPAPI-relevant triage report.
import os
from collections import defaultdict

# Synthetic profile layout for demonstration only.
synthetic = {
  "Users/alice/AppData/Roaming/Microsoft/Protect/S-1-5-21-1234-1001/Preferred": "8KB",
  "Users/alice/AppData/Roaming/Microsoft/Protect/S-1-5-21-1234-1001/0d4a...": "740B",
  "Users/alice/AppData/Roaming/Microsoft/Protect/CREDHIST": "176B",
  "Users/alice/AppData/Roaming/Microsoft/Credentials/abcdef...": "300B",
  "Users/alice/AppData/Local/Microsoft/Vault/4BF4C442-9B8A-41A0-B380-DD4A704DDB28/Policy.vpol": "180B",
  "Users/alice/AppData/Local/Google/Chrome/User Data/Default/Cookies": "4MB",
  "Users/alice/AppData/Local/Google/Chrome/User Data/Local State": "12KB",
}

categories = {
  "Master keys":          "/Microsoft/Protect/S-1-",
  "CREDHIST chain":       "/Protect/CREDHIST",
  "Credential Manager":   "/Microsoft/Credentials/",
  "Windows Vault":        "/Microsoft/Vault/",
  "Chrome state key":     "/Google/Chrome/User Data/Local State",
  "Chrome cookies":       "/Google/Chrome/User Data/Default/Cookies",
}

report = defaultdict(list)
for path, size in synthetic.items():
  for label, marker in categories.items():
      if marker in path:
          report[label].append((path, size))

for label, items in report.items():
  print("==", label)
  for path, size in items:
      print("  ", path, "(" + size + ")")

Press Run to execute.

12.3 For a red-team operator

The chain of primitives most-commonly used (verbatim from the harmj0y operational guide and the Mimikatz wiki):

Operator command sequence (defensive context only)

The operational vocabulary, in order of dependency:

  1. mimikatz "sekurlsa::dpapi" -- enumerate cached master keys from a live lsass.exe.
  2. mimikatz "dpapi::masterkey /in:<MK> /sid:&lt;SID&gt; /password:<known>" -- unwrap a master-key file.
  3. mimikatz "dpapi::cred /in:<credfile>" -- decrypt a Credential Manager entry.
  4. mimikatz "lsadump::backupkeys /system:dc.contoso.local /export" -- export the [MS-BKRP] RSA private key from a writable DC.
  5. SharpDPAPI triage /pvk:key.pvk -- offline triage with the domain backup key.
  6. SharpChrome cookies /pvk:key.pvk -- decrypt Chrome / Edge cookies offline.
  7. GoldenGMSA gmsainfo then GoldenGMSA compute -k <root-key-guid> -s <gmsa-sid> -m <managed-password-id> -- offline gMSA password derivation per the March 2022 disclosure.
  8. GoldenDMSA wordlist / bruteforce / compute -- the four-phase Server 2025 dMSA pipeline per the July 2025 disclosure.

The post-Credential-Guard scope reality: LSASS-isolated NT-hashes are gone (the Credential Guard article in this series covers what LsaIso.exe actually computes); on-disk DPAPI master keys, Chrome cookies, and Vault credentials are still there. The credential-vault inventory in §5 is the operator's map; the §10 disclosure list is the operator's playbook.

12.4 For a platform or identity engineer

Provision the KDS root key carefully. Use the Add-KdsRootKey default 10-day EffectiveTime for production forests so AD replication converges before any consumer derives against the new key; the -EffectiveTime ((Get-Date).AddHours(-10)) override is for single-DC test forests only, never production.

For Server 2025 dMSA, monitor the msDS-ManagedPasswordId brute-force surface until Microsoft addresses the time-component predictability the Golden dMSA disclosure named.

For Hello for Business, prefer the TPM-bound KSP (MS_PLATFORM_CRYPTO_PROVIDER); the software-KSP DPAPI-NG fallback is the structural worst case (per §8.3) and inherits the KDS root-key dependency on every TPM-less device.

Cross-platform context: Apple Keychain reaches a stronger upper bound (Secure-Enclave-bound + code-identity-pinned via the Apple Developer Program); GNOME libsecret covers the analogous Linux primitive over the Secret Service D-Bus interface. Neither is a drop-in replacement; both have shapes worth borrowing if Microsoft ever publishes the Generation-4 design.

12.5 The closing reflection

The credential vault under everything has a single-sentence summary in 2026: classic DPAPI is as strong as the user's password; DPAPI-NG is as strong as the KDS root key's life-cycle SOP is; both architectures admit ceilings the cryptography cannot move. The literacy a practitioner needs is the ability to recognise which ceiling any new incident hits. Twelve sections later, you have it.

Frequently Asked Questions

Frequently asked questions

Does Credential Guard mean Mimikatz cannot dump my browser cookies?

No. Credential Guard protects LSA-isolated secrets only. Chrome cookies live in the user's profile under DPAPI / DPAPI-NG and are decryptable by any process running as the user, exactly as before. The Chromium 2024 app-bound encryption is a per-process workaround for the §9.1 user-context ceiling, not a fix inside DPAPI itself.

If I reset my Microsoft Account password from the web, why do my saved Windows credentials disappear?

A web reset of a consumer Microsoft Account password does not append to CREDHIST and does not benefit from [MS-BKRP] backup -- there is no domain in the consumer scenario. Master keys encrypted under the previous password become irrecoverable for consumer Microsoft Accounts, full stop. Domain-joined enterprise users escape this because the domain backup key still works.

Are Group Managed Service Account passwords unguessable?

True if the KDS root key is intact -- the Semperis write-up records the "randomly generated password of 256 bytes, making it infeasible to crack" claim. False under the Golden gMSA / Golden dMSA assumption that any DA / SYSTEM on a DC can read msKds-RootKeyData. A 256-byte random password is irrelevant if the attacker can derive it offline.

Is DPAPI-NG just DPAPI on a newer crypto suite?

No. DPAPI-NG is a redesign whose protection model is descriptor-based (multi-principal, multi-device) rather than user-and-machine-bound. The two APIs coexist; classic DPAPI is still the default for CryptProtectData callers, and DPAPI-NG is the path for NCryptProtectSecret callers.

Are Windows Hello for Business private keys always TPM-bound?

No. On TPM-less devices the WHfB private key sits in a CNG software-KSP container persisted as a DPAPI-NG blob whose protection descriptor binds it to user SID + device, per the Hello for Business architecture. The TPM-bound case is the preferred deployment; the software-KSP fallback is the structural worst case and inherits the §9.3 KDS root-key dependency.

Does CryptProtectMemory protect against hibernation?

No. CryptProtectMemory scrubs in-memory secrets between same-process / cross-process / cross-session lifetimes but cannot prevent the OS from writing the page-protected RAM into hiberfil.sys on suspend-to-disk. BitLocker on the system volume is the structural defence (the BitLocker on Windows article in this series covers full-volume encryption end-to-end).

Did the Bursztein/Picod 2010 paper break DPAPI?

No. It broke the secrecy of DPAPI's design. The 2010 disclosure made the master-key chain public and tractable for offline forensics; it did not weaken the cryptography. The "break" was always structural -- DPAPI is as strong as the user's password is. The two-author byline is Bursztein and Picod (Black Hat DC 2010, USENIX WOOT 10), not "Bursztein, Picod and Aussel."

Study guide

Key terms

DPAPI
The Data Protection API; the per-user / per-machine secret-storage primitive in every Windows release from Windows 2000 onward.
Master key
A 64-byte random secret per user, stored under %APPDATA%/Microsoft/Protect/&lt;SID&gt;/&lt;GUID&gt;, encrypted under a pre-key derived from the user's password and SID.
[MS-BKRP] BackupKey Remote Protocol
The LSASS-hosted RPC interface that lets a member computer dual-wrap its master key under both the user password pre-key and a DC RSA backup public key; the canonical universal-decryption primitive available to Domain Admins.
CREDHIST
The previous-password hash chain stored in %APPDATA%/Microsoft/Protect/CREDHIST; one entry per self-initiated password change; broken by administrative reset and consumer-Microsoft-Account web reset.
Protection descriptor (DPAPI-NG)
The DPAPI-NG self-describing string (SID, SDDL, LOCAL, WEBCREDENTIALS, CERTIFICATE) that names the set of principals permitted to remove protection from a blob.
Microsoft Key Distribution Service (kdssvc.dll)
The DC-side daemon that implements the [MS-GKDI] protocol and computes per-(group, period) keys deterministically from a single forest-wide root key.
KDS root key
The single forest-wide secret that anchors every per-(group, period) key the KDS will ever derive; provisioned exactly once per forest with Add-KdsRootKey; documented as having no rotation procedure.
Group Managed Service Account (gMSA)
A Server-2012-introduced AD account whose 256-byte password is derived from the KDS chain and rotated every 30 days, gated by the msDS-GroupMSAMembership SDDL.
Software KSP
The non-hardware-bound CNG Key Storage Provider that persists key material as DPAPI-NG-protected files; used as the WHfB fallback on TPM-less devices.
Golden gMSA / Golden dMSA
The 2022 / 2025 Semperis offline-derivation attacks that compute any gMSA / dMSA password the forest will ever issue, given a one-shot read of the four KDS root-key attributes.

References

  1. CNG DPAPI. https://learn.microsoft.com/en-us/windows/win32/seccng/cng-dpapi
  2. Protection descriptors (CNG DPAPI). https://learn.microsoft.com/en-us/windows/win32/seccng/protection-descriptors
  3. Protected data format (CNG DPAPI). https://learn.microsoft.com/en-us/windows/win32/seccng/protected-data-format
  4. Protection providers (CNG DPAPI). https://learn.microsoft.com/en-us/windows/win32/seccng/protection-providers
  5. CryptProtectData function (dpapi.h). https://learn.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptprotectdata
  6. NCryptProtectSecret function (ncryptprotect.h). https://learn.microsoft.com/en-us/windows/win32/api/ncryptprotect/nf-ncryptprotect-ncryptprotectsecret
  7. CryptProtectMemory function (dpapi.h). https://learn.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptprotectmemory
  8. [MS-GKDI]: Group Key Distribution Protocol. https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-gkdi/943dd4f6-6b80-4a66-8594-80df6d2aad0a
  9. [MS-BKRP]: BackupKey Remote Protocol. https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-bkrp/
  10. [MS-BKRP]: BackupKey Remote Protocol Specification (PDF, v27.0, April 2024). https://winprotocoldocs-bhdugrdyduf5h2e4.b02.azurefd.net/MS-BKRP/[MS-BKRP].pdf - Source for the BackupKey RPC interface UUID and named-pipe binding
  11. Group Managed Service Accounts overview. https://learn.microsoft.com/en-us/windows-server/security/group-managed-service-accounts/group-managed-service-accounts-overview
  12. Add-KdsRootKey (PowerShell). https://learn.microsoft.com/en-us/powershell/module/kds/add-kdsrootkey
  13. Delegated Managed Service Accounts overview. https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/delegated-managed-service-accounts/delegated-managed-service-accounts-overview
  14. [MS-ADTS]: MSDS-MANAGEDPASSWORD_BLOB. https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/a9019740-3d73-46ef-a9ae-3ea8eb86ac2e
  15. Pstore (Windows developer notes). https://learn.microsoft.com/en-us/windows/win32/devnotes/pstore
  16. CNG DPAPI backup keys on AD domain controllers. https://learn.microsoft.com/en-us/windows/win32/seccng/cng-dpapi-backup-keys-on-ad-domain-controllers
  17. Windows Hello for Business: how it works. https://learn.microsoft.com/en-us/windows/security/identity-protection/hello-for-business/how-it-works
  18. NAI Labs (Network Associates) (2001). Windows Data Protection (MSDN ms995355). https://learn.microsoft.com/en-us/previous-versions/ms995355(v=msdn.10) - Canonical first public Microsoft-blessed DPAPI design document
  19. DPAPI Black Box (Passcape). https://www.passcape.com/index.php?section=docsys&cmd=details&id=28
  20. Windows Password Recovery: DPAPI master-key analysis (Passcape). https://www.passcape.com/windows_password_recovery_dpapi_master_key
  21. Elie Bursztein & Jean-Michel Picod (2010). Reversing DPAPI and Stealing Windows Secrets Offline (Black Hat DC 2010). https://elie.net/talk/reversing-dpapi-and-stealing-windows-secrets-offline
  22. Jean-Michel Picod & Elie Bursztein (2010). Decrypting DPAPI data (slide deck, Black Hat DC 2010, February 3 2010). https://elie.net/static/files/reversing-dpapi-and-stealing-windows-secrets-offline/reversing-dpapi-and-stealing-windows-secrets-offline-slides.pdf
  23. Elie Bursztein & Jean-Michel Picod (2010). Recovering Windows Secrets and EFS Certificates Offline (USENIX WOOT 10). https://elie.net/static/files/reversing-dpapi-and-stealing-windows-secrets-offline/reversing-dpapi-and-stealing-windows-secrets-offline-paper.pdf
  24. Recovering Windows Secrets and EFS Certificates Offline -- BibTeX. https://elie.net/publication/recovering-windows-secrets-and-efs-certificates-offline/
  25. Elie Bursztein & Jean-Michel Picod (2010). Recovering Windows Secrets and EFS Certificates Offline. https://www.usenix.org/conference/woot10/recovering-windows-secrets-and-efs-certificates-offline - USENIX WOOT 10 canonical record; two authors: Bursztein and Picod
  26. gentilkiwi/mimikatz repository metadata (GitHub API). https://api.github.com/repos/gentilkiwi/mimikatz
  27. Benjamin Delpy (2014). Mimikatz initial commit (gentilkiwi/mimikatz, April 6 2014). https://github.com/gentilkiwi/mimikatz/commit/6419a5f37918
  28. Mimikatz dpapi module wiki. https://github.com/gentilkiwi/mimikatz/wiki/module-~-dpapi
  29. Will Schroeder GhostPack/SharpDPAPI README. https://github.com/GhostPack/SharpDPAPI
  30. Will Schroeder Operational Guidance for Offensive User DPAPI Abuse. https://blog.harmj0y.net/redteaming/operational-guidance-for-offensive-user-dpapi-abuse/
  31. Yuval Gordon (2022). Introducing the Golden GMSA Attack (Semperis). https://www.semperis.com/blog/golden-gmsa-attack/
  32. Semperis/GoldenGMSA repository. https://github.com/Semperis/GoldenGMSA
  33. Adi Malyanker (2025). Golden dMSA: What Is dMSA Authentication Bypass? (Semperis). https://www.semperis.com/blog/golden-dmsa-what-is-dmsa-authentication-bypass/
  34. Semperis/GoldenDMSA repository. https://github.com/Semperis/GoldenDMSA
  35. (2025). Semperis Research Uncovers Critical Flaw in Windows Server 2025 (PR Newswire, July 16 2025). https://www.prnewswire.com/news-releases/semperis-research-uncovers-critical-flaw-in-windows-server-2025-exposing-managed-service-accounts-to-golden-dmsa-attack-302506258.html
  36. Jean-Christophe Delaunay (2017). DPAPI exploitation during pentest and password cracking (UniverShell 2017, Synacktiv). https://www.synacktiv.com/ressources/univershell_2017_dpapi.pdf
  37. OPCDE Dubai 2017 agenda. https://github.com/comaeio/OPCDE/tree/master/2017
  38. Bartosz Inglot (2017). The Blackbox of DPAPI: the gift that keeps on giving (OPCDE Dubai 2017). https://raw.githubusercontent.com/comaeio/OPCDE/master/2017/The%20Blackbox%20of%20DPAPI%20the%20gift%20that%20keeps%20on%20giving%20-%20Bartosz%20Inglot/The%20Blackbox%20of%20DPAPI%20-%20Bart%20Inglot.pdf
  39. Will Harris (2024). Improving the Security of Chrome Cookies on Windows (Google Security Blog, July 30 2024). https://security.googleblog.com/2024/07/improving-security-of-chrome-cookies-on.html
  40. (2024). Google Chrome Adds App-Bound Encryption (The Hacker News, August 2024). https://thehackernews.com/2024/08/google-chrome-adds-app-bound-encryption.html
  41. How Mimikatz Became the Hacker Tool That Defines an Era (Wired). https://www.wired.com/story/how-mimikatz-became-go-to-hacker-tool/
  42. Data Protection API (Wikipedia). https://en.wikipedia.org/wiki/Data_Protection_API
  43. Niels Ferguson (Wikipedia). https://en.wikipedia.org/wiki/Niels_Ferguson
  44. Windows 2000 (Wikipedia). https://en.wikipedia.org/wiki/Windows_2000
  45. Windows Server 2012 (Wikipedia). https://en.wikipedia.org/wiki/Windows_Server_2012
  46. Windows Server 2025 (Wikipedia). https://en.wikipedia.org/wiki/Windows_Server_2025
  47. (2022). NIST SP 800-108 Rev. 1: Recommendation for Key Derivation Using Pseudorandom Functions. https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-108r1.pdf
  48. Apple Platform Security: Keychain data protection. https://support.apple.com/guide/security/keychain-data-protection-secb0694df1a/web
  49. libsecret API reference (GNOME). https://gnome.pages.gitlab.gnome.org/libsecret/
  50. (2024). NIST FIPS 203: Module-Lattice-Based Key-Encapsulation Mechanism Standard (ML-KEM). https://csrc.nist.gov/pubs/fips/203/final - Published August 13, 2024
  51. (2024). NIST FIPS 204: Module-Lattice-Based Digital Signature Standard (ML-DSA). https://csrc.nist.gov/pubs/fips/204/final - Published August 13, 2024
  52. (2024). OpenSSH 9.9 release notes. https://www.openssh.com/releasenotes.html - OpenSSH 9.9 released September 19, 2024 with sntrup761x25519-sha512 hybrid PQ KEX as default
  53. NIST Post-Quantum Cryptography project. https://csrc.nist.gov/projects/post-quantum-cryptography - Source for the harvest-now-decrypt-later framing
  54. volatilityfoundation/volatility3 (memory-forensics framework with LSA-secrets plugins lsadump/cachedump/hashdump). https://github.com/volatilityfoundation/volatility3
  55. Credential Guard overview. https://learn.microsoft.com/en-us/windows/security/identity-protection/credential-guard/
  56. Virtualization-based security (VBS) for OEMs. https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/oem-vbs
  57. Chrome Releases: Stable Channel Update for Desktop (Chrome 127, July 23, 2024). https://chromereleases.googleblog.com/2024/07/stable-channel-update-for-desktop_23.html
  58. BitLocker (Wikipedia). https://en.wikipedia.org/wiki/BitLocker