Posting data to a server securely via http

Hi,

I want to post some login information to my server, however, as I have found out using openssl is out of the question. I wanted to see how other people had got over this issue. I know that for me it is a small project and that the likely hood of someone wanting to attack my system is small to non-existent, however, this is a learning exercise for me so I want to get a solid implementation that I can then work with in the future.

The idea that I had was to encrypt the data with the library by MarkT found here: http://forum.arduino.cc/index.php/topic,88890.0.html and then the Arduino and the php server would know the same key (hardcoded into both(This I guess is another security issue)) so the php server could decrypt it, however, if someone captured the message sent by the arduino they could repeat it which would make the project vulnerable. I would plan on using many arduino's not just one. I wonder the thoughts on adding a digital signature to the post.

Obviously being able use the public key would be best, however, I don't want to use the Arduino Yun or have to go to a raspberry pi to achieve this so that is out of the question. I am using a Mega 2560.

Thanks

Use AES.

As long as you can hard code the private key into your server code its fine. You can send the initial iv as part of the query string ( or post data ).

Using base64 you can encode the encrypted AES data, which is suitable for sending the data directly in the query string.

EDIT: Use a hash of the data which your PHP server saves, then reject on repeated attacks. As the IV changes the data should never repeat, and therefore can be ignored. Also use a message ID which is part of the hash. This provides a mild digital signature as the data, CRC, and hash will only be correct on valid data, so if the ID is processed it can be dumped.

I have used this approach with great success. I haven't got my TLS library handy, but here are the parts I used to build it.

My URI / Percent Encoder, useful for web server/clients. My base64 encoder

My lib for streaming CRC values

MarkT's AES library which I pulled apart for my own lib.

EDIT: didn't notice you linked the same AES library :)

I found this: https://github.com/arpitchauhan/cryptographic-protocols-arduino-and-PC

Which has Diffie–Hellman implementation. I have not looked at it as yet but surely that would be the best way to go over AES? Also what about man in the middle attacks?

Diffie–Hellman would be far more secure over a single private key ( it is only a method of sharing keys, not encryption itself ). As the shared key changes every time you re-do the DHE the attack complexity escalates dramatically. No reason not to use AES as the provider of encryption.

Man in the middle should be fine as symmetric encryption is either defeated or requires brute force cracking. Its usually the features surrounding the encryption which cause it to fail. Take WEP security, it failed because the initial TCP ack packet is known, so crackers already had plaintext data to help break the encryption. Here is a good read http://blog.agilebits.com/2011/08/18/aes-encryption-isnt-cracked/

I don't understand why man in the middle attack is not relevant. Surely if the attacker captures the message sent and replays it to the server it would accept the input and produce a result?

Sorry I edited my initial post a few times, you may not have seen the paragraph I added.

Use a hash of the data which your PHP server saves, then reject on repeated attacks. As the IV changes the data should never repeat, and therefore can be ignored. Also use a message ID which is part of the hash. This provides a digital signature as the data, IV, and hash will only be correct on valid data, so if the ID is processed it can be dumped.

CRC was meant to be IV, corrected above.

Hi I read your reply and wondered about the repeat message issue. I agree that the message should not repeat, however, if I use the Diffee-Hellmen to generate a different key and then use the AES that I send, theoretically there could be the same ciphertext for a different key meaning that a valid message will not get correctly read. Also the data will be sent fairly often so the chances of this would increase as the amount of hashes that I store increase.

Edit: Another question -

pYro_65: You can send the initial iv as part of the query string ( or post data ).

Are you saying send an unencrypted key to the server to initialise it?

theoretically there could be the same ciphertext for a different key meaning that a valid message will not get correctly read.

If the message ID, and IV are included in the data hash, then the hash value will never be the same.

If a packet is resent, the IV will produce a different cyphertext. If a new packet is sent the ID will be different as well as the IV.

So you will never receive two hash values which are equal, regardless of the cyphertext. If you do receive an ID, hash or ID/IV combo that has repeated, you know something is wrong.

This is all assuming you are using AES-CBC and a hashing algorithm which produces unique signatures for all permutations of data.

Ahh okay, I see.

The only last issue that I see is that I can restart the arduino which would reset the message ID from the beginning. What method would you employ to inform the server (Bob) that the message arduino has restarted from the beginning again and should wipe all previous sent messages. Or in fact tell the device to continue where it left off?

You can use the EEPROM to save the current ID.
it has limits if 100,000 writes, you can use techniques similar to what SSD’s use to spread the data over the eeprom rather than burning out one cell. You could get millions of writes this way.

Even better, use another hashing algorithm and say an RTC module on the Arduino.

Create a block of data repeating the time from the RTC, then hash it.
Then use this as an ID, it will be unique. For security, its non sequential and does not need to be stored.

The purpose of this style of ID is to provide validation of a single message, not to identify it in a pool of messages. As in it has no meaning to the data, just the hash cannot be created without it.
If the system dies, no worries just set the time and the unique ID’s are restored.

There is nothing stopping someone creating their own data to send, as a sequential message is just as easy to beat as a hash, its all down to AES having a secure key.

Packages like SSL and Kerberos gain their security by making a shared key’s lifetime as short as possible. Literally the only thing going for them is the fact it takes so long to brute force an algorithm., by constantly changing the key ( or IV ) it means you have to restart the brute force and also limits the amount of data encrypted to a single key you can grab. Once the encryption algo is broken the TLS is useless.

pYro_65: Create a block of data repeating the time from the RTC, then hash it. Then use this as an ID, it will be unique. For security, its non sequential and does not need to be stored.

The purpose of this style of ID is to provide validation of a single message, not to identify it in a pool of messages. As in it has no meaning to the data, just the hash cannot be created without it. If the system dies, no worries just set the time and the unique ID's are restored.

Sorry to ask more on this as like I said before I want to do this right and I am also reading Practical Cryptography by Ferguson and Schneier and as they seem to continually write "We already have enough fast, insecure systems. We don't need another one". So my question is are you saying to have a random block of data that both the server and arduino have AS WELL AS a key used for the DH key exchange. This random block is used with the RTC to create a one time code like that used in Google authenticator?