diff --git a/src/Renci.SshNet/Abstractions/CryptoAbstraction.cs b/src/Renci.SshNet/Abstractions/CryptoAbstraction.cs index 1567af3ef..46f4b429d 100644 --- a/src/Renci.SshNet/Abstractions/CryptoAbstraction.cs +++ b/src/Renci.SshNet/Abstractions/CryptoAbstraction.cs @@ -1,10 +1,10 @@ -using System; +using System.Security.Cryptography; namespace Renci.SshNet.Abstractions { internal static class CryptoAbstraction { - private static readonly System.Security.Cryptography.RandomNumberGenerator Randomizer = CreateRandomNumberGenerator(); + private static readonly RandomNumberGenerator Randomizer = RandomNumberGenerator.Create(); /// /// Generates a array of the specified length, and fills it with a @@ -14,51 +14,68 @@ internal static class CryptoAbstraction public static byte[] GenerateRandom(int length) { var random = new byte[length]; - GenerateRandom(random); + Randomizer.GetBytes(random); return random; } - /// - /// Fills an array of bytes with a cryptographically strong random sequence of values. - /// - /// The array to fill with cryptographically strong random bytes. - /// is . - /// - /// The length of the byte array determines how many random bytes are produced. - /// - public static void GenerateRandom(byte[] data) - { - Randomizer.GetBytes(data); - } - - public static System.Security.Cryptography.RandomNumberGenerator CreateRandomNumberGenerator() - { - return System.Security.Cryptography.RandomNumberGenerator.Create(); - } - - public static System.Security.Cryptography.MD5 CreateMD5() + public static byte[] HashMD5(byte[] source) { - return System.Security.Cryptography.MD5.Create(); +#if NET + return MD5.HashData(source); +#else + using (var md5 = MD5.Create()) + { + return md5.ComputeHash(source); + } +#endif } - public static System.Security.Cryptography.SHA1 CreateSHA1() + public static byte[] HashSHA1(byte[] source) { - return System.Security.Cryptography.SHA1.Create(); +#if NET + return SHA1.HashData(source); +#else + using (var sha1 = SHA1.Create()) + { + return sha1.ComputeHash(source); + } +#endif } - public static System.Security.Cryptography.SHA256 CreateSHA256() + public static byte[] HashSHA256(byte[] source) { - return System.Security.Cryptography.SHA256.Create(); +#if NET + return SHA256.HashData(source); +#else + using (var sha256 = SHA256.Create()) + { + return sha256.ComputeHash(source); + } +#endif } - public static System.Security.Cryptography.SHA384 CreateSHA384() + public static byte[] HashSHA384(byte[] source) { - return System.Security.Cryptography.SHA384.Create(); +#if NET + return SHA384.HashData(source); +#else + using (var sha384 = SHA384.Create()) + { + return sha384.ComputeHash(source); + } +#endif } - public static System.Security.Cryptography.SHA512 CreateSHA512() + public static byte[] HashSHA512(byte[] source) { - return System.Security.Cryptography.SHA512.Create(); +#if NET + return SHA512.HashData(source); +#else + using (var sha512 = SHA512.Create()) + { + return sha512.ComputeHash(source); + } +#endif } } } diff --git a/src/Renci.SshNet/Abstractions/ReflectionAbstraction.cs b/src/Renci.SshNet/Abstractions/ReflectionAbstraction.cs deleted file mode 100644 index d9e15a508..000000000 --- a/src/Renci.SshNet/Abstractions/ReflectionAbstraction.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Renci.SshNet.Abstractions -{ - internal static class ReflectionAbstraction - { - public static IEnumerable GetCustomAttributes(this Type type, bool inherit) - where T : Attribute - { - var attributes = type.GetCustomAttributes(typeof(T), inherit); - return attributes.Cast(); - } - } -} diff --git a/src/Renci.SshNet/Common/BigInteger.cs b/src/Renci.SshNet/Common/BigInteger.cs index c83ddbadc..57c3def90 100644 --- a/src/Renci.SshNet/Common/BigInteger.cs +++ b/src/Renci.SshNet/Common/BigInteger.cs @@ -179,8 +179,7 @@ public static BigInteger PositiveMod(BigInteger dividend, BigInteger divisor) /// A random number of the specified length. public static BigInteger Random(int bitLength) { - var bytesArray = new byte[(bitLength / 8) + (((bitLength % 8) > 0) ? 1 : 0)]; - CryptoAbstraction.GenerateRandom(bytesArray); + var bytesArray = CryptoAbstraction.GenerateRandom((bitLength / 8) + (((bitLength % 8) > 0) ? 1 : 0)); bytesArray[bytesArray.Length - 1] = (byte)(bytesArray[bytesArray.Length - 1] & 0x7F); // Ensure not a negative value return new BigInteger(bytesArray); } diff --git a/src/Renci.SshNet/Common/HostKeyEventArgs.cs b/src/Renci.SshNet/Common/HostKeyEventArgs.cs index acd38965a..e3365bec9 100644 --- a/src/Renci.SshNet/Common/HostKeyEventArgs.cs +++ b/src/Renci.SshNet/Common/HostKeyEventArgs.cs @@ -100,17 +100,11 @@ public HostKeyEventArgs(KeyHostAlgorithm host) HostKeyName = host.Name; KeyLength = host.Key.KeyLength; - _lazyFingerPrint = new Lazy(() => - { - using var md5 = CryptoAbstraction.CreateMD5(); - return md5.ComputeHash(HostKey); - }); + _lazyFingerPrint = new Lazy(() => CryptoAbstraction.HashMD5(HostKey)); _lazyFingerPrintSHA256 = new Lazy(() => { - using var sha256 = CryptoAbstraction.CreateSHA256(); - - return Convert.ToBase64String(sha256.ComputeHash(HostKey)) + return Convert.ToBase64String(CryptoAbstraction.HashSHA256(HostKey)) #if NET || NETSTANDARD2_1_OR_GREATER .Replace("=", string.Empty, StringComparison.Ordinal); #else diff --git a/src/Renci.SshNet/Messages/Message.cs b/src/Renci.SshNet/Messages/Message.cs index 07b747472..ea8f6a9b5 100644 --- a/src/Renci.SshNet/Messages/Message.cs +++ b/src/Renci.SshNet/Messages/Message.cs @@ -83,8 +83,7 @@ internal byte[] GetPacket(byte paddingMultiplier, Compressor compressor, bool ex var paddingLength = GetPaddingLength(paddingMultiplier, excludePacketLengthFieldWhenPadding ? packetLength - 4 : packetLength); // add padding bytes - var paddingBytes = new byte[paddingLength]; - CryptoAbstraction.GenerateRandom(paddingBytes); + var paddingBytes = CryptoAbstraction.GenerateRandom(paddingLength); sshDataStream.Write(paddingBytes, 0, paddingLength); var packetDataLength = GetPacketDataLength(messageLength, paddingLength); @@ -128,8 +127,7 @@ internal byte[] GetPacket(byte paddingMultiplier, Compressor compressor, bool ex WriteBytes(sshDataStream); // add padding bytes - var paddingBytes = new byte[paddingLength]; - CryptoAbstraction.GenerateRandom(paddingBytes); + var paddingBytes = CryptoAbstraction.GenerateRandom(paddingLength); sshDataStream.Write(paddingBytes, 0, paddingLength); return sshDataStream.ToArray(); diff --git a/src/Renci.SshNet/Messages/Transport/KeyExchangeInitMessage.cs b/src/Renci.SshNet/Messages/Transport/KeyExchangeInitMessage.cs index 7bfce46dc..a0e7979ec 100644 --- a/src/Renci.SshNet/Messages/Transport/KeyExchangeInitMessage.cs +++ b/src/Renci.SshNet/Messages/Transport/KeyExchangeInitMessage.cs @@ -12,9 +12,7 @@ public class KeyExchangeInitMessage : Message, IKeyExchangedAllowed /// public KeyExchangeInitMessage() { - var cookie = new byte[16]; - CryptoAbstraction.GenerateRandom(cookie); - Cookie = cookie; + Cookie = CryptoAbstraction.GenerateRandom(16); } #region Message Properties diff --git a/src/Renci.SshNet/PrivateKeyFile.cs b/src/Renci.SshNet/PrivateKeyFile.cs index 59e72cec6..b0ed8668f 100644 --- a/src/Renci.SshNet/PrivateKeyFile.cs +++ b/src/Renci.SshNet/PrivateKeyFile.cs @@ -7,7 +7,6 @@ using System.Text; using System.Text.RegularExpressions; -using Renci.SshNet.Abstractions; using Renci.SshNet.Common; using Renci.SshNet.Security; using Renci.SshNet.Security.Cryptography; @@ -380,7 +379,8 @@ private static byte[] GetCipherKey(string passphrase, int length) { var cipherKey = new List(); - using (var md5 = CryptoAbstraction.CreateMD5()) +#pragma warning disable CA1850 // Prefer static HashData method; We'll reuse the object on lower targets. + using (var md5 = MD5.Create()) { var passwordBytes = Encoding.UTF8.GetBytes(passphrase); @@ -394,6 +394,7 @@ private static byte[] GetCipherKey(string passphrase, int length) cipherKey.AddRange(hash); } } +#pragma warning restore CA1850 // Prefer static HashData method return cipherKey.ToArray().Take(length); } @@ -426,7 +427,8 @@ private static byte[] DecryptKey(CipherInfo cipherInfo, byte[] cipherData, strin var cipherKey = new List(); - using (var md5 = CryptoAbstraction.CreateMD5()) +#pragma warning disable CA1850 // Prefer static HashData method; We'll reuse the object on lower targets. + using (var md5 = MD5.Create()) { var passwordBytes = Encoding.UTF8.GetBytes(passPhrase); @@ -443,6 +445,7 @@ private static byte[] DecryptKey(CipherInfo cipherInfo, byte[] cipherData, strin cipherKey.AddRange(hash); } } +#pragma warning restore CA1850 // Prefer static HashData method var cipher = cipherInfo.Cipher(cipherKey.ToArray(), binarySalt); diff --git a/src/Renci.SshNet/Security/Cryptography/Bcrypt.cs b/src/Renci.SshNet/Security/Cryptography/Bcrypt.cs index 14f6169a5..40ab0695c 100644 --- a/src/Renci.SshNet/Security/Cryptography/Bcrypt.cs +++ b/src/Renci.SshNet/Security/Cryptography/Bcrypt.cs @@ -852,7 +852,7 @@ public void Hash(byte[] hpass, byte[] hsalt, byte[] output) /// public void Pbkdf(byte[] password, byte[] salt, int rounds, byte[] output) { - using (var sha512 = CryptoAbstraction.CreateSHA512()) + using (var sha512 = SHA512.Create()) { int nblocks = (output.Length + 31) / 32; byte[] hpass = sha512.ComputeHash(password); diff --git a/src/Renci.SshNet/Security/Cryptography/DsaDigitalSignature.cs b/src/Renci.SshNet/Security/Cryptography/DsaDigitalSignature.cs index a5aae17c0..8fdb6a8f7 100644 --- a/src/Renci.SshNet/Security/Cryptography/DsaDigitalSignature.cs +++ b/src/Renci.SshNet/Security/Cryptography/DsaDigitalSignature.cs @@ -1,7 +1,6 @@ using System; using System.Security.Cryptography; -using Renci.SshNet.Abstractions; using Renci.SshNet.Common; namespace Renci.SshNet.Security.Cryptography @@ -29,7 +28,7 @@ public DsaDigitalSignature(DsaKey key) _key = key; - _hash = CryptoAbstraction.CreateSHA1(); + _hash = SHA1.Create(); } /// diff --git a/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchangeSha1.cs b/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchangeSha1.cs index 791e2c44b..5eb0e7c17 100644 --- a/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchangeSha1.cs +++ b/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchangeSha1.cs @@ -35,10 +35,7 @@ protected override int HashSize /// protected override byte[] Hash(byte[] hashData) { - using (var sha1 = CryptoAbstraction.CreateSHA1()) - { - return sha1.ComputeHash(hashData, 0, hashData.Length); - } + return CryptoAbstraction.HashSHA1(hashData); } } } diff --git a/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchangeSha256.cs b/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchangeSha256.cs index 2e286345c..62d466cc1 100644 --- a/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchangeSha256.cs +++ b/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchangeSha256.cs @@ -35,10 +35,7 @@ protected override int HashSize /// protected override byte[] Hash(byte[] hashData) { - using (var sha256 = CryptoAbstraction.CreateSHA256()) - { - return sha256.ComputeHash(hashData); - } + return CryptoAbstraction.HashSHA256(hashData); } } } diff --git a/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupSha1.cs b/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupSha1.cs index 4669eb8ae..26d13a4d4 100644 --- a/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupSha1.cs +++ b/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupSha1.cs @@ -27,10 +27,7 @@ protected override int HashSize /// protected override byte[] Hash(byte[] hashData) { - using (var sha1 = CryptoAbstraction.CreateSHA1()) - { - return sha1.ComputeHash(hashData, 0, hashData.Length); - } + return CryptoAbstraction.HashSHA1(hashData); } } } diff --git a/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupSha256.cs b/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupSha256.cs index ea29e6e2f..3246a3d8e 100644 --- a/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupSha256.cs +++ b/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupSha256.cs @@ -27,10 +27,7 @@ protected override int HashSize /// protected override byte[] Hash(byte[] hashData) { - using (var sha256 = CryptoAbstraction.CreateSHA256()) - { - return sha256.ComputeHash(hashData); - } + return CryptoAbstraction.HashSHA256(hashData); } } } diff --git a/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupSha512.cs b/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupSha512.cs index 60a8e5f7c..b599e9d2e 100644 --- a/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupSha512.cs +++ b/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupSha512.cs @@ -27,10 +27,7 @@ protected override int HashSize /// protected override byte[] Hash(byte[] hashData) { - using (var sha512 = CryptoAbstraction.CreateSHA512()) - { - return sha512.ComputeHash(hashData); - } + return CryptoAbstraction.HashSHA512(hashData); } } } diff --git a/src/Renci.SshNet/Security/KeyExchangeECCurve25519.cs b/src/Renci.SshNet/Security/KeyExchangeECCurve25519.cs index c6c060bab..987665afe 100644 --- a/src/Renci.SshNet/Security/KeyExchangeECCurve25519.cs +++ b/src/Renci.SshNet/Security/KeyExchangeECCurve25519.cs @@ -68,10 +68,7 @@ public override void Finish() /// protected override byte[] Hash(byte[] hashData) { - using (var sha256 = CryptoAbstraction.CreateSHA256()) - { - return sha256.ComputeHash(hashData, 0, hashData.Length); - } + return CryptoAbstraction.HashSHA256(hashData); } private void Session_KeyExchangeEcdhReplyMessageReceived(object sender, MessageEventArgs e) diff --git a/src/Renci.SshNet/Security/KeyExchangeECDH256.cs b/src/Renci.SshNet/Security/KeyExchangeECDH256.cs index a519c1896..aabfba62f 100644 --- a/src/Renci.SshNet/Security/KeyExchangeECDH256.cs +++ b/src/Renci.SshNet/Security/KeyExchangeECDH256.cs @@ -1,4 +1,4 @@ -using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.Sec; using Org.BouncyCastle.Asn1.X9; using Renci.SshNet.Abstractions; @@ -46,10 +46,7 @@ protected override int HashSize /// protected override byte[] Hash(byte[] hashData) { - using (var sha256 = CryptoAbstraction.CreateSHA256()) - { - return sha256.ComputeHash(hashData, 0, hashData.Length); - } + return CryptoAbstraction.HashSHA256(hashData); } } } diff --git a/src/Renci.SshNet/Security/KeyExchangeECDH384.cs b/src/Renci.SshNet/Security/KeyExchangeECDH384.cs index e91dcf965..39fcf3bde 100644 --- a/src/Renci.SshNet/Security/KeyExchangeECDH384.cs +++ b/src/Renci.SshNet/Security/KeyExchangeECDH384.cs @@ -1,4 +1,4 @@ -using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.Sec; using Org.BouncyCastle.Asn1.X9; using Renci.SshNet.Abstractions; @@ -46,10 +46,7 @@ protected override int HashSize /// protected override byte[] Hash(byte[] hashData) { - using (var sha384 = CryptoAbstraction.CreateSHA384()) - { - return sha384.ComputeHash(hashData, 0, hashData.Length); - } + return CryptoAbstraction.HashSHA384(hashData); } } } diff --git a/src/Renci.SshNet/Security/KeyExchangeECDH521.cs b/src/Renci.SshNet/Security/KeyExchangeECDH521.cs index 9ed146e96..17fa89e7f 100644 --- a/src/Renci.SshNet/Security/KeyExchangeECDH521.cs +++ b/src/Renci.SshNet/Security/KeyExchangeECDH521.cs @@ -1,4 +1,4 @@ -using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.Sec; using Org.BouncyCastle.Asn1.X9; using Renci.SshNet.Abstractions; @@ -46,10 +46,7 @@ protected override int HashSize /// protected override byte[] Hash(byte[] hashData) { - using (var sha512 = CryptoAbstraction.CreateSHA512()) - { - return sha512.ComputeHash(hashData, 0, hashData.Length); - } + return CryptoAbstraction.HashSHA512(hashData); } } } diff --git a/test/Renci.SshNet.Tests/Classes/SessionTest_ConnectingBase.cs b/test/Renci.SshNet.Tests/Classes/SessionTest_ConnectingBase.cs index 05ce88754..f2c2f3476 100644 --- a/test/Renci.SshNet.Tests/Classes/SessionTest_ConnectingBase.cs +++ b/test/Renci.SshNet.Tests/Classes/SessionTest_ConnectingBase.cs @@ -9,6 +9,7 @@ using Moq; +using Renci.SshNet.Abstractions; using Renci.SshNet.Common; using Renci.SshNet.Compression; using Renci.SshNet.Connection; @@ -181,7 +182,8 @@ protected virtual void SetupData() { var serviceAcceptMessage = ServiceAcceptMessageBuilder.Create(ServiceName.UserAuthentication) .Build(ServerOutboundPacketSequence); - var hash = Abstractions.CryptoAbstraction.CreateSHA256().ComputeHash(serviceAcceptMessage); + + var hash = CryptoAbstraction.HashSHA256(serviceAcceptMessage); var packet = new byte[serviceAcceptMessage.Length - 4 + hash.Length];