feat: Implement DefaultCryptoHmac for compliance-aware HMAC operations

- Added DefaultCryptoHmac class implementing ICryptoHmac interface.
- Introduced purpose-based HMAC computation methods.
- Implemented verification methods for HMACs with constant-time comparison.
- Created HmacAlgorithms and HmacPurpose classes for well-known identifiers.
- Added compliance profile support for HMAC algorithms.
- Included asynchronous methods for HMAC computation from streams.
This commit is contained in:
StellaOps Bot
2025-12-06 00:41:04 +02:00
parent 43c281a8b2
commit f0662dd45f
362 changed files with 8441 additions and 22338 deletions

View File

@@ -1,6 +1,6 @@
using System.Security.Cryptography;
using System.Text;
using Microsoft.Extensions.Options;
using StellaOps.Cryptography;
using StellaOps.Findings.Ledger.Options;
namespace StellaOps.Findings.Ledger.Services;
@@ -13,11 +13,13 @@ public interface IAttachmentUrlSigner
public sealed class AttachmentUrlSigner : IAttachmentUrlSigner
{
private readonly LedgerServiceOptions.AttachmentsOptions options;
private readonly ICryptoHmac _cryptoHmac;
private readonly byte[] secretKey;
public AttachmentUrlSigner(IOptions<LedgerServiceOptions> optionsAccessor)
public AttachmentUrlSigner(IOptions<LedgerServiceOptions> optionsAccessor, ICryptoHmac cryptoHmac)
{
ArgumentNullException.ThrowIfNull(optionsAccessor);
_cryptoHmac = cryptoHmac ?? throw new ArgumentNullException(nameof(cryptoHmac));
options = optionsAccessor.Value.Attachments;
secretKey = Encoding.UTF8.GetBytes(options.SignedUrlSecret ?? string.Empty);
if (secretKey.Length == 0)
@@ -33,8 +35,9 @@ public sealed class AttachmentUrlSigner : IAttachmentUrlSigner
var expires = now.Add(lifetime);
var expiresUnix = expires.ToUnixTimeSeconds();
var payload = $"{attachmentId}|{expiresUnix}";
using var hmac = new HMACSHA256(secretKey);
var signature = Base64UrlEncode(hmac.ComputeHash(Encoding.UTF8.GetBytes(payload)));
var payloadBytes = Encoding.UTF8.GetBytes(payload);
var signatureBytes = _cryptoHmac.ComputeHmacForPurpose(secretKey, payloadBytes, HmacPurpose.Authentication);
var signature = Base64UrlEncode(signatureBytes);
var baseUrl = options.SignedUrlBase.TrimEnd('/');
var url = $"{baseUrl}/{Uri.EscapeDataString(attachmentId)}?exp={expiresUnix}&sig={signature}";

View File

@@ -18,11 +18,11 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0-rc.2.25502.107" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.0-rc.2.25502.107" />
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.0-rc.2.25502.107" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="10.0.0-rc.2.25502.107" />
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.0-rc.2.25502.107" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.0" />
<PackageReference Include="Npgsql" Version="7.0.7" />
</ItemGroup>