MessageDigest.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. using System;
  2. using System.IO;
  3. using System.Reflection;
  4. using System.Security.Cryptography;
  5. namespace SharpCifs.Util.Sharpen
  6. {
  7. public abstract class MessageDigest
  8. {
  9. public void Digest (byte[] buffer, int o, int len)
  10. {
  11. byte[] d = Digest ();
  12. d.CopyTo (buffer, o);
  13. }
  14. public byte[] Digest (byte[] buffer)
  15. {
  16. Update (buffer);
  17. return Digest ();
  18. }
  19. public abstract byte[] Digest ();
  20. public abstract int GetDigestLength ();
  21. public static MessageDigest GetInstance (string algorithm)
  22. {
  23. switch (algorithm.ToLower ()) {
  24. case "sha-1":
  25. //System.Security.CryptographySHA1Managed not found
  26. //return new MessageDigest<SHA1Managed> ();
  27. return new MessageDigest<System.Security.Cryptography.SHA1>();
  28. case "md5":
  29. return new MessageDigest<Md5Managed> ();
  30. }
  31. throw new NotSupportedException (string.Format ("The requested algorithm \"{0}\" is not supported.", algorithm));
  32. }
  33. public abstract void Reset ();
  34. public abstract void Update (byte[] b);
  35. public abstract void Update (byte b);
  36. public abstract void Update (byte[] b, int offset, int len);
  37. }
  38. public class MessageDigest<TAlgorithm> : MessageDigest where TAlgorithm : HashAlgorithm //, new() //use static `Create` method
  39. {
  40. private TAlgorithm _hash;
  41. //private CryptoStream _stream; //don't work .NET Core
  42. private MemoryStream _stream;
  43. public MessageDigest ()
  44. {
  45. Init ();
  46. }
  47. public override byte[] Digest ()
  48. {
  49. //CryptoStream -> MemoryStream, needless method
  50. //_stream.FlushFinalBlock ();
  51. //HashAlgorithm.`Hash` property deleted
  52. //byte[] hash = _hash.Hash;
  53. byte[] hash = _hash.ComputeHash(_stream.ToArray());
  54. Reset ();
  55. return hash;
  56. }
  57. public void Dispose ()
  58. {
  59. if (_stream != null) {
  60. _stream.Dispose ();
  61. }
  62. _stream = null;
  63. }
  64. public override int GetDigestLength ()
  65. {
  66. return (_hash.HashSize / 8);
  67. }
  68. private void Init ()
  69. {
  70. //use static `Create` method
  71. //_hash = Activator.CreateInstance<TAlgorithm> ();
  72. var createMethod = typeof(TAlgorithm).GetRuntimeMethod("Create", new Type[0]);
  73. _hash = (TAlgorithm)createMethod.Invoke(null, new object[] {});
  74. //HashAlgorithm cannot cast `ICryptoTransform` on .NET Core, gave up using CryptoStream.
  75. //_stream = new CryptoStream(Stream.Null, _hash, CryptoStreamMode.Write);
  76. //_stream = new CryptoStream(_tmpStream, (ICryptoTransform)_hash, CryptoStreamMode.Write);
  77. _stream = new MemoryStream();
  78. }
  79. public override void Reset ()
  80. {
  81. Dispose ();
  82. Init ();
  83. }
  84. public override void Update (byte[] input)
  85. {
  86. _stream.Write (input, 0, input.Length);
  87. }
  88. public override void Update (byte input)
  89. {
  90. _stream.WriteByte (input);
  91. }
  92. public override void Update (byte[] input, int index, int count)
  93. {
  94. if (count < 0)
  95. Console.WriteLine ("Argh!");
  96. _stream.Write (input, index, count);
  97. }
  98. }
  99. }