Question

I am trying to develop a website and a corresponding helper program (installed on the user computer). The website and the program will communicate with each other (AJAX mostly), but it will be a large security risk if any other web page can send requests to the program. I want to come up with a solution which makes it extremely hard to inject fraud requests to my program (installed on the user computer). My thoughts are about to use one time passwords, but I have limited security knowledge and therefore ask you for your thoughts.

I have came up with this One-Time-Password algorithm (pseudo):

function otp(seed, counter, unix_timestamp, action)
{
    for(i = 0; i < counter; ++i)
    {
        seed = sha256(seed + i);
    }
    str = seed;

    str = sha256(str + unix_timestamp/60);
    str = sha256(str + action);
    otp = substr(str,0,4); //Convert the first for bytes to an int.
    return (int)otp;
}

It should have the following properties:

  • Can only be used once, (On every otp generation will "counter" be increased => new seed)
  • Will be changed every minute (It depends on time).
  • Bound to an action (login, ...), it depends on a specific action.
  • Can easily be generated separately and later be synchronized.

If every request contains OTP code and counter value, is this secure? If not what are your tips to accomplish this? I really want all those properties I mentioned above.

Thanks in advance.

Was it helpful?

Solution

Your approach is sensible in principle. Keep in mind, however, that multiple calls to your hash function are pointless - either it's secure on the first pass, or it isn't at all. Also, you are right now only using the seed to actually authenticate requests (anything else would be known to a would-be attacker), and any weakness in seed generation becomes a weakness in authentication.

I am not aware of the specific shortcomings of SHA256. However, your problem in general is fairly common and is much easier to describe and solve in standard terms. You want to authenticate a request to your program. Your remote program needs to securely determine the authenticity of a request. This problem is most easily solved with public-key cryptography. For example, make a GnuPG key pair, keep the private key at your website and distribute the public key with your program, and sign any command you send to the program with the private key. The client program receives requests normally and only needs to verify their authenticity via a single call to GnuPG.

OTHER TIPS

There already exists a standard for this, called HOTP (RFC 4226). You should use that rather than reinventing the wheel, as it's been vetted by people with more experience in cryptography than us.

You haven't stated who your adversaries are; if they are the user on their own machine, you should bear in mind that it is literally impossible to prevent them from compromising any scheme you care to invent.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top