Authentication Method

I am writing a server-client application to receive a user's message and publish it.

Thinking about the authentication method.

  • Asymmetric encryption, possibly RSA.
  • Hash (salt + password + 'msg' + 'userid), SHA256
  • HMAC, SHA256. seems more secure than method 2. Also enable password hashing and msg messages.
  • Symmetric encryption "msg" with static password stored on both sides, possibly AES.

No need for encryption as the msg will be published online anyway. Therefore I am more inclined towards the HMAC or PKI method.

I am using java to send a request (including any authentication method to be implemented) www.mysite.com/foo?userid=12345&msg=hello&token=abc1234

python server side to receive the request and make sure the request is from a valid user.

Integration issues and make sure both parties understand each other's authentication token. This is a big factor for me. It also takes into account the availability of libraries available in both languages.

Or I can choose to rewrite the server side in java. (Why not python? Client side application should be in java)

What do you think?


EDIT: I would not consider this as a web application. The app is not serving the web page. Most operations are not network related. Simply the client-server communication takes place over the Internet. And sending POST / GET over HTTP is what I thought was an easier, albeit insecure way. Feel free to suggest me another alternative.

SSL is a secure encryption method. But this does not stop an attacker from sending a message to the server as a user. Anyone can initiate an HTTPS connection. And the content of the message doesn't need to be encrypted. In any case, it will be published by the online server. I need a way to authenticate message and sender.

For now, I'm leaning towards the HMAC algorithm. RSA will be more secure, but it will also complement developer efforts. See how it goes.

Thanks.

0


a source to share


4 answers


Can't you use standard SSL sockets to secure the connection, validate the user with a password, and then send a message to publish? If you don't have many clients, you can even use a self-signed certificate and put it in the KeyStore in the client application, so you don't need to buy a certificate from Verisign or anyone else.

If you store the hash of the user's password on the server (as I think, otherwise you have to verify the user's password somehow), you can reproduce this hash on the client side first (let's say you have hash user + pass) and then add this is the message and the hash result. You send the user id, hash and message to the server.



On the server side, you get a request with the user id, you get the user's password (the server only saved the user + pass hash), you add this message and hash again and compare it to the hash in the request. If it matches, the user can post a message.

Oh, and you should be using HTTP POST instead of sending data to URL. The server should not accept data in the URL to request a publish.

+2


a source


OK, first of all, the option to consider is to simply go down the "enterprise solution" path and go to the standard PKI market: buy yourself a certificate from Veri $ ign, etc. and use boring old HTTPS (or at least TLS, the underlying protocol). Then sending the data from the client (more or less) happens with a doddle and there will be a standard library in whatever langauge you choose to interpret on the other end. In fact, I think HTTPS / TLS and the whole certificate infrastructure is a tricky waste of space for applications where you know which server you are talking to and you know which encryption system you want to use. But having libraries out of the box means you can get started quickly and quickly, so it's definitely worth thinking about it one way or another.

Basically, you don't need a PKI certificate to use HTTPS / TLS. But in practice, it may be easier to just spend a few dollars than trying to convince the standard library to accept a self-issued certificate. (In general, using the HTTPS libraries could mean that you end up turning a 2-day "programming my encryption system" problem into a two-day "why isn't this black box accepting my certificate" problem? About what problem you want decide...)

Even if you are not using HTTPS / TLS, you may need to read the specification to understand how it overcomes certain security threats (and what those threats are).



OK, so take your glasses:

  • To be clear, you DO NOT need a certificate or PKI to use RSA or other asymmetric encryption. PKI (try) solves the problem of a client who has to talk to a "secret" server that he cannot trust when that server says "here's my public key." If you are writing a dedicated client and know ahead of time which server you are talking to, then you can simply distribute the public key with your client. The client knows that he is talking to the correct server, because if it is not, that server will not understand the things he encrypted with that public key.
  • The main thing you need to be careful about when using raw hashes is that they are vulnerable to extension attacks. So if you send "a | b | c" plus a hash code for that data, an attacker could generate a hash code for "a | b | c | d" (so in your example (2) they might replace "userid" for "useridX" and for that, develop a new hash code based on the hash code you specified for "a | b | c"). HMACs wrap this problem.
  • Anyway, if you are going to use "raw" encryption tools, use the standard libraries anyway, because they will think about some security concerns. For example, with RSA, you have to be careful to use indentation (see some information I wrote on the RSA encryption in Java and cryptography section in this ... which might be of interest to you). And when generating any encryption key, you need to be careful where the random data comes from.
  • You don't need to base the AES encryption key on the password (if you do, read the password-based encryption schemes: the password usually has little entropy, so you need to take extra steps to try to protect against this). But I would go for a more standard approach of using a password to authenticate the connection, and negotiate a random AES key as part of the authentication.
  • Make sure your schema addresses the issue of replay attacks . Typically, the client and server should send each other a random "nonce" at the beginning of the message and authentication and future communication on this connection will depend on the nonce).
+1


a source


Let me add some random thoughts / comments to your suggestions.

  • RSA: Since you are mainly interested in authentication, I am assuming that you want to use RSA signatures. This will mean that each user needs their own private key. This sounds a bit like overkill to me, especially when the user and the server already share secrets (i.e. passwords).
  • Using SHA256 is a good approach. I have some trouble figuring out why you are including salt, as salt is commonly used to avoid an attacker pre-calculating the dictionary hashes. To be clear: problems with discipline problems are here. An attacker can use hash messages with all passwords from the dictionary. It just has to repeat this attack for every user and cannot reuse the precomputed values. One way to make this attack a little more difficult is called key hardening, for example. by repeatedly hashing the result n times and hence forcing the attacker to do more work during the dictionary attack.
  • I totally agree that HMAC is better than just SHA-256. After all, HMAC was designed for authentication. I'm not sure why you want a hash message before calculating the HMAC. HMAC does it for you.
  • Encryption does not always provide authentication. This is especially in cases where an attacker learns the plaintext, as in your case. It could use the properties of the cipher mode to control the ciphertext, know exactly how the resulting plaintext will look (for example, CBC mode allows such manipulations). Your previous suggestion (HMAC) is preferred.

Finally, if you can set up an SSL connection between the user and the server, as others suggest: that would be a much more secure solution, as even the link mentioned above was not possible.

+1


a source


RSA is typically used to configure key exchange for faster encryption. This is how SSL works.

If the security requirements for your applications are so sensitive that you need a PKI, then it should be said (without any intent to be harsh) that if you need to ask this on SO, then there is probably something you shouldn't (given, that in general, successful attacks on secure channels attack implementation weaknesses).

As Chochos suggested, what is wrong with using the existing SSL infrastructure in Java and your server to set up a secure https connection and then just pass the user's password from the client to the server?

0


a source







All Articles