|
| 1 | +using System; |
| 2 | +using System.Security.Cryptography; |
| 3 | +using Microsoft.IdentityModel.Tokens; |
| 4 | + |
| 5 | +namespace NorthwindCRUD.Providers; |
| 6 | + |
| 7 | +/// <summary> |
| 8 | +/// Custom Crypto Provider for HMAC-SHA512 algorithm which ignores the minimum key size requirement to allow the previous keys to work. |
| 9 | +/// </summary> |
| 10 | +public class HmacSha512CryptoProvider : ICryptoProvider |
| 11 | +{ |
| 12 | + public object Create(string algorithm, params object[] args) |
| 13 | + { |
| 14 | + if (!IsSupportedAlgorithm(algorithm, args)) |
| 15 | + { |
| 16 | + throw new NotSupportedException("Algorithm not supported."); |
| 17 | + } |
| 18 | + |
| 19 | + var keyBytes = (args != null && args.Length > 0 && args[0] is byte[] bytes ? bytes : null) |
| 20 | + ?? throw new ArgumentNullException(nameof(args), "Key bytes must be provided as the first argument."); |
| 21 | + |
| 22 | + if (keyBytes.Length < 28) |
| 23 | + { |
| 24 | + throw new CryptographicException("The key size is too small for HMAC-SHA512. Minimum key size is 28 bytes."); |
| 25 | + } |
| 26 | + |
| 27 | + return new HMACSHA512(keyBytes); |
| 28 | + } |
| 29 | + |
| 30 | + // Indicate supported algorithms |
| 31 | + public bool IsSupportedAlgorithm(string algorithm, params object[] args) |
| 32 | + { |
| 33 | + if (string.IsNullOrEmpty(algorithm)) |
| 34 | + { |
| 35 | + return false; |
| 36 | + } |
| 37 | + |
| 38 | + var keyBytes = args != null && args.Length > 0 && args[0] is byte[] bytes ? bytes : null; |
| 39 | + if (keyBytes == null || keyBytes.Length == 0) |
| 40 | + { |
| 41 | + // We only care about handling keybytes for HmacSha512 |
| 42 | + return false; |
| 43 | + } |
| 44 | + |
| 45 | + // Accept common HMAC-SHA512 names (including the constant) |
| 46 | + return string.Equals(algorithm, SecurityAlgorithms.HmacSha512, StringComparison.OrdinalIgnoreCase) |
| 47 | + || algorithm.Contains("HmacSha512", StringComparison.OrdinalIgnoreCase); |
| 48 | + } |
| 49 | + |
| 50 | + // Release/dispose a created crypto instance |
| 51 | + public void Release(object cryptoInstance) |
| 52 | + { |
| 53 | + if (cryptoInstance is IDisposable disposable) |
| 54 | + { |
| 55 | + disposable.Dispose(); |
| 56 | + } |
| 57 | + } |
| 58 | +} |
0 commit comments