in reply to
Good IPC Message Protocols?
I'd like to assume that my non-privileged client has been completely hacked, so I want to make it as hard as possible for the baddies to crack open the privileged process. I want to pretend bad guys can send anything at all down the socket at my privileged process.
If the client has been completely hacked, what is to stop the bad person simply finding and copying whatever obfustication you are implementing ?
As far as the framing of each message is concerned, I would:
have a message type field, so that you can change or improve things in future.
pack the elements together using: $data = pack((n/a*)*, @elements). It's up to you whether you treat those as name/attribute pairs...
prefix that packed data with its length and type, and append a 32-bit CRC (String::CRC32):
$message = pack('n', $type) . $data ;
$framed = pack('N', length($message)) . $message . pack('N', crc32($message)) ;
if the CRC passes, it's likely your message is intact, and you can unpack it. In the unlikely event of a CRC failure... I'd log it and close the connection. If you wanted to get fancy, you could have an error message type, and send one before closing...
I guess you have some sort of password authentication when the client connection is established ? What I would do is as follows:
add a NONCE to the message:
$message = pack('Nn', $nonce, $type) . $data ;
where the NONCE is a random 32-bit number.
now for the authentication step I would send an authentication type message to the server, where the data portion is a TOKEN = MD5(password XOR NONCE).
When the server responds to the authentication that message will also contain a NONCE. Both ends should compute and remember SEED = MD5(password XOR NONCE). The SEED is now a shared secret, based on the password.
for each message I would take MD5(SEED XOR NONCE) XOR that with the $data part of the message after having taken the 32-bit CRC. (Of course, this step must be omitted for authentication messages.)
This is by no means a strong encryption ! But it will take a lot more than casual interest to decrypt a message, and each one is XOR'ed with a different "key". However, in order to create a fake message, you need the current session's SEED... which is hard. The SEED changes for each session, so replay attach is also hard. (To protect against replay attack during a session you could introduce a sequence number in each message -- starting from a random value at the start of each session.)
Because the CRC is taken before the "encryption", the CRC will fail if the data is incorrectly encrypted.
If the client is so completely hacked that a bad person can find the current SEED while a session is in progress... then you have a very serious problem. You could limit the damage by requiring periodic re-authentication -- which requires the password, which one assumes the bad person doesn't know. Beyond that... I don't know -- it looks like an almost impossible requirement (and I guess that requiring the password for every transaction would be ineffably tedious.)