Best way to get data from text (char *) - c++

Hey,
I'm sending messages via TCP and UDP from clients to the server while the server written in C++. I'm wondering what would be the best, must secure way to send, for example, if I want to send login data: email, password and IP. What would be the best way to send it in a message ang read the data in the server, while this data is stored in char *.
Thanks.

This doesn't really have anything to do with C++. You are asking a generic question about information security. You want to send information via TCP or UDP that includes sensitive information (email address, password, and IP). For this you need to use cryptography.
Cryptography is a complicated area where you should not try to roll your own protocols unless you know a lot about what you are doing. Instead, you should avoid UDP (because it is VERY hard to do crypto properly over UDP) and simply use SSL over TCP.
To do this from C++ you can use the OpenSSL sockets library. Both the client and the server link with the library. If you want a little help, you can debug using sslwrap, a command-line tool that allows you to use cleartext sockets from your client & server, but have the unencrypted data wrapped inside an SSL TCP connection.

As another poster stated, don't worry about C++; use SSL or TLS. This means you will need to acquire a certificate for the server, and that will cost you between $50 and $1500 dollars if you get a commercial one, or you can make your own from a intranet certificate authority that you establish yourself.
This measure will encrypt the communication, and ensure that your client is actually "talking" to the authentic server, not an imposter. However, if you need the client to also be authenticated, then you will need a second certificate (possibly one per client machine, to be precise). If that is too heavy-weight for your client needs, then consider using HMAC to help determine an authorized client from an imposter.

Related

C++ client/server application with single messages and broadcast

I am trying to write a simple client-server application where a client can send or broadcast a message to one or all clients in the network. The server stores all IP addresses that are connected to it, and broadcasts a new IP if a new client connects itself.
I'm not quite sure how to implement the sending of a single message to another client. Would I just have to send a TCP message to the server and put the desired recipient as data in the TCP layer which is then extracted by the server so it knows where to send it?
I also want to add encryption to the messages which would then no longer allow the server to read the data, so I'm not sure how to solve that!?
I am using c++ and Qt5 for the implementation
I'm not quite sure how to implement the sending of a single message to
another client. Would I just have to send a TCP message to the server
and put the desired recipient as data in the TCP layer which is then
extracted by the server so it knows where to send it?
In an ideal world, the clients could talk to each other directly, since they could find out the IP addresses of the other clients from the server (either via its broadcast or by requesting a list of IP addresses from the server). If all of your clients are running on the same LAN, that can work well.
Assuming you want your system to run on the general Internet, however, that won't work so well, since many/most clients will be behind various firewalls and so they won't accept incoming TCP connections. (There are some ways around that, but they require a very advanced understanding of how TCP works, and even then they only work in certain situations, so I don't recommend attempting them in a first project)
Therefore, for a reliable client->client messaging mechanism, your best bet is indeed to have the sending client send the message to the server, along with some short header that tells the server which other client(s) the message ought to be forwarded to. My own client/server messaging system works along these lines, and I've found it to work well.
I also want to add encryption to the messages which would then no
longer allow the server to read the data, so I'm not sure how to solve
that!?
Don't worry about adding encryption until you've got the basic non-encrypted functionality working first, since encryption will make things much more difficult to debug. That said, it's perfectly possible to pass encrypted/opaque data to the server, as long as the aforementioned header data (which tells the server where to forward the message to) is not encrypted (since the server will need to be able to read the header to know what to do with the encrypted data). The trickier part will be when the receiving client gets the forwarded data from the server -- how will the receiving client know how to decrypt it? You'll need some external mechanism for clients to share keys (either symmetric keys or public/private keypairs), since if you sent the encryption keys themselves through the server, there wouldn't be much point in encrypting anything (since the server could retain a copy of any keys it forwarded, and use them to decrypt, if it wanted to)

Is a TCP socket secure or should I always check the user

I have a C++ app that connects to a nodeJS server through a TCP socket.
On socket 'handshake' the client authenticates itself with a UUID known by the server, the server then associates the account to this recognised UUID
Once a TCP socket is open, the app sends requests and the server answers through the same socket.
Is it necessary to add passphrase to every request to be sure the request comes from the client? Or is a socket supposed to be in place and remain in place?
So should I be sure the client is the client:
Only when opening the socket?
Every time a request is made?
The UUID known to the server is normally called a token. And it can be used for your scenario. However it should never be done unencrypted.
What you need to make sure is the following:
An external party (not one of the 2 members of the communication) should not be able to read the token.
The client should not connect to anything but YOUR server.
This is typically accomplished using TLS. (This is what makes HTTPS secure.)
I suggest you do some research into token-based authentication/authorization and TLS/SSL.
One last advice: do not implement the encryption code yourself but use a well used library that has as a result had a lot of testing and has good maintenance.
No, it's not "secure". Your scheme is susceptible to, just off the top of my head, replay attacks, man-in-the-middle attacks, eavesdropping, subsequent impersonation ...
A socket isn't like an actual physical pipe or tunnel. A socket is just an agreement that data marked with a certain source and destination port pair (these are just numbers) are to be treated as belonging to a particular logical data channel. This is determined by handshake and trust. There is no verification.
What you're specifically asking is whether man-in-the-middle attacks exist. Yes, yes they do.
Will requiring a passphrase be given in each packet fix that problem? No, it won't. It will be trivial to intercept and then replay. You're just giving the man in the middle the passphrase.
This is why people use encryption and other clever security schemes. If you're concerned about message authenticity and integrity, you'll need a basic grounding in communications security principles; providing one is out of the scope of this answer.

Sniffing HTTPS traffic from client program

this might be a dumb question...
I wrote a C++ client program that communicates with a web service over HTTPS with the help of the cURL library.
I am wondering if the person using the client can see clearly the traffic originating from his computer using some sniffing program?
Or would he see encrypted data?
Thanks!
Using a utility like netcat to sniff data on the wire, the user would only see encrypted data. The only way to see the raw data is to log it inside the app, before it's passed to cURL, OR to find it in the machine's active RAM (much more difficult since it's likely to be fragmented).
Not if your app checks for valid certificates.
If your users have the ability to use a proxy server with your app, they could use fiddler's decrypt https sessions function to do this, but it results in an invalid certificate which could be made to stop it from working when detected.
He would see the encrypted data. Sniffers only see the packets, so if HTTPS is working as it should, the packets should be encrypted, and that's all the program could see.
If you would like to try it yourself, learn about ettercap-ng.
I doubt that an average user would be able to do that...
BUT there are ways to do this like:
replacing the cURL library with a proxy (if you link dynamically)
running your program under a debugger and placing breakpoints on the cURL functions
replacing the cURL program with a proxy (if you use it as a commandline utility)
digging deep and diessecting the memory at runtime
From my POV it is improbable (since you need some skill + knowledge + some control over the client environment to pull that off) but possible...
The SSL/TLS protocol is typically implemented at the application layer, so the data is encrypted before it is sent.
If the user has access to the certificate key(s) used to encrypt/decrypt the data, then he/she can plug them into WireShark and it can then decode sniffed HTTPS packets off the wire.

Client / Server Cryptography for passwords

I am building a client/server application in C++ and need each client to provide a password. Obviously I want this to be secure during transport so I have been looking into a way of encrypting the password; so that only the server application can decrypt it again.
The problem I am having is not necessarily getting the functions to work, but rather understanding what it is I need to do in order to relate that into code. I am trying to understand and have read MSDN (feels like it) but still I am only learning so really need some clear and accurate guidance on my implementation.
Does this sound right?
I aquire a context to the CSP on both server and client.
I generate a key on the server, or load one (whatever).
and then I
export a public key from the server and send it to the client, the client imports the key and then encrypts the password and returns it so that only the server can decrypt it again.
(Fails when I try).
OR, do I then
export a session key, or an exchange key pair ( single public) which is encrypted with the exchange key pair?
Oh I am so lost, I cannot even explain clearly.
Please help me to understand this...
It really depends on what sort of authentication solution you want to be based one. The options are varied.
You could, for example, rely on the underlying OS authentication. You wouldn't need to manage passwords at all. But this requires a somewhat tighter integration with the domain in which your application is running.
Another option is to use HTTPS and simple authentication. It basically uses SSL to encrypt communication and then sends a username/password pair. Pretty simple, and supported by all web servers. You could probably find C++ code quite easily that takes care of this for you (search StackOverflow for such a question) if you don't want to rely on an existing web server like IIS being installed.
If you do not need the encrypted Communication for other things like data transfer, you can use Challenge-Response for password verification. The Password does not need to be transferred over the network and there is no risk of a replay attack in wich a third party just resends some packets. On the downside, a man in the middle (MITM) attack is possible.
If you need protection from MITM or need an encrypted channel for other communication, you should use TLS with certificates or Public-Key-Encryption with two keypairs.
Do not do anything.
This is very important. Do not implement this yourself.
Repeat do not do anything you will get it wrong.
You should use what is already available. Simply open a connection to an SSL socket and the content of the stream will be automatically encrypted and de-crypted at the other end.
Your application should simply take a username/password tupple and validate if they are correct. Do not attempt to implement the cryptographic part.

UDP Encryption - Simple and Sorta Safe

Heyo!
I am writing an application in Qt/C++ that creates connections between peers. The first step in my protocol is for a new peer to broadcast it's information, soliciting connections from established peers. The location of these peers is unknown.
To do this I am using a UDP Broadcast. Since this broadcast contains information about the peer, I would like it to be encrypted. However, peer authentication happens when a TCP connection is established between peers, so there is still plenty of security beyond the UDP broadcast, but I just don't want to be too easily intercepted and interpreted by a 3rd party.
What I am looking for is a simple way to encrypt the datagram.
Can anyone suggest a reliable method?
Thanks a million!
You can use pretty much any encryption method you want what is more important/difficult is key distribution.
E.G. if all the clients just use the same symmetric encryption method like AES then the broadcast information will be encrypted but anyone who decompiles your client may be able to find out the key.
Have a look at :
How to encrypt and decrypt a file with Qt/C++?
When broadcasting a message to unknown hosts, you will be giving up your IP address and port number. You would have to have a pre-shared key for a broadcast to be meaningful, and as "brain" pointed out, that limits your ability to be secure. If you are feeling sufficiently secure with all clients being able to decrypt as well as anybody who reverses it, then you'll be ok. You can use any symmetric form of encryption and be relatively safe. For the very simplistic, XORing the data could be sufficient in this case.
If you want to be more secure in your broadcast, make your broadcast message a Diffie-Hellman key exchange message. The rest of the exchange after that can be unicast and use different numbers for each client. This would permit a new key for every individual connection. Granted somebody could re-implement your protocols and fake being a peer, but they wouldn't be able to get information from any other peers.