1

I'm looking to secure an API based on a shared key and a given username and datetime. The API gives access to trusted third parties and does not require the input from a user in order to access their account (i.e. no OAuth user interaction flow). The third party does not know, nor should require, the user's password.

/// <summary>
/// Generate a Time/String based Hash from the given DateTimeStamp, Authentication Details 
/// and (Pre-Shared) API Key.
/// </summary>
/// <param name="datetimeStamp">The DateTimeStamp that is to be used to generate the Hash</param>
/// <param name="userName">The UserName that is to be used to generate the Hash</param>
/// <returns>A string based Hash generated from the DateTimeStamp, Username and 
/// Pre-Agreed API Hash Key</returns>
public string GenerateHash(DateTimeOffset dateTimeStamp, string userName)
{
    string hash = string.Empty;
    DateTimeOffset DateStamp = dateTimeStamp.ToUniversalTime();
    string input = string.Format("{0}{1}{2}", DateStamp, userName, PreSharedKey);
    var sha1 = System.Security.Cryptography.SHA1.Create();
    byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
    byte[] hashArray = sha1.ComputeHash(inputBytes);
    var hashOutput = new StringBuilder();
    for (int i = 0; i < hashArray.Length; i++)
        hash += hashArray[i].ToString("X2");
    return hash;
}

A POST is made to an authentication API like so:

{ 
  Hash : "9B970DD40DB803EDB301C5B1CC23DF7B2C5B5FF5", 
  DateTimeStamp : "yyyyMMddHHmmss", 
  UserName : "admin"
}

The Hash is made up of the following: SHA1(datetime + username + presharedkey).

An authentication token is then generated and returned to the third party (session token that has an expiry date).

Are there any obvious problems with such an approach? Is there a better way to do such authentication when the third party is semi-trusted, and the user shouldn't be required to authorise access to their account?

Rebecca
  • 151
  • 6
  • 2
    The title mentions HMAC, but the code does not use it. Why? – CodesInChaos Sep 30 '15 at 11:55
  • Correct, which is why I used the term "HMAC style" for want of a better phrase 'HMAC-esque'? I was given this code to use by a third party, but I'm trying to figure out why anyone would use this over 'System.Security.Cryptography.HMACSHA256(key)'. It seemed insecure, and I wondered what other opinions there were. – Rebecca Sep 30 '15 at 12:06
  • As far as I can tell it doesn't have any practical weaknesses, but it's clearly not good design. – CodesInChaos Sep 30 '15 at 12:08
  • What does `PreSharedKey` look like? Is it a string? What format does it have and how long is it? – CodesInChaos Sep 30 '15 at 12:15
  • @Junto: Why would anyone use concat then hash rather than proper HMAC? Probably because they don't know better. – Siyuan Ren Sep 30 '15 at 12:17
  • @SiyuanRen which was also my concern. – Rebecca Sep 30 '15 at 12:20
  • @CodesInChaos it wasn't specified, but regardless of how long it was, the 'naked' SHA1 hash is pretty much brute-forceable anyway right? – Rebecca Sep 30 '15 at 12:20

0 Answers0