Simple (but good) Message Encryption? #5596
Replies: 1 comment
-
Posted at 2015-05-15 by joppiesaus Is XOR Encryption with the One-Time pad an option for you? Here's some pseudo-code:
Posted at 2015-05-15 by @gfwilliams I guess the problem is how I'd go about changing that key - as I understand it, if I use it to encode multiple messages then it starts to be pretty easy to work out what the key was... For instance if I just sent 1000 packets and random data over the air using the same pad, you could listen in, take the average of all packets, and you've basically got the key :( Posted at 2015-05-15 by joppiesaus You are right. But this is actually not a problem if the data is 100% random, because the chance that the message is "Attack from the north" is the same as "Attack from the south", or "I like cats so much!!" Posted at 2015-05-15 by Mike Take a look at: http://bitwiseshiftleft.github.io/sjcl/ AES is a well tested standard, and has low resource requirements. I can't speak for the safety of that particular library, but they certainly have some good credentials. I think it would be possible to trim down that library to fit on an Espruino, especially since you already have some components implemented (SHA-256). Posted at 2015-05-15 by @gfwilliams Thanks! That looks really interesting... Posted at 2015-05-16 by d0773d @gfwilliams With encryption, I think custom compiling an encryption library into the firmware like the one I mentioned in the "shiny ui" thread should run faster than using javascript. I've tried using other Aes javascript libraries in the past found them to be too memory intensive and I kept getting the out of memory error in the console. Posted at 2015-05-16 by DrAzzy I tend to agree that this probably ought to be in the firmware, not JS... I get the impression that the JS implementation would be memory intensive, both in terms of code size and variables. We already use a lot of RAM for JS modules with AT and ESP8266WiFi. If we add JS encryption on top of that, I worry that there wouldn't be much ram left for user code. Posted at 2015-05-16 by Stevie I also think that Blowfish is a very good cipher. Fast, low resource requirements. And coming from a very well known and reliable source. There are many free implementations in all kinds of languages: https://www.schneier.com/blowfish-download.html Posted at 2015-05-17 by the1laz There's an stm32 cryptographic library: http://www.st.com/web/en/catalog/tools/PF259409 It would be handy to have access to things like aes as a native module for performance reasons, but I guess it'd have to be an optional inclusion into the firmware add must people wouldn't use it. Posted at 2015-05-17 by d0773d @the1laz Encryption can be confusing and combursome for someone to implement or at least for me when I started reading about it. I think Encryption needs to be easy to use in order for more people to use it. Like handling keys and etc... automatically in the background. Maybe if more people requested encryption support for the espruino, someone could donate their time to add encryption? I currently offload encryption to the Intel Edison which also handles the network side. The only issue I have is how long the Edison takes to bootup. I like the instantaneous bootup and code execution feel that microcontrollers have. So, ya having encryption would be a major plus for the espruino :) Posted at 2015-05-18 by d0773d Also, here is an informative post about AES encryption: http://stackoverflow.com/questions/1220751/how-to-choose-an-aes-encryption-mode-cbc-ecb-ctr-ocb-cfb Posted at 2015-05-18 by @gfwilliams Thanks - I totally agree a firmware implementation seems like the best bet. That crypto library got posted before - it sure looks good (hopefully it's quite efficient)... I could swap the current SHA implementation over to it as well. I didn't realise AES could work on 16 byte blocks - it definitely makes it much more of an option for low power radio. However: I'm very conscious that even good encryption that's applied badly can be useless. It'd be interesting to see if there are any good examples of using something like AES in this area (low resources and a pre-shared key). Posted at 2015-05-18 by Pinnchus A simple but effective message encryption could be http://en.wikipedia.org/wiki/XTEA it is lightweight and should be fast enough. Posted at 2015-05-19 by @gfwilliams Wow, thanks - that looks good. I guess it's not quite up to AES? but then the resource requirements are tiny... It seems like a perfect solution to this kind of problem. Posted at 2015-05-19 by Pinnchus If you like it, you could take a look to this js implementation http://www.movable-type.co.uk/scripts/tea.html Posted at 2015-05-19 by LawrenceGrif @user54159 thanks for this on the moveable-type page there is a line to Block xxTEA Would that be a better choice? Posted at 2015-05-19 by Pinnchus May be..., As I see both implementations are very easy to try, I suppose we can do both as a module. Posted at 2015-05-19 by AntiCat I recommend Blowfish http://en.wikipedia.org/wiki/Blowfish_(cipher) It has however a significant initialization time (I expect 100 ms.) and quit a large RAM footprint 4k. If the initialization happens only once per boot the initialization time should not be an issue. You can run any block cipher in two parallel modes - Counter Mode for Encryption and CBC Mode for Message Authentication (Cryptographically Secure CRC). Note, I basically described here the CCM mode. The last block of the CBC output is used as MAC/CRC. Keep in mind that you should use a different initialization vector (basically a random value) for every new message to prevent static analysis of the data. Posted at 2015-05-19 by Pinnchus Sure blowfish is one of the strongest algorithms but it is a heavy resource consuming too and don't know if it is really useful for this kind of use. Posted at 2015-05-19 by Stevie While I initially also proposed Blowfish, I now think that maybe due to limited resources XXTEA is a better choice. As a test, I implemented a C library which can be used to encrypt / decrypt strings using XXTEA. The code consumes roughly 1500 bytes. A test with encoding 10000 strings of 1000 bytes each took about 20 seconds, leading to about 500 KB per second encoding speed - decoding should be the same. That sounds pretty nice for me. Posted at 2015-05-20 by Pinnchus @stevie, Would you mind to share your C library? Thanks, Posted at 2015-05-20 by Stevie @user54159, sure. But it's not really much. I guess Gordon will do a much better version at some point. This was more for experimentation, quickly hacked together. Due to the fact that xxtea needs to have the data with a size of multiples of 4, this version can only treat strings which do not contain the 0 character. I use it as a padding and also to detect end of string when decoding. To include in the makefile put the following before "endif # BOOTLOADER":
Then you will be able to write something like this in JS:
The key needs to be exactly 16 characters, the data can be from 1 to 1024 bytes, because it will be copied to a char buffer. Attachments: Posted at 2015-05-20 by Pinnchus Thanks!!! Posted at 2015-08-27 by @gfwilliams Just to update this, here's an implementation in JavaScript. Just needed some minor tweaks for Espruino:
Posted at 2015-08-27 by @gfwilliams Just to add, we could use Uint32Arrays here which would end up being a bit more memory efficient. Posted at 2015-08-27 by Stevie Cool. It would be interesting to know the relative speed of the C implementation and the JS implementation. I guess for most things it does not matter that much, but it would be good to know. Posted at 2015-08-28 by @gfwilliams The JS implementation is going to be significantly slower - maybe in the 100x range? So something built in would definitely be preferable - but this is a good stopgap for very small amounts of data. Posted at 2017-02-07 by @MaBecker Hi @stevie and @gfwilliams This is so cool, like to setup a PR to have this in master, if you don't mind ? Posted at 2017-02-07 by @gfwilliams Do you mean the JS version, or the C? There's already proper AES crypto in the Crypto library: http://www.espruino.com/Reference#crypto Is that not compiled into ESP8266 now (which I guess is what you'd want it for)? We could add it, but some devices are getting short on flash now and I wonder if it's a good idea if AES is available. Posted at 2017-02-07 by @MaBecker Sorry for not being specific enough, I am talking about the C part.
What about a Posted at 2017-02-07 by @gfwilliams We could do that, yes. But what is the reasoning for it? Can you not just include AES in whatever platform you care about? I would imagine that is a much more secure encryption method? Posted at 2017-02-07 by @MaBecker I want to have a simple and good encryption and decryption as a balance of size and security. On ESP8266 there will be no https with Espruino as far as I unterstand. So I was thinking about to secure the content thats being send and received. TEA seems to be simple to implement in C or in JS, both are available as source in this thread. Tried to include AES on ESP8266, looks like no one tried this before :)
Posted at 2017-02-07 by @gfwilliams Odd errors to get - there shouldn't be specific build options for AES stuff so I don't know why you're getting those errors. Add TEA as a PR then. It may well be that it adds extremely little to the code size in which case it'll be nice to add to everything Posted at 2017-02-07 by @gfwilliams It'd be good if you could add it as part of the Crypto module though, rather than its own XXTEA namespace Posted at 2017-02-07 by @MaBecker That's what I will do ! Posted at 2017-02-08 by @MaBecker one more try to make ESP8266_BOARD
no idea how to fix or if possible at all Posted at 2017-02-08 by @gfwilliams That looks like a RAM usage issue? I guess you'd have to reduce the amount of variables? Posted at 2017-02-08 by Wilberforce I've put comments on your GitHub issue... it's the static tables that by default got to ram... The errors in #33 above are due to the headers not being included. Posted at 2017-02-08 by CanyonCasa First I've seen this thread, but I can suggest an alternative less resource intensive solution that I have used... Assumptions... @gfwilliams initial premises of low resources, low message overhead, validating message integrity, use of a predefined secret, and use of the built-in SHA256 hash function; however, no message encryption. This can be extended to Puck.js security as well. Consider that sometimes authentication of the message can be more important than the actual message -- the message bears the kings seal! For example, if I want to read a sensor value or send a message to open/close a garage door, particularly within a small coverage area such as BLE vs the global Internet, I may not need to encrypt the message if I can validate that the message is authentic. In other words who cares what the message says if I can discriminate and trust who sent the message. This involves a much simpler and faster procedure. For a string of "data", you calculate an authentication hash equivalent say to the following pseudo-code.
Where salt is a random prefix string, typically 2-8 characters, to ensure sending the same message does not generate the same hash response; epoch is a time stamp that enables checking that the message was generated within a valid time window (i.e. sent just now, not a replay from yesterday. Also, need to be able to sync time.); secret is a piece of information known only by the sender and receiver and never passed openly (although this may be required one time in a learn mode, which presumably you can control); and the optional version provides identification of the scheme used that allows the receiver to discriminate different formats and enables a migration path to newer schemes. Note the salt, epoch, and the hash get passed with the data message. The receiver uses the same code to generate the same hash locally, using the locally known secret. If the sent message hash matches the locally generated hash, the message is authentic so act on it; otherwise, ignore the message or report it as a bad request perhaps. The hash also acts as a "checksum" to validate the integrity of the data. A single bit error will radically alter the generated hash. If the overhead of the hash, salt, and epoch represent to much bandwidth burden, many options exist. For example, send a simple string instead of a JS object with the fixed length version (1 byte), salt (2 byte), epoch (4 byte), and hash (32 bytes) prefixed to the data string, which the receiver can very easily parse by fixed substrings. Alternately, the hash can be truncated as a trade with security. A 4 byte hash for example still has 256^4 or ~1:4 billion chance of being replicated, probably good enough for most personal sensor/actuator applications. Assuming 5 byte hash, you only add 12 bytes overhead per message, which even works for the limited BLE message size. Another feature I like is that with an initial stored secret, the secret used for the hash can itself be adapted on the fly or on (authenticated) command. For example, you could hash the stored secret with a client provided random string, which changes the key for the specific message at the request of the client. Or roll the key based on a variable such as the day of the week. Or generate the key internally to the transmitter perhaps with a PUF -- see https://en.wikipedia.org/wiki/Physical_unclonable_function There are many variations on this theme, but...
Posted at 2017-02-08 by @MaBecker What about a sequence number ? This should allow the receiver to identify if a message is missing. Posted at 2017-02-10 by CanyonCasa
Yes, useful for flagging lost data but i wouldn't recommend for validating data, that is, you don't want to rely on having to receive every sequential packet. It's probably not as easy to recover a missing packet as it is to just design with expectation of missing samples. Recovery means having to queue each data packet until you get an acknowledgement for each, which means memory resources and additional overhead for handshaking too, pretty significant for small devices like Espruino. It can be useful for rolling a secret code too, essentially what garage door openers do. Posted at 2017-02-10 by @MaBecker Yes, I fully agree, never thought of recover, just as flag to get an idea how reliable the communication really is. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-05-15 by @gfwilliams
I'd like to transmit some data wirelessly over a low-bandwidth, insecure channel - maybe 433Mhz, NRF24, etc.
The data would be:
The transmitter could be pre-loaded with an encryption key that didn't change, and the receiver with a decryption key.
Does anyone know of an algorithm/protocol suitable for this? I hear all the time of people implementing their own home-grown solutions with massive security holes, so really want something tried and tested.
Beta Was this translation helpful? Give feedback.
All reactions