diff --git a/src/Antiforgery/src/Internal/AntiforgeryOptionsSetup.cs b/src/Antiforgery/src/Internal/AntiforgeryOptionsSetup.cs index 0227068130..74a591698e 100644 --- a/src/Antiforgery/src/Internal/AntiforgeryOptionsSetup.cs +++ b/src/Antiforgery/src/Internal/AntiforgeryOptionsSetup.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Linq; +using System.Security.Cryptography; using System.Text; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.WebUtilities; @@ -35,12 +35,8 @@ namespace Microsoft.AspNetCore.Antiforgery private static string ComputeCookieName(string applicationId) { - using (var sha256 = CryptographyAlgorithms.CreateSHA256()) - { - var hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(applicationId)); - var subHash = hash.Take(8).ToArray(); - return WebEncoders.Base64UrlEncode(subHash); - } + byte[] fullHash = SHA256.HashData(Encoding.UTF8.GetBytes(applicationId)); + return WebEncoders.Base64UrlEncode(fullHash, 0, 8); } } } diff --git a/src/Antiforgery/src/Internal/AntiforgerySerializationContext.cs b/src/Antiforgery/src/Internal/AntiforgerySerializationContext.cs index 342d1d8fb4..19609e43c7 100644 --- a/src/Antiforgery/src/Internal/AntiforgerySerializationContext.cs +++ b/src/Antiforgery/src/Internal/AntiforgerySerializationContext.cs @@ -27,7 +27,6 @@ namespace Microsoft.AspNetCore.Antiforgery private MemoryStream? _stream; private BinaryReader? _reader; private BinaryWriter? _writer; - private SHA256? _sha256; public MemoryStream Stream { @@ -82,23 +81,6 @@ namespace Microsoft.AspNetCore.Antiforgery } } - public SHA256 Sha256 - { - get - { - if (_sha256 == null) - { - _sha256 = CryptographyAlgorithms.CreateSHA256(); - } - - return _sha256; - } - private set - { - _sha256 = value; - } - } - public char[] GetChars(int count) { if (_chars == null || _chars.Length < count) diff --git a/src/Antiforgery/src/Internal/CryptographyAlgorithms.cs b/src/Antiforgery/src/Internal/CryptographyAlgorithms.cs deleted file mode 100644 index 936b93f0c6..0000000000 --- a/src/Antiforgery/src/Internal/CryptographyAlgorithms.cs +++ /dev/null @@ -1,25 +0,0 @@ -// 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.Antiforgery -{ - internal static class CryptographyAlgorithms - { - public static SHA256 CreateSHA256() - { - try - { - return 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. - return new SHA256CryptoServiceProvider(); - } - } - } -} diff --git a/src/Antiforgery/src/Internal/DefaultClaimUidExtractor.cs b/src/Antiforgery/src/Internal/DefaultClaimUidExtractor.cs index 3df55b523f..c8d1e195fc 100644 --- a/src/Antiforgery/src/Internal/DefaultClaimUidExtractor.cs +++ b/src/Antiforgery/src/Internal/DefaultClaimUidExtractor.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Security.Claims; +using System.Security.Cryptography; using Microsoft.Extensions.ObjectPool; namespace Microsoft.AspNetCore.Antiforgery @@ -134,9 +135,13 @@ namespace Microsoft.AspNetCore.Antiforgery writer.Flush(); - var sha256 = serializationContext.Sha256; - var stream = serializationContext.Stream; - var bytes = sha256.ComputeHash(stream.ToArray(), 0, checked((int)stream.Length)); + bool success = serializationContext.Stream.TryGetBuffer(out ArraySegment buffer); + if (!success) + { + throw new InvalidOperationException(); + } + + var bytes = SHA256.HashData(buffer); return bytes; } diff --git a/src/Middleware/WebSockets/src/HandshakeHelpers.cs b/src/Middleware/WebSockets/src/HandshakeHelpers.cs index 64e6c435da..84f4642dd8 100644 --- a/src/Middleware/WebSockets/src/HandshakeHelpers.cs +++ b/src/Middleware/WebSockets/src/HandshakeHelpers.cs @@ -110,23 +110,20 @@ namespace Microsoft.AspNetCore.WebSockets // this concatenated value to obtain a 20-byte value and base64-encoding" // https://tools.ietf.org/html/rfc6455#section-4.2.2 - using (var algorithm = SHA1.Create()) + // requestKey is already verified to be small (24 bytes) by 'IsRequestKeyValid()' and everything is 1:1 mapping to UTF8 bytes + // so this can be hardcoded to 60 bytes for the requestKey + static websocket string + Span mergedBytes = stackalloc byte[60]; + Encoding.UTF8.GetBytes(requestKey, mergedBytes); + EncodedWebSocketKey.CopyTo(mergedBytes.Slice(24)); + + Span hashedBytes = stackalloc byte[20]; + var written = SHA1.HashData(mergedBytes, hashedBytes); + if (written != 20) { - // requestKey is already verified to be small (24 bytes) by 'IsRequestKeyValid()' and everything is 1:1 mapping to UTF8 bytes - // so this can be hardcoded to 60 bytes for the requestKey + static websocket string - Span mergedBytes = stackalloc byte[60]; - Encoding.UTF8.GetBytes(requestKey, mergedBytes); - EncodedWebSocketKey.CopyTo(mergedBytes.Slice(24)); - - Span hashedBytes = stackalloc byte[20]; - var success = algorithm.TryComputeHash(mergedBytes, hashedBytes, out var written); - if (!success || written != 20) - { - throw new InvalidOperationException("Could not compute the hash for the 'Sec-WebSocket-Accept' header."); - } - - return Convert.ToBase64String(hashedBytes); + throw new InvalidOperationException("Could not compute the hash for the 'Sec-WebSocket-Accept' header."); } + + return Convert.ToBase64String(hashedBytes); } } } diff --git a/src/Mvc/Mvc.Razor/src/Infrastructure/CryptographyAlgorithms.cs b/src/Mvc/Mvc.Razor/src/Infrastructure/CryptographyAlgorithms.cs deleted file mode 100644 index 2442315477..0000000000 --- a/src/Mvc/Mvc.Razor/src/Infrastructure/CryptographyAlgorithms.cs +++ /dev/null @@ -1,25 +0,0 @@ -// 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.Razor.Infrastructure -{ - internal static class CryptographyAlgorithms - { - public static SHA256 CreateSHA256() - { - try - { - return 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. - return new SHA256CryptoServiceProvider(); - } - } - } -} diff --git a/src/Mvc/Mvc.Razor/src/Infrastructure/DefaultFileVersionProvider.cs b/src/Mvc/Mvc.Razor/src/Infrastructure/DefaultFileVersionProvider.cs index a58bf6252d..d179e3e12a 100644 --- a/src/Mvc/Mvc.Razor/src/Infrastructure/DefaultFileVersionProvider.cs +++ b/src/Mvc/Mvc.Razor/src/Infrastructure/DefaultFileVersionProvider.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Security.Cryptography; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.ViewFeatures; @@ -97,7 +98,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Infrastructure private static string GetHashForFile(IFileInfo fileInfo) { - using (var sha256 = CryptographyAlgorithms.CreateSHA256()) + using (var sha256 = SHA256.Create()) { using (var readStream = fileInfo.CreateReadStream()) { @@ -107,4 +108,4 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Infrastructure } } } -} \ No newline at end of file +} diff --git a/src/Mvc/Mvc.TagHelpers/src/Cache/CacheTagKey.cs b/src/Mvc/Mvc.TagHelpers/src/Cache/CacheTagKey.cs index f527f8f55f..1cfc3a726e 100644 --- a/src/Mvc/Mvc.TagHelpers/src/Cache/CacheTagKey.cs +++ b/src/Mvc/Mvc.TagHelpers/src/Cache/CacheTagKey.cs @@ -4,12 +4,11 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Security.Cryptography; using System.Text; using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc.Razor.Infrastructure; using Microsoft.AspNetCore.Razor.TagHelpers; using Microsoft.AspNetCore.Routing; -using Microsoft.Extensions.Internal; using Microsoft.Extensions.Primitives; namespace Microsoft.AspNetCore.Mvc.TagHelpers.Cache @@ -180,12 +179,9 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers.Cache // 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 // values will generate dramatically different keys). - using (var sha256 = CryptographyAlgorithms.CreateSHA256()) - { - var contentBytes = Encoding.UTF8.GetBytes(key); - var hashedBytes = sha256.ComputeHash(contentBytes); - return Convert.ToBase64String(hashedBytes); - } + var contentBytes = Encoding.UTF8.GetBytes(key); + var hashedBytes = SHA256.HashData(contentBytes); + return Convert.ToBase64String(hashedBytes); } /// diff --git a/src/Security/Authentication/MicrosoftAccount/src/MicrosoftAccountHandler.cs b/src/Security/Authentication/MicrosoftAccount/src/MicrosoftAccountHandler.cs index 043900b1aa..d16a8c1301 100644 --- a/src/Security/Authentication/MicrosoftAccount/src/MicrosoftAccountHandler.cs +++ b/src/Security/Authentication/MicrosoftAccount/src/MicrosoftAccountHandler.cs @@ -68,8 +68,7 @@ namespace Microsoft.AspNetCore.Authentication.MicrosoftAccount // Store this for use during the code redemption. properties.Items.Add(OAuthConstants.CodeVerifierKey, codeVerifier); - using var sha256 = SHA256.Create(); - var challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier)); + var challengeBytes = SHA256.HashData(Encoding.UTF8.GetBytes(codeVerifier)); var codeChallenge = WebEncoders.Base64UrlEncode(challengeBytes); queryStrings[OAuthConstants.CodeChallengeKey] = codeChallenge; diff --git a/src/Security/Authentication/OAuth/src/OAuthHandler.cs b/src/Security/Authentication/OAuth/src/OAuthHandler.cs index 99dccc6b7e..13d7140fd3 100644 --- a/src/Security/Authentication/OAuth/src/OAuthHandler.cs +++ b/src/Security/Authentication/OAuth/src/OAuthHandler.cs @@ -280,8 +280,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth // Store this for use during the code redemption. properties.Items.Add(OAuthConstants.CodeVerifierKey, codeVerifier); - using var sha256 = SHA256.Create(); - var challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier)); + var challengeBytes = SHA256.HashData(Encoding.UTF8.GetBytes(codeVerifier)); var codeChallenge = WebEncoders.Base64UrlEncode(challengeBytes); parameters[OAuthConstants.CodeChallengeKey] = codeChallenge; diff --git a/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectHandler.cs b/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectHandler.cs index 73f7f96d69..533d419c5d 100644 --- a/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectHandler.cs +++ b/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectHandler.cs @@ -375,8 +375,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect // Store this for use during the code redemption. See RunAuthorizationCodeReceivedEventAsync. properties.Items.Add(OAuthConstants.CodeVerifierKey, codeVerifier); - using var sha256 = SHA256.Create(); - var challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier)); + var challengeBytes = SHA256.HashData(Encoding.UTF8.GetBytes(codeVerifier)); var codeChallenge = WebEncoders.Base64UrlEncode(challengeBytes); message.Parameters.Add(OAuthConstants.CodeChallengeKey, codeChallenge); diff --git a/src/SignalR/common/Http.Connections/src/Internal/HttpConnectionManager.cs b/src/SignalR/common/Http.Connections/src/Internal/HttpConnectionManager.cs index aec84c5dab..2712b5d7cf 100644 --- a/src/SignalR/common/Http.Connections/src/Internal/HttpConnectionManager.cs +++ b/src/SignalR/common/Http.Connections/src/Internal/HttpConnectionManager.cs @@ -23,8 +23,6 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal // TODO: Consider making this configurable? At least for testing? private static readonly TimeSpan _heartbeatTickRate = TimeSpan.FromSeconds(1); - private static readonly RNGCryptoServiceProvider _keyGenerator = new RNGCryptoServiceProvider(); - private readonly ConcurrentDictionary _connections = new ConcurrentDictionary(StringComparer.Ordinal); private readonly TimerAwaitable _nextHeartbeat; @@ -113,7 +111,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal // 128 bit buffer / 8 bits per byte = 16 bytes Span buffer = stackalloc byte[16]; // Generate the id with RNGCrypto because we want a cryptographically random id, which GUID is not - _keyGenerator.GetBytes(buffer); + RandomNumberGenerator.Fill(buffer); return WebEncoders.Base64UrlEncode(buffer); } diff --git a/src/Tools/Microsoft.dotnet-openapi/src/Commands/BaseCommand.cs b/src/Tools/Microsoft.dotnet-openapi/src/Commands/BaseCommand.cs index 1edc21c413..da84a008cc 100644 --- a/src/Tools/Microsoft.dotnet-openapi/src/Commands/BaseCommand.cs +++ b/src/Tools/Microsoft.dotnet-openapi/src/Commands/BaseCommand.cs @@ -513,19 +513,7 @@ namespace Microsoft.DotNet.OpenApi.Commands private static byte[] GetHash(Stream stream) { - SHA256 algorithm; - try - { - algorithm = SHA256.Create(); - } - catch (TargetInvocationException) - { - // SHA256.Create is documented to throw this exception on FIPS-compliant machines. See - // https://msdn.microsoft.com/en-us/library/z08hz7ad Fall back to a FIPS-compliant SHA256 algorithm. - algorithm = new SHA256CryptoServiceProvider(); - } - - using (algorithm) + using (var algorithm = SHA256.Create()) { return algorithm.ComputeHash(stream); }