/* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ using Amazon.Runtime; using Amazon.Util.Internal; using System; using System.Globalization; using System.Security.Cryptography; using System.Text; namespace Amazon.Util { public static partial class CryptoUtilFactory { partial class CryptoUtil : ICryptoUtil { /// /// Computes a hash-based message authentication code /// /// Input to compute the hash code for /// Signing key /// Hashing algorithm to use /// Computed hash code in base-64 public string HMACSign(byte[] data, string key, SigningAlgorithm algorithmName) { if (String.IsNullOrEmpty(key)) throw new ArgumentNullException("key", "Please specify a Secret Signing Key."); if (data == null || data.Length == 0) throw new ArgumentNullException("data", "Please specify data to sign."); KeyedHashAlgorithm algorithm = KeyedHashAlgorithm.Create(algorithmName.ToString().ToUpper(CultureInfo.InvariantCulture)); if (null == algorithm) throw new InvalidOperationException("Please specify a KeyedHashAlgorithm to use."); try { algorithm.Key = Encoding.UTF8.GetBytes(key); byte[] bytes = algorithm.ComputeHash(data); return Convert.ToBase64String(bytes); } finally { algorithm.Clear(); } } /// /// Computes a hash-based message authentication code /// /// Input to compute the hash code for /// Signing key /// Hashing algorithm to use /// Computed hash code in bytes public byte[] HMACSignBinary(byte[] data, byte[] key, SigningAlgorithm algorithmName) { if (key == null || key.Length == 0) throw new ArgumentNullException("key", "Please specify a Secret Signing Key."); if (data == null || data.Length == 0) throw new ArgumentNullException("data", "Please specify data to sign."); KeyedHashAlgorithm algorithm = KeyedHashAlgorithm.Create(algorithmName.ToString().ToUpper(CultureInfo.InvariantCulture)); if (null == algorithm) throw new InvalidOperationException("Please specify a KeyedHashAlgorithm to use."); try { algorithm.Key = key; byte[] bytes = algorithm.ComputeHash(data); return bytes; } finally { algorithm.Clear(); } } [ThreadStatic] private static HashAlgorithm _hashAlgorithm = null; private static HashAlgorithm SHA256HashAlgorithmInstance { get { if (null == _hashAlgorithm) { _hashAlgorithm = CreateSHA256Instance(); } return _hashAlgorithm; } } internal static HashAlgorithm CreateSHA256Instance() { try { return HashAlgorithm.Create("SHA-256"); } catch (Exception) // Managed Hash Provider is not FIPS compliant. { return new SHA256CryptoServiceProvider(); } } } } }