Skip to content

Generate a system hash

This operation produces the identifier that callers present when requesting a secure configuration setting. It resolves the most plausible calling assembly name, hashes the resulting {systemName}-{systemType} payload with SHA-256, and — unless the caller explicitly asks for the raw value — wraps the digest with a time-based salt so its age can later be validated.

Field Value
Operation ID OP-ENV-011
Trigger Caller needs a system hash
Inputs SystemType, optional explicit systemName
Outputs Salted hash string from ComputeHash or Get, or unsalted hash string from ComputeHashNow
Primary components SystemHashUtil.Get, SystemHashUtil.GetAssembly, SystemHashUtil.ComputeHash, SystemHashUtil.ComputeHashNow, SystemHashUtil.GetHashValue
Entry point SAIF.Framework.Security.EnvironmentApi\Services.Common\SystemHashUtil.cs

Steps

  1. Resolve the source system name when the caller did not supply one explicitly.
  2. Get(SystemType) calls GetAssembly() and uses whichever assembly name that method returns.
  3. GetAssembly() tries Assembly.GetEntryAssembly() first, then GetWebEntryAssembly(), then GetLegacyWebEntryAssembly(), and falls back to Assembly.GetExecutingAssembly() only if every prior candidate is unavailable.
  4. Build the deterministic hash payload as {systemName}-{(int)type}, so the same system and type combination always produces the same input to the hash function.
  5. Encode that payload as Unicode bytes, hash it with SHA-256, and convert the digest to Base64.
  6. If the caller used ComputeHash or Get, pass the Base64 payload to new SaltShaker(DateTime.Now).SaltHash(value) and return the salted token.
  7. If the caller used ComputeHashNow, skip salting entirely and return the direct Base64 hash for scenarios that need an immediate, unsalted value.

Process flow

The following diagram visualizes this operation's control flow.

flowchart TD
    Start([Caller requests system hash]) --> Name[Resolve system name or assembly]
    Name --> Payload[Build systemName-type payload]
    Payload --> Digest[SHA-256 hash and Base64 encode]
    Digest --> Salt{Salt result?}
    Salt -->|Yes| SaltHash[SaltHash with current timestamp]
    Salt -->|No| Raw([Return unsalted hash])
    SaltHash --> End([Return salted hash])

Failure and edge-case behavior

  • GetLegacyWebEntryAssembly() falls back to stack-frame heuristics only when the standard entry-assembly discovery methods return nothing, so its result is best-effort in atypical hosting scenarios.
  • ComputeHashNow intentionally skips the time-based salt wrapper, so its output cannot later be validated for age through Validate system hash lifetime.
  • The salting behavior itself is implemented entirely by the external SAIF.HashUtil package; this operation only supplies the payload being salted.

Sources

  • SAIF.Framework.Security.EnvironmentApi\Services.Common\SystemHashUtil.cs