- Project page: https://github.com/TheFox/phpchat
- Documentation: https://github.com/TheFox/phpchat/wiki
In January 2014 I though I must fight against the mass surveillance of the Internet. Each big site on the Internet is writing about this topic but nobody wants to fight against. If nobody on the Internet cares about security and privacy we must take care about ourselves. So I started this project. We need to encrypt and secure the Internet. The Internet is broken and we need to fix it. Thanks people like Edward Snowden we know today that the NSA (and also other intelligence agencies too) operates a global surveillance on citizens. We can’t lose our right of freedom, our right of privacy to centralized governmental authorities.
But not only governments spy on citizens. Also Google reads your personal emails while using Gmail. Apple censors informations.
Now it’s our move. It’s time to fight back!
Bitmessage
I also like the Bitmessage project. But building thinks by myself feels like I can contribute to the Internet. And programming this with PHP because it’s an easy-to-learn programming language and every one can contribute to this project.
Multithreading
Building a decentralized, peer-to-peer, encrypted chat is not that easy. The every first version of PHPChat I wrote with pthreads. But after 2 months of programming PHPChat with pthreads I decided not to contaminate my project with pthreads. At some point you can’t continue programming with pthreads. So I killed pthreads from PHPChat and re-coded everything with my own version of a IPC layer. If you need to run multiple Threads don’t use pthreads. Just don’t use it. Use fcntl_fork()
in combination with IPC layer instead. My personal favourite is to create a single php file for each process/thread. But it always depends - of course - on what you want to do.
Frameworks
At first you need do decide what framework to use. I used no framework to build the basics of PHPChat. After a while I added Symfony’s Console Component to handle the command-line arguments and Kevin Le Brun’s colors.php to make some magic in the terminal. Simple tools always have a huge benefit. Another such a tool is Ryan Chouinard’s ByteSize.
Protocol
The second you need to do is to design a network protocol. I was always a fan of decentralized networks, the idea of building a network without a centralized server no one can take down. So I used the Kademlia algorithm. But it was not exactly Kademlia from the first line of code. Starting at the fact that PHPChat doesn’t generate a new UUID for each node start. So I think calling it Kademlia is wrong. I used the k-buckets system of Kademlia for a while. But why make the (file)system complicated[1] when there’s is a simpler way? Like Kademlia PHPChat uses XOR metric to define distance between two single nodes.
I also decided not to use a binary format for a single network packet between two nodes. PHPChat only uses Base64 and JSON to create a network packet. Only a “\n” is used to detach a single network packet from another. I know that JSON has a huge overhead compared to binary formats but it’s just simpler to debug and simpler to understand for human. People using PHPChat and developing PHPChat are human.
GUI
Because I hate building grafical interfaces for users I built an IMAP- and a SMTP-server instead. The user can decide to use an email client like Thunderbird or the good old command-line interface for sending messages. I prefer to use the command-line. The Console of PHPChat is a kind of shell. It’s like a shell written in PHP.
Here is an example of using PHPChat with Thunderbird:
Bridge
I took the basic idea from the Tor Project. There are multiple ways to implement a bridge. Here are two:
- Forward the original source node ID and public key. This is the simplest method to implement bridges. But it also provides no anonymity for a bridge client node. Only the IP address and port are not known to other nodes.
- Generate for each source node ID an alias node ID (salted with a unique password for each bridge server). Harder challenge to implement but more anonymity for each node. Only one bridge server knows the real contact informations about the destination node. But there must be also an alias-table for each bridge server. This means more data.
The challenge is not to route an offline message to the original path of the destination node, but route the message to the corresponding bridge server if the destination node is defined as a bridge client. So it must be obvious for all nodes that a single node is a client of a bridge. Also inside the bridge tube there must be a route to the destination node.
[PHPCHat is still under development. I created this post a while ago but I decided to publish it on 2015-02-25 because I don’t know if PHPChat will be released under a stable version in a foreseeable future.]
Footnotes
- [1] The simple things in life are often the best.