Should WebRTC's SDP be private for secure communication? - security

There are ice-ufrag and ice-pwd parameters in SDP, but do they (or any other parameters) really need be private for secure end-to-end connection if I can ensure SDP offer/answer was not modified (with digital signature as an example)?
The use case is P2P system where I have a public key of the other side and want to ensure I'm actually securely connected to it. The other side however doesn't have my public key and doesn't care who am I.
WebRTC and related specs are too large so that I didn't find clear answer to this question yet (HTTPS is recommended everywhere, but not much besides that), also I haven't found any article that considers WebRTC security from this point of view. Hopefully someone with deep WebRTC knowledge can clarify this question.
Questions that this one was marked as possible duplicates of do not include any proof of the SDP origin (in form of digital signature or in some other way), which is why this question is in unique.

Absolutely! While WebRTC secures its data communication, the SDP is a free ticket to call you.
If you don't secure your signaling channel then you may end up having a perfectly secure call with an attacker, who unbeknownst to you forwards packets to and from your intended call recipient.
This is a variant of Man-in-the-middle attack. See security.stackexchange.com for more.

Related

would TLS prevent others reverse engineer my protocol?

I'm working on a network program and I don't want anyone to know what kind of information is being passed when they sniff the network. Would using TLS achieve this? My main reason is that I want to keep the protocol I'm using to myself for now. If not please tell me if there is anything that can achieve my goal.
It depends on a lot of things, e.g. what your exact threat model is, and how much information leakage you can tolerate.
For TLS to provide adequate protection, these assumptions must be true:
Obviously, you should use a correct implementation, otherwise, if for instance, you are using SecureTransport from iOS 7.0.4, all bets are off.
You should enforce a minimum version requirement and only support secure ciphersuites. If you allow downgrade to SSLv2, you are setting yourself up for problems.
You check for validity of the server public key. You'd be surprised how many client apps skip this.
You use client certificates to authenticate the client, as well as the server, otherwise, it is possible to write a phony client that talks to your TLS server and reverse engineer your protocol. (You can also authenticate the client early in the protocol lifecycle using other means, but that part of your protocol would not be safe).
You keep the private keys secure.
(If you are using X509 certificates and trust chains:) Certificate authorities that you trust do what they are supposed to do, i.e. not sign certificates in your name for others.
You will still leak some packet length and timing information that you hope would not be complete enough for the reverse engineer.
The attacker does not control your client or server or have access to the binaries on any side. If, like an iPhone app, you are giving away the client binary, you have already lost.
Your higher level protocol cannot be tricked into say, redirecting to another server blindly, or lose its mind and do some other crazy thing when the client secure channel is interrupted. This can be hard to notice at times and depends on many other factors.
Something else I have probably missed here.
Would TLS prevent others reverse engineer my protocol?
Probably not. Pentesters do it all the time. They use something like Burp Suite to proxy the connection and watch all the web requests.
If not please tell me if there is anything that can achieve my goal.
Common practice is: if you don't want it stolen, copied, pilfered, abused, etc, then you don't put it on a client. So all sensitive code and data goes on a server you control. Since the client gets to see the request, you have to remove all sensitive information from it.

Man in the middle attack in LAN

I am pretty new in this kind of things.
I have a local area network, accessed by some users via cable some and via wifi others.
I have developed a local application in php which receives only some of the LAN clients as authentic users; they can be identified by the system with an algorithm of key exchange similar to Diffie–Hellman's, to estabilish a secret key. The client then asks to be identified throug such a channel.
The problem is, MITM attack is possible in this kind of situation. I read wikipedia about how such an attack is executed: somebody listens the messages of the two, and puts himself between them creating two different secret keys for the client and server.
This attack is reality, so it must be possible; but I do not understand how it happens in a LAN:
the attacker can listen to the messages, and inject message of his own, impersoning the two subjects of the communications by forging https' IP fields if necessary...
But he can't prevent the original unforged message to reach, concurrently (but also later, because of forging process taking the attacker computer some time) with his malevolent forged one, the recipient! Especially in a wifi connection, which cannot be cut off for a single user, for example cutting his cable.
So, client and server receive two different http requests from each other, a true and a forged one; isn't this a way for them to recognize that such an attack is in progress?
Maybe this question is newby-ous; as I said, I am pretty new at this.
I think that is a scenario where you would use a digital signature (which also uses the idea that asymmetric encryption/Diffie-Hellman uses, that is "public and private key") to sign your messages.
The MITM attacker can not forge a message with a bad "from" and then sign it with the private signature of the original sender. The recipient uses the public part of the signature/certificate to validate the message. So that way he will not only know he is being attacked but also which message is genuine.

How long is an open, secure, TCP channel secure?

