Client / Server Cryptography for passwords - c++

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.

Related

How to implement secure socket communication in c++ application using winsock?

I am trying to implement secure communication between a server and client in c++. The limitation is that both the client and server must run on windows and have to be in c++. This is for a research project I am working on at my university.
So far I have found that SChannel is the best option, but the documentation is extremely confusing and I can not find any guides/tutorials on how to use it. I have already looked at this link https://learn.microsoft.com/en-us/windows/desktop/secauthn/creating-a-secure-connection-using-schannel but still do not understand how to get it working. Could someone guide me through this if this is the best way?
I also looked into use SSLStream using the CLR to have .net run inside of a c++ application. However I can not use this because the client application is threaded and threads can't be used with CLR.
I already have a dummy client and server set up with communication between the two, I am just trying to secure and encrypt that communication.
Any help is greatly appreciated!
Whichever SSL library you choose to use there are a few things you need to know as a beginner in this field:
The server and client implementations will end up looking quite different in places.
Your server is absolutely going to need a certificate with a private key. During development you clearly don't want to get one from Verisign or something so you need to create a self-signed certificate. You can do this with openssl or other tools.
The certificate consists of a private part and a public part. The public part needs to go to the client, and will be used to validate the connection. When you are using something like SChannel the certificates (private and public) will need to be installed in the certificate stores of the server and client respectively.
SChannel does not send or receive data for you. So the core of your implementation is going to be: when the network has data: read ciphertext from socket and write to SChannel. Read clear text from SChannel (if any) and pass to application. When the application has data to send, get clear text from Application and pass to SChannel. Get the resulting ciphertext buffers from SChannel and write to the socket.
buffers from the internet may be partial, and negotiations and re-negotiations means there's no 1:1 mapping of passing data into SChannel and getting data out.
You therefore can't get away with a naive implementation that calls SChannel once to pass data in, and once again to get un/encrypted data. There will potentially be nothing available, or a whole lot of packets to send between the client and the server, before you'll get any application bytes. i.e. You will need some kind of state machine to keeptrack of this.
Obviously, don't write both the client and server at the same time: Start with your client against an https server.
That's the general outline of the process - the things that confused me when I first encountered SSL and why none of the samples were nearly as simple as I had hoped them to be.

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.

Algorithm for client validation?

Here is what I am trying to do.
I have a game and a server executable. The clients connect to the server to play.
The concern I currently have is that someone might use telnet or something to simulate a client.
Currently, the user only sends a simply hello string after they are connected and if it is correct I accept data from them.
I have tried to use certificates / ssl without success so I am trying to figure out an effective way to know if a game client is really a client.
Simply put, what would be an effective way to validate the client?
I am not concerned with a man in the middle attack since the users do not login nor provide passwords, just a session name.
I have thought of the possibility of the server sending a fixed length random string, then the client modifies this string with an algorithm, then sends it back.
I am wondering if there are better more clever ways than that.
I do actually have a certificate for my server, it is a pfx, if that helps.
Thanks
Its intrinsically difficult as a problem. Certainly there is no software you can write, that could run on a foriegn machine, that can proves its the program you wrote in an un-tampered form.
Still, there is some simple challenge response stuff you ca do to improve things.
Lets assume your client and your server share a secret (your writing it, so they can, though being software it wont be very secret.) Lets also assume you have ahandy crypt or hashing library (for things like a SHA-1 hash) Then:
Server send challenge, including a nonce (eg the time + random number).
Client sends a response, which includes a secure hash of (nonce + secret)
Server know the nonce and the secret, so they can check the hash received is correct, and thus can confirm the "client" also knows the secret.
This is a basic symmetric validation scheme.

c++ encrypt a text with a key received over packet? keyczar?

I'm storing a client's password in his device and there are times when clients need to send their password to server.
When a client connects to me(server),
I give him a key that will be used for encryption.
I want a client to send a encrypted password by the key.
Server will decrypt the password with the key(which was stored) and
verify the password.
Even if it may not be perfect, it sounds more secure than using one static key stored in client and server.
Sounds simple enough and I was looking at c++ encryption library(crypto++), bleh looks too complicated.
Found there is a easy one to use. Keyczar.
But doesn't seem to offer the functionality that I need.
Keyczar seems to require to generate a file that will hold encryption key, and this file is generated by one of their tools, which will be too much hassle to do it on the fly.
If this can be done in c++ or keyczar(I may have missed what it can do)
please enlighten me how to.
Thank you.
Linux/Mac platform.
If you are sending the key to the user immediately before the user uses it to encrypt his or her password, you might as well be sending the password in the clear. (You're sending all the data required to reconstruct the cleartext password, anyway.)
A better method would use TLS to encrypt the entire conversation using a nonce-protected (to avoid replay attack) randomly generated session key.
If you really wanted to be fancy, you could use client-side x509 certificates to authenticate the client for you -- then you wouldn't need passwords on the server at all. (But you might still want to use the password to store the private key encrypted on the devices.)
If you like the idea but dislike TLS because x509 is supremely complicated, perhaps it would be easier to integrate ssh session management, using ssh keys. ssh keys are far easier to work with than x509 keys, but their simplicity means they aren't applicable everywhere.
if the key exchange is not secured, you'll gain absolutely nothing (except reduced replay attack); perhaps simply look into TLS/SSL for the purpose of securing the transport

Best way to get data from text (char *)

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.