views:

56

answers:

4

EDIT 1 : I think I was not clear myself before and hence could not word it better. So, I am creating a system where I am providing page content to another system via IFRAMEs. A user will login to the other system and that system will set their apiKey and userKey in a cookie on my system so that access will be granted into my system. I want to encrypt these values so that a malicious user cannot be granted access into someone elses sytem by modifying a value. Are there good .NET standards for this type of encryption/security? What do you recommend I do in this scenario?

Hi all, Firstly this might be asked before but I have never implemented hashing or encryption before so I just want to make sure that I put my point across clearly.I want to have some good idea of what needs to be done here.

I have couple of keys which are unique to the users and are being passed by client through the iframes and to maintain session we create cookies using these values for them.So, now I want encrypt or generate a hash for these values since they are visible in the url I dont want the users manipulating these values.

So, I guess I want to generate a hash for both the keys and display that in the browser in order to stop the users from entering some random values and try to abuse the system. I guess would store these hashed values in the database and then compare with original values.

Please just anyone guide me to the steps what all I need to do and what should I be using to achieve it.

+2  A: 

You said that your database is storing information that is private to specific users, something along these lines:

{ ID = 1, User = Bob }
{ ID = 2, User = Bob }
{ ID = 3, User = Fred }
{ ID = 4, User = Bob }
{ ID = 5, User = Susan }

If this is the case, then it would seemingly make sense not to encrypt the ID in the URL, but to verify that the user actually has access to the data he's trying to view. For example, if Fred is logged in and tries to access ?id=2, the system would detect that he doesn't have permission to access that and would return an error page. But if Bob is logged in, he can access ?id=2 just fine. You could do this by having an additional column in the DB table which specifies the user who owns that particular row. In this particular scenario, the ID itself isn't sensitive, so you don't need to encrypt or obfuscate it.

If I'm misunderstanding your scenario, please clarify. :)

Levi
Updated My Question..Thanks for your response.
Misnomer
+2  A: 

I'm afraid I don't understand the details of your scenario very clearly, but I can say that in general, what you are looking for is "integrity" of the data that you are passing.

This can be provided by a message authentication code, like an HMAC algorithm. Here, a shared secret is combined with the data and hashed iteratively. The result is sent with the data. The recipient who knows the shared secret can perform the same process on the data, and see if their result matches the provided MAC. If not, the data were forged or altered.

Don't try to implement the HMAC algorithm yourself. The .NET class library provides a few variations of the algorithm.

erickson
Updated My Question..Thanks for your response.
Misnomer
@Misnomer - Thanks for clarifying. I think a MAC could still be useful. It will stop a user from simply typing someone's user name and trying to forge their identity. (A MAC serves a similar function to a digital signature, but it uses a shared key instead of public key.) However, the other system would have to implement the HMAC functionality too, which might be impractical. Another caveat is that while the tokens are tamper-proof, they could be copied and re-used. Some sort of nonce (a unique ID) would need to be incorporated to prevent that.
erickson
+2  A: 

Firstly if I understand your scenario correctly you don't need a hash but you need an encryption of those keys. If you hash them you will never be able to read the original values back and create the session cookie. You are trying to implement a cross domain Single-Sign-On (if this is not your case and I misunderstood your scenario you could ignore the rest of my answer).

I would recommend you using the machine keys to encrypt/decrypt:

Encrypt:

var ticket = new FormsAuthenticationTicket(
    1, // version
    "ticketName", // name of the ticket (it doesn't really matter here)
    DateTime.Now, // issue date
    DateTime.Now.AddMinutes(1), // validity of the ticket
    false, // should the ticket be persistent
    "key1=value1&key2=value2......" // values to encrypt, could be any string
);
string encrypted = FormsAuthentication.Encrypt(ticket);

Now send the encrypted string over the wire and on the other hand decrypt. It is important to perform this over an encrypted channel using SSL to avoid a Man-In-The-Middle who can steal the encrypted value and try to brute force it:

var ticket = FormsAuthentication.Decrypt(encrypted);
if (!ticket.Expired)
{
    // The ticket hasn't expired (< 1min) => use the values
    string keys = ticket.UserData;
    // TODO: Parse and issue cookie
}

For this to work it is necessary to have the same machine keys on both the encrypting and the decrypting side.


UPDATE:

Here are the steps:

  1. The user is authenticated on System A (Domain 1)
  2. System A decides to include in an iframe System B (Domain 2) where the user is not authenticated
  3. System A generates an encrypted string containing user information using machine keys
  4. System A sends to System B (via the src property of the iframe) this encrypted value
  5. System B reads and decrypts the encrypted value containing the user information
  6. System B issues an authentication cookie to indicate that the user is now authenticated on Domain 2
  7. System B shows the authenticated content to the user

You have achieved cross domain single sign on. Of course this technique is not limited to iframes.

Darin Dimitrov
Updated My Question..Thanks for your response.
Misnomer
After your edit it seems that the scenario you described is the one I propose a solution for in my answer.
Darin Dimitrov
+1  A: 

If I understand yoru question correctly, I think your going about this the wrong way. Your app should be made in such a way that messing with the query string or even posted data should not be able to circumvent your security.

Present the data plain text, it shouldn't matter if your security is done correctly. By using hashing, encrypting, or any other method to 'hide' this data is only securing it again the most basic users.

Analyze why you want to secure the query string and which parts are important. Then verify the data on the server side (controller) to make sure that each action is indeed proper... Anything else is just leaving you open to manipulation no matter how secure you think your querystring encryption/obsfucation is.

Kelsey
Updated My Question..Thanks for your response.
Misnomer