private async Task <RSA> GetRSAProviderFromCertAsync(RequestSignature reqSignature)
        {
            _ = reqSignature ?? throw new ArgumentNullException(nameof(reqSignature));
            _ = reqSignature.KeyId ?? throw new InvalidOperationException($"{nameof(reqSignature.KeyId)} is null");

            var certUri   = new Uri($"{_config.SmartThingsCertUriRoot}{reqSignature.KeyId}");
            var certBytes = await _httpClient.GetByteArrayAsync(certUri).ConfigureAwait(false);

            if (certBytes?.Length > 0)
            {
                using X509Certificate2 cert = new(certBytes);
                return(cert.GetRSAPublicKey());
            }

            return(null);
        }
        public async Task <bool> VerifySignedRequestAsync(HttpRequest request)
        {
            _ = request ?? throw new ArgumentNullException(nameof(request));

            _logger.LogDebug($"Verifying sign request: {request.Path}");

            var reqSignature = RequestSignature.ParseFromHeaderVal(request.Headers["Authorization"].FirstOrDefault());

            var hash = GetHash(reqSignature, request);
            var data = Convert.FromBase64String(reqSignature.Signature);

            var publicKeyProvider = await GetRSAProviderFromCertAsync(reqSignature).ConfigureAwait(false);

            if (publicKeyProvider != null)
            {
                return(publicKeyProvider.VerifyData(hash, data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1));
            }
            else
            {
                return(false);
            }
        }
        private static byte[] GetHash(RequestSignature reqSignature, HttpRequest request)
        {
            var siginingString = new StringBuilder();
            int headerCount    = reqSignature.Headers.Count();

            for (int i = 0; i < headerCount; i++)
            {
                var h = reqSignature.Headers.ElementAt(i);

                if (h == "(request-target)")
                {
                    siginingString.Append("(request-target): ");
                    siginingString.Append(request.Method.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
                    siginingString.Append(' ');
                    siginingString.Append(request.Path);
                }
                else
                {
                    if (!request.Headers.TryGetValue(h, out StringValues vals))
                    {
                        throw new InvalidOperationException($"Missing {h} header per the auth header!");
                    }

                    siginingString.Append(h);
                    siginingString.Append(": ");
                    siginingString.Append(vals.FirstOrDefault());
                }
                if (i < (headerCount - 1))
                {
                    siginingString.Append('\n');
                }
            }

            var val      = siginingString.ToString();
            var encoding = UTF8Encoding.UTF8;

            return(encoding.GetBytes(val));
        }