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:
@@ -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}";
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user