I am trying to built a home automation solution with following use case

  1. User registers on server with username and password_a
  2. User sets the password_b for IoT device
  3. The connection between user and server is TLS encrypted
  4. The IoT device connect to server with unsecured websocket connection
  5. The server acts as medium to pass the data to/from IoT device from/to user
  6. The datapackets for websockets are encrypted by AES using password_b to generate key
  7. Only user and IoT device can encrypt/decrypt the data

Is this a secure way to communicate? Are there any pitfalls with this approach?

I am new to security.

  • 1
    Why do you want the device, when connecting to the server, to do it over an unsecured websocket connection? If you set a random key for the initial connection at production time, the risk of a MitM attack or any information disclosure is then reduced.
    – RLFP
    Aug 24, 2016 at 5:30
  • 3
    You have provided exactly zero information that could be used to determine the level of security that your design provides. "AES" doesn't mean a damn thing if you use the wrong mode of operation, or you use this mode in a way that it was not designed. If you are interested in building secure systems, then you have a lot of studying ahead of you. Consider reading 'Cryptography Engineering'
    – rook
    Aug 24, 2016 at 7:33
  • 1
    @rook I think it's acceptable for a newbie to ask such a specific question without glibly being told to 'go read a textbook'. Not everybody has the time to be a subject matter expert, and surely there's some pointers OP could get here.
    – sscirrus
    Sep 9, 2016 at 3:06

2 Answers 2


The main problem I see with this scheme is what's called the Key Distribution Problem: how do you securely deliver password_b to the device?

In step 2, the user inputs password_b into a web-form. Presumably in step 5 password_b is sent to the device over an unsecured websocket connection. From then on, the device encrypts all websocket data using AES with a key derived from password_b.

My issue is with step 5: if it's being sent in plaintext then an attacker on the same network as the device could just wireshark the password out of the packet. Even if you use a standard server-authenticated TLS connection, the server would have no way of proving which device it's talking to and an attacker could connect and claim to be the device and get the server to send it password_b.

My suggestion is that if you can afford to run a TLS library, then give each device a client certeficite during manufacturing and have the server keep a table of which public key belongs to which device serial number. This way, when a device connects to the server over TLS, the server knows which device it's talking to just from the public key / signature.

Usually you would use an SSL/TLS ciphersuite that wraps AES, rather than inventing your own protocol because as @Rook suggests, there's just so many ways to shoot yourself in the foot. I understand that some low-power devices can do AES but don't have the memory footprint for a full TLS library. Fine, but you'll have to either become a crypto expert, or hire one, to be sure you're doing it right because you're going off the beaten trail here.


This is not a secure way to communicate. There are many things that can go wrong.

Like mentioned before, if you can, just use a TLS connection. You should be able to use the same certificate you use for your HTTPS server. So just get a websocket server that supports TLS and you're done. However, I want to focus on your question about using AES, and go through some basic attacks.

Taking a look at the websocket handshake, we see that some data is always the same (like "HTTP/1.1 101 Switching Protocols"):


This allows for known plaintext attacks. For example, an attacker knows that that specific plaintext is converted to the observed ciphertext. Also, you're schema doesn't seem to protect against replay attacks, where I re-send some observed packet.

AES is a block cipher that converts a plaintext block of data to a ciphertext block of the same length. There are multiple ways to send a bunch of blocks over the line. See:


The most simple is ECB. Here you just send block after block. This means that any block that contains the same plaintext will contain the same ciphertext. So if I know the plaintext for some ciphertext block, and I see the same ciphertext somewhere else, I know that it contains the same plaintext. Also, with ECB, an attacker can also just exchange one block for another, which will exchange the plaintext blocks after decryption.

A more common use of block chaining is CBC. This will chain blocks together with an IV, such that no two plaintext blocks (or bunch of blocks) will turn into the same ciphertext blocks. However, this is also full of danger. If you look closely at the decryption schema for CBC, you can see that xor'ing a byte in a ciphertext block will result in an xor of the same value for the plaintext one block after that. There are all types of bitflipping attacks and things you can do. Also, if the server responds differently when AES padding is correct or not, parts of the plaintext can be recovered with a padding oracle attack.

The above attacks work because I don't see anything about integrity checking (with an HMAC for example) that doesn't prevent an attacker from tampering with the ciphertext.

These are just some examples of things that can go wrong. Also check out timing attacks if you want to get into it and are looking for some cool reads. Please don't implement your own crypto.

And aside from getting the password on the device like Mike mentioned, I see great trouble in letting users chose a password for encrypting data. Without some key expansion algorithm, I might just brute force the password for some ciphertext.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .