Masterly.Hash.Integrity 2.0.0

dotnet add package Masterly.Hash.Integrity --version 2.0.0
                    
NuGet\Install-Package Masterly.Hash.Integrity -Version 2.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Masterly.Hash.Integrity" Version="2.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Masterly.Hash.Integrity" Version="2.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Masterly.Hash.Integrity" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Masterly.Hash.Integrity --version 2.0.0
                    
#r "nuget: Masterly.Hash.Integrity, 2.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Masterly.Hash.Integrity@2.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Masterly.Hash.Integrity&version=2.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Masterly.Hash.Integrity&version=2.0.0
                    
Install as a Cake Tool

Masterly.Hash.Integrity

Masterly.Hash: password hashing you can't get wrong.

Tamper evidence for files and records, built on Masterly.Hash:

  • Content hashes: sha256:<hex>, sha384:, sha512: and keyed hmac-sha256:<keyId>:<hex>, computed from streams in pooled buffers. Verification is constant-time.
  • Merkle trees (RFC 9162 / Certificate Transparency v2) with inclusion and consistency proofs.
  • Hash-chain audit logs: every entry covers the previous one. With an HMAC key, someone who can write the database still cannot forge the chain.
  • Directory manifests: per-file hashes plus a Merkle root. Verification reports added, removed and modified files. Manifests serialize to JSON.

Targets net8.0. Uses only the .NET cryptography APIs (no custom primitives).

Install

dotnet add package Masterly.Hash.Integrity

Quickstart

using Masterly.Hash.Integrity;

// Content hashes
ContentHash hash = await ContentHasher.ComputeFileAsync("release.zip");   // sha256:9f86d0...
string stored = hash.ToString();
bool ok = await ContentHasher.VerifyFileAsync("release.zip", ContentHash.Parse(stored));

// Keyed (HMAC) hashes: the key never leaves your secret store
var mac = ContentHashAlgorithm.HmacSha256("k2026", key32Bytes);
ContentHash tag = ContentHasher.Compute(data, mac);                     // hmac-sha256:k2026:...

// Merkle trees (RFC 9162)
MerkleTree tree = MerkleTree.Build(records);
IReadOnlyList<byte[]> proof = tree.GetInclusionProof(5);
bool included = MerkleTree.VerifyInclusion(records[5], 5, tree.Size, proof, tree.Root);
IReadOnlyList<byte[]> consistency = tree.GetConsistencyProof(oldSize);
bool appendOnly = MerkleTree.VerifyConsistency(oldSize, tree.Size, oldRoot, tree.Root, consistency);

// Hash-chain audit log
var log = new HashChainLog(ContentHashAlgorithm.HmacSha256("audit-1", auditKey));
log.Append(Encoding.UTF8.GetBytes("user 42 changed role to admin"));
HashChainCheckpoint head = log.Head!;          // save this somewhere else, refresh it periodically
// Later (the chain may have grown since): the entry at head.Sequence must still be there, unchanged.
HashChainVerificationResult result = log.Verify(loadedEntries, head);
if (!result.IsValid)
    Console.WriteLine($"{result.Failure} at index {result.FirstBrokenIndex}");   // Gap, Reorder, HashMismatch, ...

// Directory manifests
DirectoryManifest manifest = await DirectoryManifest.CreateAsync("/srv/app");
File.WriteAllText("manifest.json", manifest.ToJson());
ContentHash trustedRoot = manifest.Root;       // keep this out of the attacker's reach
DirectoryManifestDiff diff = await DirectoryManifest.VerifyAsync(
    "/srv/app", DirectoryManifest.FromJson(json), trustedRoot, algorithm: null, options: null);
// diff.Added, diff.Removed, diff.Modified, diff.ManifestIntact, diff.IsMatch

If you persist the chain in a database, use HashChain.CreateNext(previousEntry, payload, algorithm) and HashChain.Verify(entries, algorithm, anchor, expectedHead).

Encodings

  • Hash chain entry: H(field("masterly-hash-chain/v1") || field(algorithmId) || u64(seq) || field(prevHash) || field(payload)). Here u64 is 8-byte big-endian and field(x) = u64(len(x)) || x. Genesis previous hash: all zeros.
  • Manifest leaf: field(tag) || field(utf8(path)) || u64(length) || field(digest), with tag masterly-manifest/v1 for files and masterly-manifest/v1:link for links (whose digest covers the UTF-8 link target text). Leaves are sorted by ordinal path, and the tree is hashed as in RFC 9162.

Security notes

  • A plain hash only detects accidental or outside changes. An attacker who can rewrite the data can also rewrite plain hashes. Use an HMAC algorithm with a key kept outside the data store, and/or keep the root or chain head somewhere the attacker cannot write (another system, a signed receipt, a transparency log).
  • HashChain.Verify detects gaps, reordering, duplicates, edited entries and broken links. Pass a trusted head checkpoint to also detect truncation and rewritten history up to that checkpoint; the chain may keep growing past it. Entries after the newest checkpoint are protected only by the links (and the key, when keyed).
  • A manifest's root only detects accidental or inconsistent edits when the algorithm is unkeyed: anyone can recompute it. Pass a trusted copy of the root to VerifyAsync/Compare, or use an HMAC algorithm.
  • Manifest verification walks the directory and never opens paths taken from the manifest. Symbolic links, junctions and other reparse points are not followed by default; each is recorded as a link entry holding the hash of its target text, so planting, removing or retargeting a link is reported. With FollowReparsePoints = true, loops back to an ancestor and broken links are recorded as links instead of being followed.
  • The walk fails closed: a non-empty directory deeper than MaxDepth (64) or more than MaxEntries (1,000,000) entries raises IOException instead of silently leaving files out. Zero-length files are recorded as empty without being opened, so FIFOs, sockets and device nodes cannot block or flood the walk.
  • Verifiers return false or a failure result, and do not throw, for malformed stored values and for a stored algorithm or key id that differs from the one supplied (treat that as tampering, or pick the key by KeyId during rotation). Manifest verification can still throw IOException for file system errors. Proof lengths are capped.
  • The HMAC algorithm's identity covers its name and key id, never the key material. ToString() never prints keys or payloads.
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Masterly.Hash.Integrity:

Package Downloads
Masterly.Hash.Integrity.Blake3

BLAKE3 (plain and keyed) for Masterly.Hash.Integrity content hashes, Merkle trees, hash chains and directory manifests, using the fully managed SIMD Blake3 package.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.0 84 11/3/2026