We have a web service that acts as a gateway between our clients and another service. The clients send messages to, and receive random messages from, the third-party service. The client's server opens a channel to our web server via a secure socket in order to receive the incoming messages (and not have to poll the server every few minutes).
My question is: is it safe to leave this channel open indefinitely, or should we periodically close and re-open it to obtain new credentials (session keys)? If the latter, how often (hourly, daily, weekly) would be considered "best practice"? I've found a lot of information on secure communications, but nothing to answer this specific question.
Thanks
SSL/TLS (which I'm going to assume you're talking about here) does NOT automatically refresh/renegotiate the session keys being used. There is a renegotiation procedure built-in to the protocol to allow the session keys to be changed within an active session but that procedure was found to have a significant vulnerability a few years back and the renegotiation process was changed (in RFC 5746, see here) to resolve the problem. If you do want to renegotiate the session keys for SSL/TLS, make sure you're doing it in the manner described in this RFC.
That does not, however, answer your original question of IF the session keys should be changed. The answer is...it depends on your security requirements. A good guideline to be used is that any encrypted communications can be eventually decrypted if you see enough of the encrypted data (how practical/doable this is can vary wildly). So, changing your keys every so often is a very good thing to do. If you're passing a small amount of data over a secured connection and the data isn't that sensitive, then you can get away with doing this on a not-so-regular basis (indeed, your SSL/TLS session is probably going to get broken and restablished due to timeouts on one of the two parties on a somewhat regular basis anyway...). If you've got a very sensitive dataset and you're sending alot of data, then I'd suggest rotating the keys every day or so to mitigate this risk (just do it in a secure manner).

TCP secured connection - only via my client

so I have this TCP connections between my server and client, and anyone can connect to my server. But I want to make sure that the client is really using MY client application and not just faking messages from a fake TCP client. What would be the ways to do that, check that the connection really is from my game client?
Thanks!
EDIT
If I'm gonna use TLS, can I solve that problem?
There will probably not be a complete solution to your problem, since whatever you do, the other party might always take your program, run it in a monitored environment, manipulate the runtime data and let it use its "secure" network protocol. Since the client application is in uncontrollable hands, you can never be sure that it is your own program.
Baby example: My application runs your application and plays back the data to your server, and forwards your response back to the application. How can you tell?
That said, it might be a very promising "99%" approach to use SSL and hardcode the client's private key into the application -- with some trickery you can try and make it hard to find (e.g. see how Skype does it). If you then also build integrity checks into your program that figure out whether anyone is manipulating the memory or debugging into your program, you can try and make it a bit harder for a potential adversary. (But note that you will always have to ship the private key with your application, so it isn't really safe from discovery.)
Others have suggested useful answers to your question, but I'm going to suggest another approach. Re-examine your requirements.
Ask yourself why you want to know the identity of the client program. Is it so that you can trust your client program more than you trust 3rd-party client programs?
If you need to trust the identity or integrity of software that you have already shipped to your customers, I claim your security model is broken. Once the software runs on a client's PC, you should assume it is evil, even if you originally wrote it.
Any status, any command, any data whatsoever that comes from the network must be checked before it is relied upon.
My default response is to use a challenge/response authentication.
After connection, send a random number from the server to the client
The client then computes, using a hash/key/.... a response message and returns that to the server
If the response matches the servers computation, your chances of authenticity are better. Note though that a reverse engineer of your client will leave this method open to fraud.
You could use a public/private key pair in order to verify that you are who you say you are.
http://en.wikipedia.org/wiki/RSA#Signing_messages

Secure password transmission over unencrypted tcp/ip

I'm in the designing stages of a custom tcp/ip protocol for mobile client-server communication. When not required (data is not sensitive), I'd like to avoid using SSL for overhead reasons (both in handshake latency and conserving cycles).
My question is, what is the best practices way of transmitting authentication information over an unencrypted connection?
Currently, I'm liking SRP or J-PAKE (they generate secure session tokens, are hash/salt friendly, and allow kicking into TLS when necessary), which I believe are both implemented in OpenSSL. However, I am a bit wary since I don't see many people using these algorithms for this purpose. Would also appreciate pointers to any materials discussing this topic in general, since I had trouble finding any.
Edit
Perhaps the question should have been: is there a best practices approach for secure passwords over unencrypted tcp/ip? If not, what are the reasons for selecting a particular method over others? (The Rooks answer is closest in spirit to this question so far, even if it does violate the letter).
Edit, part deux
I'm primarily interested in the case of client-server authentication, where there is an expectation that both parties have a shared secret (password) a priori.
You should have a look at "Diffie-Hellman key exchange":
Diffie–Hellman key exchange (D–H) is a cryptographic protocol that allows two parties that have no prior knowledge of each other to jointly establish a shared secret key over an insecure communications channel. This key can then be used to encrypt subsequent communications using a symmetric key cipher.
Once you have exchanged a key, you can encrypt your password with this key and transmit it over the insecure protocol.
I still think that SSL is by far your best choice, after all why reinvent the wheal when so much can go wrong? You don't have to buy an expensive certificate if your have a list of "good" and "bad" (compromised) certificates. openSSL is completely free, and i don't see a good reason not to use it.
Some things you might not know: ssl handshakes can be resumed.
Also you can use SSL/TLS over UDP to reduce overhead its called DTLS.
You could use a challenge-response algorithm. The algorithm goes like this:
The server sends a random string to the client.
The client combines this string with the password (by combining, you can xor them or just append them).
The client calculates a hash (for example, SHA1) of the result, and sends it to the server.
The server calculates the same hash using this random number and the real password.
The server compares the two hashes.
Since you shouldn't store a password in plain text, but as a hash instead, the client should calculate this hash at the very beginning.
There are possibly several libraries implementing this, so you probably don't need to code it yourself.

Resources