/// <summary> /// Creates a HMAC signature from the supplied data. /// </summary> /// <param name="signatureData">The data to create a signature from.</param> /// <returns>The signature as a <see cref="string"/>.</returns> /// <exception cref="ArgumentNullException">The signature data is null.</exception> /// <exception cref="ArgumentException">The key from the signature data is null or empty.</exception> /// <exception cref="HmacConfigurationException">One or more of the configuration parameters are invalid.</exception> public virtual string CreateSignature(HmacSignatureData signatureData) { if (signatureData == null) { throw new ArgumentNullException(nameof(signatureData), "The signature data cannot be null."); } if (HmacConfiguration.SignatureEncoding == null) { throw new HmacConfigurationException("The character encoding cannot be null."); } if (string.IsNullOrEmpty(signatureData.Key)) { throw new ArgumentException("The key cannot be null or empty.", nameof(signatureData)); } string headerString = signatureData.Headers != null ? CreateCanonicalizedHeadersString(signatureData.Headers) : null; string requestUri = CreateCanonicalizedUriString(signatureData.RequestUri); string representation = string.Join( HmacConfiguration.SignatureDataSeparator ?? string.Empty, signatureData.HttpMethod?.Trim().ToUpperInvariant(), signatureData.ContentMd5?.Trim(), signatureData.ContentType?.Trim().ToLowerInvariant(), signatureData.Date?.Trim(), signatureData.Username, headerString, requestUri); byte[] keyBytes = SignatureEncoding.GetBytes(signatureData.Key); byte[] representationBytes = SignatureEncoding.GetBytes(representation); HMAC hmac; try { hmac = HMAC.Create(HmacConfiguration.HmacAlgorithm); } catch (Exception ex) { throw new HmacConfigurationException("The HMAC implemenation instance could not be created from the configured algorithm name.", ex); } hmac.Key = keyBytes; byte[] hash = hmac.ComputeHash(representationBytes); return(Convert.ToBase64String(hash)); }
private HmacSignatureData GetSignatureDataFromHttpRequest(HmacRequestWrapper request) { HmacSignatureData signatureData = new HmacSignatureData { HttpMethod = request.Method.ToUpperInvariant() }; // Get the request URI if configured if (HmacConfiguration.SignRequestUri) { signatureData.RequestUri = request.RequestUri.AbsoluteUri; } // Get the request date if a maximum request age is configured if (HmacConfiguration.MaxRequestAge.HasValue && request.Date.HasValue) { DateTime date = request.Date.Value.UtcDateTime; signatureData.Date = date.ToString(HmacConstants.DateHeaderFormat, DateHeaderCulture); } // Get the content type and, if configured, the MD5 body hash signatureData.ContentType = request.ContentType; if (HmacConfiguration.ValidateContentMd5) { signatureData.ContentMd5 = request.ContentMd5; } // Get the username if (!string.IsNullOrEmpty(HmacConfiguration.UserHeaderName)) { signatureData.Username = request.Headers[HmacConfiguration.UserHeaderName]; } // Get the key try { signatureData.Key = HmacKeyRepository.GetHmacKeyForUsername(signatureData.Username); } catch (Exception ex) { throw new HmacKeyRepositoryException("Failed to retrieve the key.", ex); } // Add full additional headers if (HmacConfiguration.Headers != null && HmacConfiguration.Headers.Count > 0) { signatureData.Headers = new NameValueCollection(); foreach (string headerName in HmacConfiguration.Headers.Distinct(StringComparer.OrdinalIgnoreCase)) { if (string.IsNullOrEmpty(headerName)) { continue; } IList <string> headerValues = request.Headers.GetValues(headerName); if (headerValues == null || headerValues.Count == 0) { continue; } foreach (string headerValue in headerValues) { signatureData.Headers.Add(headerName, headerValue); } } } return(signatureData); }