Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Monday, April 10, 2017

Performance of MD5, SHA1, SHA256, SHA384, and SHA512 with C#

Recently I ran a few performance calculations to see the differences of performance of MD5, SHA1, SHA256, SHA384, and SHA512. I ran the tests on my box with one code set. I compiled my code as a 32-bit program and as a 64-bit program. Besides the performance of each hashing algorithm, I wanted see the difference in 32-bit and 64-bit compiles would make.


My testing method consisted of the following method.
  • CPU: Intel(R) Core (TM) i7-4700MQ CPU 2.40GHz
  • OS: Windows 7, 64-bit Operating System
  • Memory: 32.0 GB (31.6 GB usable)
  • Hash string size was 1K.
  • Ran in release mode, (not inside of Visual Studio, language used was C#)
  • Each hash string method was called 10,000 times with a different string to be hashed.
  • Time was accumulated in CPU ticks.
  • I ran each the program three times.
 

The one thing that stood out to me was SHA-256. I was surprised by the performance, the small difference between 32 and 64-bit programs and the actual time it took to create an SHA-256 hash. After spending some time on the internet I came up with the following.
  




 
SHA-256 algorithm generates an almost-unique, fixed-size 256-bit (32-byte) hash. So even on a 64-bit machine where the word size is larger to push more data thru the transformations algorithm because SHA-256 is using a fix 32-byte data you do not see the larger difference between a 32 and 64 bit processors.  One interesting note is Microsoft has not updated its core base class from which all implementations of cryptographic hash algorithms. The HashAlgorithm class is still is using 32-bit transformblocks. I am curious why Microsoft hasn't change to use a 64-bit transformblock. Would that improve the performance level? I would have thought Microssoft would have a 64-bit version of SHA256.




The largest takeaway here is "Do not use MD5 or SHA1". The difference in performance isn't going to hurt your application as much as using an outdated hashing algorithm will.



Code.

  Calling method to create a Hash string. All hashing followed the same template.


         static Random random = new Random();
         static Int64 MaxIterations = 10000;
         static Int16 TotalHashLength = 1024;
              static void MD5()
              {
                  MD5Hash md5Hash = new MD5Hash();
                  for (int i = 0; i < MaxIterations - 1; i++)
                  {
                      md5Hash.CalculateHash(RandomString(TotalHashLength));
                  }
                  file.WriteLine("MD5 , {0}", md5Hash.TotalElapseTime().ToString());
              }
 

 Each time an hash was created a different random string was created using lower, upper case, number and special printable characters.

 
              static string RandomString(int length)
              {
                  const string chars = "Aa0BbCcDd1+EeFf2_GgHh3(IiJj4)KkLl5*MmNn6&OoPp7^QqRr8%SsTt9#UuVv@WwXxYyZz!";
                  StringBuilder sb = new StringBuilder();
                  for (int i = 0; i < length; i++)
                  {
                      sb.Append(new string(Enumerable.Repeat(chars, 1).Select(s => s[random.Next(s.Length)]).ToArray()));
                  }
                  return sb.ToString();
             }
   

 Main hashing calculation for MD5, other hashing methods follow this template.


              private Stopwatch sw;
              private MD5 md5;
              private TimeSpan ElapseTime;
    
               public void CalculateHash(string input)
               {
                  sw = Stopwatch.StartNew();
                  md5 = MD5.Create();
                  byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
                  byte[] hash = md5.ComputeHash(inputBytes););
                  ElapseTime += sw.Elapsed;
                  sw.Stop();
               }




For the complete code solution see my github page https://github.com/lwconklin/Hashing

Sunday, July 22, 2012

Code Obfuscation


Languages like C# and Java can be easily be de-compiled and now with more web applications using JavaScript we don’t even need to de-compile the code to see it.

Because of this, code obfuscators are on the rise.  One of the newest kids on the block is JScrambler (https://jscrambler.com/) made by AuditMark (http://auditmark.com/).

Code obfuscator’s work but do they provide any value? Do they add any value, for security, protecting our intellectual property, etc.?

Obfuscated code is modified on purpose to make it harder to read and making it more difficult to analysis what the code really does.  A key point here is this goal is a two way street.  It can be for someone trying to protect their intellectual property or for malware trying to prevent its detection by anti virus/malware scanners.  So our first point is obfuscated code can be used for and against us.

That brings up an excellent point. If your web site uses something like jscrambler should I have the right to inspect the JavaScript used by your web application to make sure it is not doing something evil? Remember the JavaScript is not running on the server it’s running on your box.

Code obfuscated makers say obfuscation provides the following benefits to its users…
  •       Protect Intellectual property (e.g. algorithms) contained in JavaScript.
  •       Prevent code reutilization.
  •       Prevent code modification.
  •      Prevent unauthorized code execution (piracy).
  •       Add another layer of security, by making it harder for attackers to interfere with your Web Application.


This last point is the most discussed point; does obfuscated code really provide a benefit as an added layer of security? Remember code obfuscation is NOT encryption.

Yes, obfuscated code does provide extra security. We know it can be broken/reverse engineered but the time and effort it takes does provide a temporarily determent to the causal hacker. In the long-run it will not protect your code.

Before using code obfuscation I think one of the first things we need to ask ourselves is “What are we trying to accomplish with code obfuscation?” with that question in mind here are a few guidelines.

  •    Never put sensitive information on the client (passwords, 'hidden" URLs, validation routines, encryption routines, etc).
  •    Understand that anything on a client can be compromised because you no longer have control.
  •   Any obfuscation of client-side code has to be un-done in order for the framework to process it... thus only providing only a marginal security improvement.


My personal take on this is JavaScript code obfuscation provides less transparency on the Web. Open transparency creates better privacy in that everyone can see what everyone else is doing in an open environment. The temporary time value of security gained by using obfuscation is not enough to overcome the potential downfall of a less open transparent environment.

A few other resources:
https://developers.google.com/closure/compiler/docs/api-tutorial3  Compression provides obfuscation as a side-effect.