Change SHA256 algorithm to work on FIPS-compliant machines.

#5103
This commit is contained in:
N. Taylor Mullen 2016-08-09 11:44:52 -07:00
parent 6e5fd4f89f
commit edb5baf81c
3 changed files with 47 additions and 8 deletions

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.TagHelpers.Internal;
using Microsoft.AspNetCore.Razor.TagHelpers; using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Internal; using Microsoft.Extensions.Internal;
@ -151,10 +152,10 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers.Cache
// The key is typically too long to be useful, so we use a cryptographic hash // The key is typically too long to be useful, so we use a cryptographic hash
// as the actual key (better randomization and key distribution, so small vary // as the actual key (better randomization and key distribution, so small vary
// values will generate dramatically different keys). // values will generate dramatically different keys).
using (var sha = SHA256.Create()) using (var sha256 = CryptographyAlgorithms.CreateSHA256())
{ {
var contentBytes = Encoding.UTF8.GetBytes(key); var contentBytes = Encoding.UTF8.GetBytes(key);
var hashedBytes = sha.ComputeHash(contentBytes); var hashedBytes = sha256.ComputeHash(contentBytes);
return Convert.ToBase64String(hashedBytes); return Convert.ToBase64String(hashedBytes);
} }
} }
@ -183,14 +184,14 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers.Cache
AreSame(_headers, other._headers) && AreSame(_headers, other._headers) &&
AreSame(_queries, other._queries) && AreSame(_queries, other._queries) &&
AreSame(_routeValues, other._routeValues) && AreSame(_routeValues, other._routeValues) &&
_varyByUser == other._varyByUser && _varyByUser == other._varyByUser &&
(!_varyByUser || string.Equals(other._username, _username, StringComparison.Ordinal)); (!_varyByUser || string.Equals(other._username, _username, StringComparison.Ordinal));
} }
/// <inheritdoc /> /// <inheritdoc />
public override int GetHashCode() public override int GetHashCode()
{ {
// The hashcode is intentionally not using the computed // The hashcode is intentionally not using the computed
// stringified key in order to prevent string allocations // stringified key in order to prevent string allocations
// in the common case where it's not explicitly required. // in the common case where it's not explicitly required.
@ -219,7 +220,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers.Cache
return _hashcode.Value; return _hashcode.Value;
} }
private static IList<KeyValuePair<string, string>> ExtractCollection<TSourceCollection>(string keys, TSourceCollection collection, Func<TSourceCollection, string, string> accessor) private static IList<KeyValuePair<string, string>> ExtractCollection<TSourceCollection>(string keys, TSourceCollection collection, Func<TSourceCollection, string, string> accessor)
{ {
if (string.IsNullOrEmpty(keys)) if (string.IsNullOrEmpty(keys))
@ -244,7 +245,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers.Cache
return result; return result;
} }
private static void AddStringCollection( private static void AddStringCollection(
StringBuilder builder, StringBuilder builder,
string collectionName, string collectionName,
@ -275,7 +276,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers.Cache
.Append(CacheKeyTokenSeparator) .Append(CacheKeyTokenSeparator)
.Append(item.Value); .Append(item.Value);
} }
builder.Append(")"); builder.Append(")");
} }

View File

@ -0,0 +1,38 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Security.Cryptography;
namespace Microsoft.AspNetCore.Mvc.TagHelpers.Internal
{
public static class CryptographyAlgorithms
{
#if NETSTANDARD1_6
public static SHA256 CreateSHA256()
{
var sha256 = SHA256.Create();
return sha256;
}
#else
public static SHA256 CreateSHA256()
{
SHA256 sha256;
try
{
sha256 = SHA256.Create();
}
// SHA256.Create is documented to throw this exception on FIPS compliant machines.
// See: https://msdn.microsoft.com/en-us/library/z08hz7ad%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
catch (System.Reflection.TargetInvocationException)
{
// Fallback to a FIPS compliant SHA256 algorithm.
sha256 = new SHA256CryptoServiceProvider();
}
return sha256;
}
#endif
}
}

View File

@ -111,7 +111,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers.Internal
private static string GetHashForFile(IFileInfo fileInfo) private static string GetHashForFile(IFileInfo fileInfo)
{ {
using (var sha256 = SHA256.Create()) using (var sha256 = CryptographyAlgorithms.CreateSHA256())
{ {
using (var readStream = fileInfo.CreateReadStream()) using (var readStream = fileInfo.CreateReadStream())
{ {