1. encryption - this means anyone sniffing in the middle cannot be able to see what's being transmitted because it's sensitive
2. authentication - this means someone might be able to sniff your communications to see what's being transmitted, but they cannot impersonate your server or device; or replay commands.
For most of my purposes I almost always need 2. but may not always need 1. So I never want anyone spoofing my devices or letting them accept commands from spoofed servers, but if someone captures some temporary data, it's not as bad.
Turns out you can do this securely even over HTTP without needing HTTPS. What I do is create a unique and random "secret" for each unit I produce. This secret is generated during flashing/manufacture and stored in two places: on the device's memory and on the server's database. The server being the one the devices will talk to.
So now every time the server or device send any data to each other, they include a timestamp along with the data, as well as a "digest hash". This digest hash is the contents of the data/payload, concatenated with the timestamp, then run through an SHA1-based HMAC hashing algorithm along with the secret. The result of that HMAC, just a hash, is also included with the data and timestamp. And this happens with every request over HTTP or whatever other protocol.
Now when the unit sends data to the server, it'll do that process for creating a digest using a timestamp and its secret on flash. The server on the other side will authenticate this by first looking at the timestamp to see that it came within the last 10 seconds or so, to account for small drift but still prevent re-play attacks.
if that passes, the next step is for the server to create that same HMAC digest and compare it. So it concats the included timestamp to the data, and HMAC's it with that device's "secret" it pulls out from its database. If the calculated digest matches what was in the request, the server can now be pretty sure it was actually generated and sent by the controller.
The main underpinning with this is that the secret is stored only on the database and each unit but never transferred over the wire, only stuff that's produced with it. And if someone hacks open the flash of the device and pulls out the secret, they only get it from one device. All others are still secure because their secrets are unique and different. It's much more important to protect your entire population of products as opposed to just a single one. You can count on someone eventually breaking one of them, but that shouldn't ever mean the rest are compromised.
If you need encryption, you can use HTTPS since it's standard and better than making something custom. You can do that by using certificates and something like the "axTLS" library which is a pretty nice one and small, so it can be embedded in ESP8266 firmware you make. But even with that, you still need a scheme like the one above for the authentication portion.