views:

150

answers:

3

I have a few variables that must be stored on the client side. As usual anything on client side can be tampered. I would like to sign a few variables and verified them when the data is sent back to the server. At the moment i think they are 5 64bit vars.

On the server i would like to sign those 5 variables, then ensure the signature is valid when the client sends it back. How do i do this using C# .NET?

-edit- in this case i am not using asp.net

+2  A: 

Please see Encrypt ViewState in ASP.NET 2.0.

kervin
+1  A: 

A simple approach would be to calculate a checksum or hash (e.g. MD5) over the numbers and send this to the client with the data. When the data (and the hash) is sent back back by the client, create another hash with the sent data and compare it with the original hash (sent by the client) to verify whether the data was tampered.

E.g. convert the numbers to strings, concatenate them and calculate the MD5 hash over it. This can be "improved" by adding the currently logged-in user's name or the current SessionID to the string before calculating the hash.

M4N
Sounds hackish but still secure. I can put all the variables into a byte array and call md5 right? hmm IIRC it doesnt matter if the user has hundreds of data with sigs, i dont think they can find the salt? i think i'll accept this.
acidzombie24
Just to be clear, your proposal is that the hash be stored on the server, right? If you're going to store the hash on the server then why not simply store *all* the data on the server? Then the problem goes away.
Eric Lippert
The hash would be stored client side. Otherwise i'd store all 5*64bits on the server
acidzombie24
@Eric, @acidzombie24: The idea was to send the hash to the client. Once the data and hash is sent back to the server, it allows to check whether the data was modified. I don't know for how long you want to store the data on the client, maybe for a long time (using a cookie or local storage)? Maybe you don't want to/can't store data server-side?
M4N
@Eric, @acidzombie24: updated the answer to clarify.
M4N
i'm surprised you modified it, i wasn't confused ;). I'm just waiting a bit before i accept this answer.
acidzombie24
If the hash and the data are both stored on the client then what stops the hostile client from editing the data *and the hash*? What you want to do to prevent that is to *encrypt the hash with a private key on the server*. Then the client cannot edit the hash without knowing the private key, which is a secret. With this system, the whole thing can be stored on the client and verified by the server at a later date. However, don't think that you can get this correct just from this sketch; correct hashing and signing is not a trivial problem.
Eric Lippert
Wait a minute, you're talking about 40 bytes of data per user here? Storage is what, a tenth of a penny for a million bytes? I suspect that the dollar's worth of your time you've spent typing in the question is more than the cost of storing this data for every one of your customers.
Eric Lippert
I was not questioning the "must be stored on the client" part of the question, instead tried to give a simple idea how this problem could be approached. If the user does not know how you build the input to calculate the hash, then he will not easily be able to create a valid hash for tampered data.
M4N
@Eric Lippert: I hope you see this. Now i am thinking about keeping it serverside but i am a bit worried about writes killing the database. For one i am using sqlite atm even while after moving to mysql i can see writes causing a problem.
acidzombie24
Oh and its not just customers. Its anyone who visits the site or uses the app. I guess i need sessions data as well. hmmm. You made me think eric. You made me think hard!
acidzombie24
+1  A: 

At the very minimum:

  1. The server should have an asymmetric signature key-pair (private for signing, public for verification).

  2. The server should send the client a message containing the variables data, and a a signature for the hash value of the variables data:

    M, S(H(M))

  3. Upon reception, the client stores the entire message. When the time comes, the client sends the server everything back, then the server computes the hash for the variables data and verifies that

    V(S(H(M))) = H(M)

    Thus making sure that the variables data was issued by the server.

This is the very basis of the protocol, which should be expanded to handle whatever threats you need to secure against. The protocol as given is very prone to attacks, and only guarantees that the data was signed by the server.

Implemening this in .NET, almost all needed functionality is provided by the Security.Cryptography namespace. See the following MSDN article, it provides sample code for signing and verifying a given hash value, using DSA. See here for sample code of creating a hash value using SHA256.

M.A. Hanin
Perfect, i didnt know which crypto class to use. after thinking about what eric said i know what to use if i decide to do this. accepted!
acidzombie24