---
title: DPAPI
summary: API reference for DPAPI.
status: draft
owner: <owner>
last_reviewed: 2026-07-23
library: SAIF.Framework.SecurityModule
reference_type: package
---

# DPAPI

`DPAPI` wraps the Win32 Data Protection API (`CryptProtectData`/`CryptUnprotectData` in `crypt32.dll`) to encrypt and decrypt string and byte-array payloads. It is the mechanism used to protect the `SAIFAUTH` cookie contents consumed by `CookieAuthenticator` (see [BR-003](../../business-rules.md#br-003-a-decrypted-saifauth-cookie-must-contain-exactly-two-tab-delimited-fields)).

## Purpose
- Encrypt plaintext (string or byte array) using either a user-specific or machine-specific DPAPI key.
- Decrypt previously DPAPI-encrypted ciphertext back to its original plaintext, with an optional entropy value and returned description.

## Context
- Namespace: `SAIF.Framework.SecurityModule`
- Assembly/package: `SAIF.Framework.SecurityModule` (packaged inside the `SAIF.BOF.Framework` NuGet package)

## Public members
| Member | Signature | Purpose |
| --- | --- | --- |
| `KeyType` | `Public Enum KeyType : UserKey = 1, MachineKey : End Enum` | Selects whether DPAPI protects data with a user-specific key (`UserKey`) or a machine-specific key (`MachineKey`). |
| `Encrypt` | `Public Shared Function Encrypt(plainText As String) As String` | Encrypts `plainText` using the default key type (`UserKey`), no entropy, and no description; returns a base64-encoded ciphertext string. |
| `Encrypt` | `Public Shared Function Encrypt(keyType As KeyType, plainText As String) As String` | Encrypts `plainText` with the specified `keyType`, no entropy, and no description; returns a base64-encoded ciphertext string. |
| `Encrypt` | `Public Shared Function Encrypt(keyType As KeyType, plainText As String, entropy As String) As String` | Encrypts `plainText` with the specified `keyType` and `entropy`, no description; returns a base64-encoded ciphertext string. |
| `Encrypt` | `Public Shared Function Encrypt(keyType As KeyType, plainText As String, entropy As String, description As String) As String` | Encrypts `plainText` with the specified `keyType`, `entropy`, and `description`; returns a base64-encoded ciphertext string. Null `plainText`/`entropy` are normalized to `String.Empty` before encoding to UTF-8 bytes. |
| `Encrypt` | `Public Shared Function Encrypt(keyType As KeyType, plainTextBytes As Byte(), entropyBytes As Byte(), description As String) As Byte()` | Byte-array overload that calls the Win32 `CryptProtectData` function directly via BLOB structures. Sets the `CRYPTPROTECT_UI_FORBIDDEN` flag always, and additionally sets `CRYPTPROTECT_LOCAL_MACHINE` when `keyType` is `MachineKey`. Throws on failure, wrapping the Win32 error in a `Win32Exception`. |
| `Decrypt` | `Public Shared Function Decrypt(cipherText As String, ByRef description As String) As String` | Decrypts a base64-encoded `cipherText` with no entropy; returns the decrypted UTF-8 string and outputs the stored `description` by reference. |
| `Decrypt` | `Public Shared Function Decrypt(cipherText As String, entropy As String, ByRef description As String) As String` | Decrypts a base64-encoded `cipherText` using the supplied `entropy` (required if entropy was specified during encryption); returns the decrypted UTF-8 string and outputs `description` by reference. |
| `Decrypt` | `Public Shared Function Decrypt(cipherTextBytes As Byte(), entropyBytes As Byte(), ByRef description As String) As Byte()` | Byte-array overload that calls the Win32 `CryptUnprotectData` function directly via BLOB structures. Sets the `CRYPTPROTECT_UI_FORBIDDEN` flag; does not set a machine/user key flag since DPAPI determines key type from the ciphertext signature during decryption. Throws on failure, wrapping the Win32 error in a `Win32Exception`. |

## Behavioral notes
- Decryption does not require the caller to specify `KeyType`; DPAPI determines whether a user or machine key was used from the ciphertext signature itself.
- All public members are `Shared`, so `DPAPI` is used as a static utility class rather than instantiated.
- Internal P/Invoke declarations, BLOB marshaling helpers (`InitBLOB`, `InitPrompt`), and the `DATA_BLOB`/`CRYPTPROTECT_PROMPTSTRUCT` structures are `Private`/`Friend` implementation details and are not part of the public surface.
- `CookieAuthenticator.DecryptCookie` is the library's sole consumer of `Decrypt`, using the client host address as the entropy value.*

## Constraints and usage notes
- Depends on `crypt32.dll` being present on the host (Windows-only; the DLL path is hardcoded to `c:\windows\system32\crypt32.dll`).
- The assembly requests `SecurityPermissionAttribute(SecurityAction.RequestMinimum, UnmanagedCode:=True)` to allow the P/Invoke calls into `crypt32.dll`.
- Callers must supply the same `entropy` value used during encryption in order to successfully decrypt; mismatched entropy causes `CryptUnprotectData` to fail.

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with ** could not be confirmed; treat as unknown until verified. Statements marked with
> † were retrieved from dependency library documentation via the Legends CLI RAG service. They
> describe inherited behavior from the indicated origin library and should be verified if the
> dependency version changes.

## Sources
- `SAIF.Framework.SecurityModule\DAPIEncrypt.vb`
