Skip to content

Automated-login credential packaging and restoration

This is a pair of complementary operations rather than one: getEncryptedCredentials() packages a logged-in user's credentials into an encrypted token that a caller can persist for unattended reuse (for example, a scheduled job that logs in without user interaction), and setDecryptedCredentials() reverses that transformation to repopulate the login fields from a previously stored token.

Field Value
Operation ID OP-009
Trigger Caller invokes getEncryptedCredentials() or setDecryptedCredentials()
Inputs User ID, private password field, encrypted payload, optional separator override
Outputs Encrypted credential string or restored user/password fields
Primary components clsSAIFLoginInfo.getEncryptedCredentials, clsSAIFLoginInfo.setDecryptedCredentials, DPAPI.Encrypt, DPAPI.Decrypt
Entry point SAIF.Framework.Security\clsSAIFLoginInfo.vb

Steps

  1. getEncryptedCredentials() assembles the outbound payload as UserID + separator + password + separator, then encrypts it with DPAPI.Encrypt(MachineKey, credentials, ENTROPY_VALUE, ""), using the library's fixed ENTROPY_VALUE constant rather than a per-request value.
  2. setDecryptedCredentials() first clears UserID and DecryptedPwd, then selects either the default tab separator or a caller-supplied override for parsing the incoming payload.
  3. If EncryptedLogin is empty: the method stops after clearing the fields, leaving them blank rather than attempting a decrypt.
  4. When encrypted input is present, the method decrypts it with DPAPI.Decrypt(EncryptedLogin, ENTROPY_VALUE, ""), splits the result on the chosen separator, and restores UserID and the private password field only when the split produces exactly two non-empty parts.
  5. If the decrypted payload is malformed or yields an unexpected number of parts: the method silently ignores it and leaves the fields blank, without raising an error.

Process flow

The following diagram visualizes this operation's control flow.

flowchart TD
    Start([Credential helper called]) --> Mode{Encrypt or decrypt?}
    Mode -->|Encrypt| Build[Build payload and encrypt]
    Mode -->|Decrypt| Clear[Clear current fields]
    Clear --> Present{Encrypted input present?}
    Present -->|No| EndBlank([Leave fields blank])
    Present -->|Yes| Decrypt[Decrypt and split payload]
    Decrypt --> Parts{Exactly two parts?}
    Parts -->|Yes| Restore[Restore user and password]
    Parts -->|No| EndBlank
    Build --> EndEnc([Return encrypted payload])
    Restore --> EndOk([Fields restored])

Failure and edge-case behavior

  • Encryption always uses the same hard-coded ENTROPY_VALUE constant rather than a value derived from the request, so the encrypted payload's security depends entirely on DPAPI.Encrypt's machine-key scoping.
  • An empty encrypted input leaves the target fields blank instead of raising an error.
  • An unexpected decrypted payload shape (not exactly two parts) is ignored silently rather than surfaced to the caller.

Sources

  • SAIF.Framework.Security\clsSAIFLoginInfo.vb
  • SAIF.Framework.Security\DAPIEncrypt.vb