- 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.
116 lines
5.6 KiB
C#
116 lines
5.6 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace StellaOps.Cryptography;
|
|
|
|
/// <summary>
|
|
/// Interface for HMAC (Hash-based Message Authentication Code) operations with compliance profile support.
|
|
/// </summary>
|
|
public interface ICryptoHmac
|
|
{
|
|
#region Purpose-based methods (preferred for compliance)
|
|
|
|
/// <summary>
|
|
/// Computes an HMAC for the specified purpose using the active compliance profile's algorithm.
|
|
/// </summary>
|
|
/// <param name="key">The secret key.</param>
|
|
/// <param name="data">The data to authenticate.</param>
|
|
/// <param name="purpose">The HMAC purpose from <see cref="HmacPurpose"/>.</param>
|
|
/// <returns>The HMAC bytes.</returns>
|
|
byte[] ComputeHmacForPurpose(ReadOnlySpan<byte> key, ReadOnlySpan<byte> data, string purpose);
|
|
|
|
/// <summary>
|
|
/// Computes an HMAC for the specified purpose and returns it as a lowercase hex string.
|
|
/// </summary>
|
|
/// <param name="key">The secret key.</param>
|
|
/// <param name="data">The data to authenticate.</param>
|
|
/// <param name="purpose">The HMAC purpose from <see cref="HmacPurpose"/>.</param>
|
|
/// <returns>The HMAC as a lowercase hex string.</returns>
|
|
string ComputeHmacHexForPurpose(ReadOnlySpan<byte> key, ReadOnlySpan<byte> data, string purpose);
|
|
|
|
/// <summary>
|
|
/// Computes an HMAC for the specified purpose and returns it as a Base64 string.
|
|
/// </summary>
|
|
/// <param name="key">The secret key.</param>
|
|
/// <param name="data">The data to authenticate.</param>
|
|
/// <param name="purpose">The HMAC purpose from <see cref="HmacPurpose"/>.</param>
|
|
/// <returns>The HMAC as a Base64 string.</returns>
|
|
string ComputeHmacBase64ForPurpose(ReadOnlySpan<byte> key, ReadOnlySpan<byte> data, string purpose);
|
|
|
|
/// <summary>
|
|
/// Computes an HMAC for the specified purpose from a stream asynchronously.
|
|
/// </summary>
|
|
/// <param name="key">The secret key.</param>
|
|
/// <param name="stream">The stream to authenticate.</param>
|
|
/// <param name="purpose">The HMAC purpose from <see cref="HmacPurpose"/>.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
/// <returns>The HMAC bytes.</returns>
|
|
ValueTask<byte[]> ComputeHmacForPurposeAsync(ReadOnlyMemory<byte> key, Stream stream, string purpose, CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Computes an HMAC for the specified purpose from a stream and returns it as a lowercase hex string.
|
|
/// </summary>
|
|
/// <param name="key">The secret key.</param>
|
|
/// <param name="stream">The stream to authenticate.</param>
|
|
/// <param name="purpose">The HMAC purpose from <see cref="HmacPurpose"/>.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
/// <returns>The HMAC as a lowercase hex string.</returns>
|
|
ValueTask<string> ComputeHmacHexForPurposeAsync(ReadOnlyMemory<byte> key, Stream stream, string purpose, CancellationToken cancellationToken = default);
|
|
|
|
#endregion
|
|
|
|
#region Verification methods (constant-time comparison)
|
|
|
|
/// <summary>
|
|
/// Verifies an HMAC for the specified purpose using constant-time comparison.
|
|
/// </summary>
|
|
/// <param name="key">The secret key.</param>
|
|
/// <param name="data">The data that was authenticated.</param>
|
|
/// <param name="expectedHmac">The expected HMAC value.</param>
|
|
/// <param name="purpose">The HMAC purpose from <see cref="HmacPurpose"/>.</param>
|
|
/// <returns>True if the HMAC matches; otherwise, false.</returns>
|
|
bool VerifyHmacForPurpose(ReadOnlySpan<byte> key, ReadOnlySpan<byte> data, ReadOnlySpan<byte> expectedHmac, string purpose);
|
|
|
|
/// <summary>
|
|
/// Verifies an HMAC for the specified purpose using constant-time comparison (hex format).
|
|
/// </summary>
|
|
/// <param name="key">The secret key.</param>
|
|
/// <param name="data">The data that was authenticated.</param>
|
|
/// <param name="expectedHmacHex">The expected HMAC value as a hex string.</param>
|
|
/// <param name="purpose">The HMAC purpose from <see cref="HmacPurpose"/>.</param>
|
|
/// <returns>True if the HMAC matches; otherwise, false.</returns>
|
|
bool VerifyHmacHexForPurpose(ReadOnlySpan<byte> key, ReadOnlySpan<byte> data, string expectedHmacHex, string purpose);
|
|
|
|
/// <summary>
|
|
/// Verifies an HMAC for the specified purpose using constant-time comparison (Base64 format).
|
|
/// </summary>
|
|
/// <param name="key">The secret key.</param>
|
|
/// <param name="data">The data that was authenticated.</param>
|
|
/// <param name="expectedHmacBase64">The expected HMAC value as a Base64 string.</param>
|
|
/// <param name="purpose">The HMAC purpose from <see cref="HmacPurpose"/>.</param>
|
|
/// <returns>True if the HMAC matches; otherwise, false.</returns>
|
|
bool VerifyHmacBase64ForPurpose(ReadOnlySpan<byte> key, ReadOnlySpan<byte> data, string expectedHmacBase64, string purpose);
|
|
|
|
#endregion
|
|
|
|
#region Metadata methods
|
|
|
|
/// <summary>
|
|
/// Gets the algorithm that will be used for the specified purpose based on the active compliance profile.
|
|
/// </summary>
|
|
/// <param name="purpose">The HMAC purpose from <see cref="HmacPurpose"/>.</param>
|
|
/// <returns>The algorithm identifier (e.g., "HMAC-SHA256", "HMAC-GOST3411").</returns>
|
|
string GetAlgorithmForPurpose(string purpose);
|
|
|
|
/// <summary>
|
|
/// Gets the expected HMAC output length in bytes for the specified purpose.
|
|
/// </summary>
|
|
/// <param name="purpose">The HMAC purpose from <see cref="HmacPurpose"/>.</param>
|
|
/// <returns>The output length in bytes.</returns>
|
|
int GetOutputLengthForPurpose(string purpose);
|
|
|
|
#endregion
|
|
}
|