using System; using System.IO; using System.Reflection; using System.Security.Cryptography; namespace SharpCifs.Util.Sharpen { public abstract class MessageDigest { public void Digest (byte[] buffer, int o, int len) { byte[] d = Digest (); d.CopyTo (buffer, o); } public byte[] Digest (byte[] buffer) { Update (buffer); return Digest (); } public abstract byte[] Digest (); public abstract int GetDigestLength (); public static MessageDigest GetInstance (string algorithm) { switch (algorithm.ToLower ()) { case "sha-1": //System.Security.CryptographySHA1Managed not found //return new MessageDigest (); return new MessageDigest(); case "md5": return new MessageDigest (); } throw new NotSupportedException (string.Format ("The requested algorithm \"{0}\" is not supported.", algorithm)); } public abstract void Reset (); public abstract void Update (byte[] b); public abstract void Update (byte b); public abstract void Update (byte[] b, int offset, int len); } public class MessageDigest : MessageDigest where TAlgorithm : HashAlgorithm //, new() //use static `Create` method { private TAlgorithm _hash; //private CryptoStream _stream; //don't work .NET Core private MemoryStream _stream; public MessageDigest () { Init (); } public override byte[] Digest () { //CryptoStream -> MemoryStream, needless method //_stream.FlushFinalBlock (); //HashAlgorithm.`Hash` property deleted //byte[] hash = _hash.Hash; byte[] hash = _hash.ComputeHash(_stream.ToArray()); Reset (); return hash; } public void Dispose () { if (_stream != null) { _stream.Dispose (); } _stream = null; } public override int GetDigestLength () { return (_hash.HashSize / 8); } private void Init () { //use static `Create` method //_hash = Activator.CreateInstance (); var createMethod = typeof(TAlgorithm).GetRuntimeMethod("Create", new Type[0]); _hash = (TAlgorithm)createMethod.Invoke(null, new object[] {}); //HashAlgorithm cannot cast `ICryptoTransform` on .NET Core, gave up using CryptoStream. //_stream = new CryptoStream(Stream.Null, _hash, CryptoStreamMode.Write); //_stream = new CryptoStream(_tmpStream, (ICryptoTransform)_hash, CryptoStreamMode.Write); _stream = new MemoryStream(); } public override void Reset () { Dispose (); Init (); } public override void Update (byte[] input) { _stream.Write (input, 0, input.Length); } public override void Update (byte input) { _stream.WriteByte (input); } public override void Update (byte[] input, int index, int count) { if (count < 0) Console.WriteLine ("Argh!"); _stream.Write (input, index, count); } } }