DEV Community

IJustDev
IJustDev

Posted on

The ultra secure chat

I know what you're doing

Have you ever wondered who else has got the ability to read through your chat messages? Who can see your naughty pictures and the unfunny memes you've sent to your friends?
Well this shouldn't shock you that much since you're in the DEV community but you are not the only one.

Especially if you use services like WhatsApp, Instagram or any other service powered by a company.

The Problem

Although knowing all of this, I don't know anybody who ever dared switching to a more secure messenger (at least nobody who had nothing to hide). All these big messengers are way to comfortable. You just install any app, the contacts will be auto-imported to the messenger and you're good to go and you can send messages to your friends, family (including grand parents) so on and so forth.

Almost everybody on this earth is using an messenger you can contact him over, this comfort just makes switching an disaster. And by this blog post nothing will change, since you give away much more comfort by using this than you're doing by using Signal or Telegram).

So... What is this?

This is a brief overview of my latest chat concept named asfaleia (Greek word for security). It does not store any data on the server and the clients only authenticate through public and their correlating private keys. The project itself (by RoyalZSoftware) isn't finished yet. I mean it's in the rapid development phase and just consists of two commits. So if you've understand these concepts and want to work on this project, feel free to do so
github.com/royalzsoftware/asfaleia

This article will cover the basic concept of my chat idea with some deeper specification concerning the packets. There are more than a few possible enhancements, especially on the network part (since I'm a noob at this topic), but let's dive in.

General

The server used by asfaleia is a simple TCP server written in go. Just a few lines by now.

l, err := net.Listen("tcp4", "0.0.0.0:3308")
if err != nil {
    fmt.Println(err)
    return
}
defer l.Close()
for {
    c, err := l.Accept()

    if err != nil {
        fmt.Println(err)
        return
    }
    go handleConnection(c)
}
Enter fullscreen mode Exit fullscreen mode

Where the handleConnection(c) function is invoked inside a new thread to handle each client simultaneously.

Currently not developed but planned is an Message struct containing an message, an receiver and an sender.

Communication itself and Contacts?

Authentication

The protocol uses ssh keypairs to verify identities. In order to tell the server now that you are this "public Key" the client sends an AUTH-Packet with his public key to the server.

The server then generates an random string which will then be encrypted with the sent public key.

After this procedure the server sends back an ANSWER-Packet containing the encrypted message with an handle, which in plain would look like this:

# Client sends following
0;MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1DGPUSPqPJdcWvdBNM5ymAQlKIXbLMa3X4D0JaBKKqv47w4ii3sLw2lckEHk+8LGyBNkbQN0aaVxWeuo4R7IsBMXVpJgvf/iQImRm5b9HIxkAYi5PqYGcHKBqiuzuHmpPlGYdGpM+hK5EeWiDj/sRVcP42KyYzGmd6ExbqaWMewIDAQAB
# Server sends back following
1;1238013;aMbZ55lweKk7+grkGQhzZHkl2Jt6cjKxzmnQ+gq6ydsYzs1830JqNgcZzbTsHI9hSOvuii6AXwF0WY6WnHnKsANDdC+mTDcvz51D2eiwt27xEK5N2toiJ0bE4SJcf25vtTi9hKH3D/xVpdEzXcH3vMNiB4UKl410eF33PijI4Ws=
Enter fullscreen mode Exit fullscreen mode

Where at the both packets 0 or 1 stands for the packet identifier. In the server-response example beginning with 1 the second argument after a ; is the handle that the client needs to pass in the AuthVerifyPacket he will later send. The last field is the encrypted message (in this example it's just a plain Hello World) base64 encoded.

Upon receiving this information the client now sends an AuthVerifyPacket

2;12380138;Hello World
Enter fullscreen mode Exit fullscreen mode

If this works the client receives an jwt auth token verifying his identity which he will later needs to pass to every request.

Sender

But how could senders and receivers be anonymous within a chatroom? Technically they can, but sure enough it depends on the way they are using these program. You can't be anonymous if you make yourself identifiable with any chat message.

The protocol itself uses ssh keypairs to verify their identity. Conversation partners can now use the ssh public key of the receiver, encrypt their message with it and send a packet to the server containing:

  • The public key of the receiver
  • The (with the public key) encrypted message

Receiver

The receiver can send an GET-Packet which returns all the Message[] messages stored in an two-dimensional array. Once the server has finished sending the messages those are removed from the array so nobody ever can find out what was sent.

Drawbacks

Although it's safe that none data is save to the disk, this also means that there isn't a chat history you can scroll through or any other thing related.

Furthermore you can't just write somebody with an contact, you need his full public key which you need to transfer.

Conclusion

Well although this won't be used for mobile applications there may be a use for hidden services. If you like this approach and want to help developing this feel free to do so on GitHub.

How much do you value your privacy? Leave a comment!

Top comments (0)