Skip to content

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).

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