On this blog I regularly publish articles with tips and tricks for the programming language C# .Net.
C# is a modern, object-oriented programming language, which fully ultilizes the possibilites of the .Net framework. I also write about app programming for Android via C#, as well as PHP and Matlab. The difficulty of this blog is supposed to be variable, I hope for beginners and experts there is always something to look for.
If you have questions or suggestions, I am happy about your emails.

Thursday, April 30, 2015

In this post I want to improve the Chat Client a bit further and now, after using RSA to secure the authentication, also encrypt the communication with RSA. That means that every message is encrypted with RSA and can only be decrypted and read by the correct receiver.
Normally, e.g. in PHP, a symmetric key is chosen and encrypted by an asymmetric cipher, and the complete message than by the symmetric one. This is done because symmetric encryptions are notably faster. Here we just use RSA, so an asymmetric encryption, since chat messages are not that long anyway, maybe one could implement the symmetric encryption later.

Idea: When creating a new user now, additionally to the key pair required for the authentication, a new key pair is created for encrypting the communication. The private key is then also AES encrypted (with the password of the authenticaion) and saved on the local computer, the public one send to the database and there stored next the user. If one now wants to send a message to a different user, the client asks the server for the public key via a PHP script. Then the message is encrypted and send to the server. If the receiver fetches this, he decrypts it with his private key, which he made available by entering his login password.

So for the PHP server the encryption is invisible, in the scripts just some variable names changed, and in the database an extra field for the public key for message sending was added. But still one needs to pay a bit attention, especially to the coding of the data, therefore you find some information about the general usage of RSA with C# and PHP combined in the linked post. New is the script getsendkey.php, with which the correspoding public key for sending to a user can be queried:

The class SimpleChatClient now manages a list ActiveChat of the type User. If by the user interface via a click on Send a new chat is started or a message of a new user is received, the user is added to ActiveChats, his public key is queried from the server and saved. When sending the message then this is encrypted with the saved key, when receiving one it is decrypted with the private key. When registering the private key for receiving, similar to the private key for the authentication, is saved locally on the computer, only in the subfolder "send".

I here also created a page for this project, from where, for example, a runnable version can be installed.
Also here I am called bloggeroliver and am looking forward to your messages.

For this client version I currently see the following attacks:

1.) As in the first version of the authentication an attacker now can simply replay messages of a logged in user, like for example fetch my messages oder send a message. The reason for this is that in these always session ID and / or cookie is send with them and this data is always the same.
Solution: Usage of encryption, for example TLS. Because of the mentioned reasons I do not want to use this, therefor: All requests are signed by the client and the signature is checked by the server.

2.) The server is not authenticated to the client, which is especially problematic when the client queries public keys from the server. A man in the middle could intercept these and change them, so that now his public key is sent and he can decrypt the messages. Solution: The sever encrypts its answer with the private key of the recipient (or better: The server also gets a keypair and signs the answers).

3.) Sender and receiver name are sent as plaintext and thus can also be read. Solution: Also encrypt these.

I will implement these solutions and publish the new version on the project page shown above, but write no more posts about it, since the idea of such a program now should be clear.
Except these I currently do not see any other vulnerabilities, and thus would declare the client as safe then.
I am looking forward to comments and discussion, especially if you can find different ones.

Tuesday, April 28, 2015

I here want to build upon the Chat Client, which was presented in an earlier post, and remove a security issue mentioned there.
In the previous version the user chose a password when creating an account, the password then was sent to the server and saved as a hash in the database. On every login process the client sends the password of the user, the server then compares this with the saved one and thus can authenticate the user.
But now every one with access to the network traffic, for example a user in the same network or an attacker with access to internet nodes etc., can see and read the sent login message, and either read out the password or simply resend the same message to authenticate correctly. Because of this also encrypting the message would be of no use, we have to come up with something else.
The default choice would now be SSL / TLS, an encryption protocol for secure data transfer. For this (but also depending on the choice of usage) via a public key system a key is chosen, with which the communication is encrypted and thus not readable anymore (also the key is always different, so the login messages are different too). But for TLS a certificate is needed, which authenticates the server. Probably not everybody has one and it will also probably be not free to get.
To ensure the easy and universal usability of the client, I thus set TLS aside and implemented a small custom, also based on public key cryptography, method: A so called challenge - response authentification. As a short introduction to asymmetric cryptography I can recommend the post about RSA.
A challenge - response authentification is, as the name already says, an authentication protocol, in which the server asks the client a challenge, which the client then has to solve (response). This can, for example, like here, be done with a public key algorithm.

The idea: When creating a new user account a new RSA key pair is created. The public key is then sent to the server, this saves it next the username in the database. The private key is saved on the computer of the user, but encrypted with AES and a chosen password. If the user wants to log in, he first loads his private key from the file by inputting the password. He then connects to the server, which encrypts a random string (here a combination of username, current time and 16 bit random number) with the public key of the user and sends it back. The user now can decrypt this with his private key and sends the decrypted string back. The server then compares both strings and logs the user in, if they match. Because: Under the assumption that RSA is secure, only the correct user can decrypt the string. Further, all messages can be send openly, reading them does not endanger the security of the system, since every time a new string is the correct login response and the public key anyway can be known (attack possibilites still exist, but this method is already way more safe than the one used before - a total security can never be ensured anyway).
I have to highlight here though that this method alone is useless - without additional methods such a replay attack is still possible. Although the actual login process is now safe, the messages of a user logged in through a PHP session can simply be replayed - in these always session ID and / or cookie is contained, which can be read out or simply replayed. Then the server cannot distinguish the valid user and some attacker. As already mentioned, TLS solves this problem (but then already the simple login method would be enough), and in the next post about the client I mention a self made solution.

The code: As described in the post about RSA encryption in PHP, we first download the library phpseclib and then upload this into the folder of your PHP scripts.
The script register.php stayed the same, only the parameter password now is called pubkey:

First the public key of the submitted user, created during registration, is loaded from the database. With this we then encrypt the challenge and output it. But we now already set the username in the session and also save the challenge it it, to be able to later verify the answer.

The submitted decrypted challenge is compared with the saved one and on agreement the current user is logged in by setting the session variable LoggedIn.
Important is also the query whether the challenge is empty, since otherwise an attacker could possibly create a new session with an arbitrary username (and thus an empty challenge)!
The scripts send.php and receive.php are the same, except that in them the session variable LoggedIn is checked.

In the C# code I will only show the changed code parts, a majority is of course the same, especially the complete client user interface and a majority of the class SimpleChatClient. To this I added the class Crypto:

The functions AESEncode(), AESDecode(), RSAEncrypt() and RSADecrypt() are known from the previous posts about AES and RSA. The function CreateSymmetricKey() derives by the PBKDF2 algorithm out of the given password an encryption key and IV and returns these. The function CreateRSA() is called on every registration of a new user, with this a new key pair for RSA is created. With the passwort chosen by the user CreateSymmetricKey() is called and with the returned data the private key is AES encrypted and written into a local file. The function GetRSA() is called on login, it reads and decrypts the private key from the file.
The function Register() was changed in the obvious fashion:

First the script prelogin.php is called and the challenge outputted. Then the private RSA key is loaded and the challenge decrypted with it. Eventually the result is sent back as a Base64 string and the user by this authenticated.