I want to encrypt video directly at the source where it is being captured, e.g. inside a video camera. This way I can transmit the encrypted stream over WiFi securely.

I could use AES on the chip inside the camera, but this would be open to an attack on the semiconductor package, where an actor could retrieve the AES encryption key and use it to decrypt the data.

Is there an asymmetric encryption algorithm like RSA (which is unfortunately not efficient to encrypt a video stream), that is efficient at encrypting a video stream and that can also be implemented in hardware (like on an ASIC chip)?

This would allow me to store only the public key inside the ASIC, thereby increasing security. After receiving the encrypted stream I would be able to use the private key to decrypt it.

Would you recommend the video stream being compressed before being encrypted?

  • 6
    $\begingroup$ Is a session key approach possible? That is you encrypt an AES key with RSA, send that key and the AES encrypted bulk data? The key could be stored similarly as with HSMs? $\endgroup$
    – SEJPM
    Mar 4 '18 at 18:55
  • 2
    $\begingroup$ hybrid encryption $\endgroup$ Mar 4 '18 at 19:01
  • $\begingroup$ Yes, it is possible, and the hybrid approach has been suggested below. Thank you anyways. $\endgroup$ Mar 5 '18 at 2:21
  • $\begingroup$ If your encryption is any good, the encrypted stream will be almost indistinguishable from random data, so you will not be able to compress it without decrypting it first. And raw video footage is very large, so you probably don't want to skip the compression step. $\endgroup$ Mar 5 '18 at 23:37
  • $\begingroup$ Practical side-channel attacks on encrypted video streams over WiFi to detect if a certain point of interest is monitored: arxiv.org/pdf/1801.03074.pdf $\endgroup$
    – JimmyB
    Mar 6 '18 at 11:55

Except in exotic applications, nobody sensible encrypts data directly with a public-key primitive like the RSA trapdoor permutation of integers modulo a large semiprime $n$, for a variety of reasons.

If you are a sensible practitioner, you will use a public-key key encapsulation method, where the sender uses the recipient's public key to randomly generate, at the same time, (a) a fresh secret session key, and (b) an encapsulation of the secret session key from which the recipient knowing the private key can derive the secret session key.

Then the sender uses the secret session key for a secret-key authenticated encryption scheme like AES-GCM to conceal arbitrarily large volumes of plaintext—in this case, your video stream. Finally, the sender transmits the encapsulation of the session key alongside the authenticated ciphertext from AES-GCM. Pseudocode:

// Sender, given pubkey and plaintext.
key, encap <- kem_encapsulate(pubkey);
ciphertext <- aes256gcm_encrypt(key, 0, plaintext);
packet <- encap || ciphertext;

// Receiver, given privkey, encap, and ciphertext.
if ((key <- kem_decapsulate(privkey, encap)) = null)
    goto fail;
if ((plaintext <- aes256gcm_decrypt(key, 0, ciphertext)) = null)
    goto fail;

A common, though complicated, example of a KEM is RSAES-OAEP with a randomly chosen session key, or its predecessor RSAES-PKCS1-v1_5, sometimes also called ‘hybrid encryption’. This is what you will find in protocols like OpenPGP and S/MIME. Although you can view RSAES-OAEP as a way to encrypt short strings, essentially all applications of it use it like a KEM by randomly choosing a session key, encapsulating it, and then using the session key for secret-key authenticated encryption.

And essentially all new public-key encryption schemes, such as those under consideration for NIST PQCRYPTO, are built out of this KEM structure—including many that don't work by first choosing a session key and then encapsulating it, such as Shoup's RSA-KEM. Besides the additional flexibility in design of the primitives, this KEM structure does not even tempt you to try to feed data into the public-key primitives directly.

You can also use the secret session key for many messages without doing additional public-key computations, as long as you use a different message sequence number for each message—that's the parameter that I wrote as ‘0’ in the pseudocode above. For example, you might break your video stream into chunks, so that even if one chunk gets corrupted at least the surrounding chunks will still be viable.

Alternatively, you can use a public-key authenticated encryption composition like NaCl crypto_box, with an ephemeral key that you can reuse if you want to send many chunks at a time. In this case, the pseudocode will look like this:

// Sender, given pubkey, seqno, and plaintext.
temppriv, temppub <- crypto_box_keypair();
key <- crypto_box_beforenm(pubkey, temppriv);
ciphertext <- crypto_box_afternm(plaintext, seqno, key);

// Receiver, given privkey, seqno, temppub, and plaintext.
key <- crypto_box_beforenm(temppub, privkey);
if ((ciphertext <- crypto_box_open_afternm(ciphertext, seqno, key)) = null)
    goto fail;

Note that you can reuse the key for many different messages and seqnos, as you will likely want to do with video streams broken into chunks.


Would you recommend the video stream being compressed before being encrypted?

This is an excellent question in itself. What compression does, it recognizes redundancies in the data and removes those. So it changes the length of the data as a function of its value. Now cryptography doesn't promise to hide the length of the transmitted data, because that would be an impossible goal to achieve. So an outside attacker, could now go ahead and deduce some information about the plaintext, through the encryption, simply by looking at the length and frequency of packet transmissions. This in fact has been a famous attack, called CRIME, and has lead to TLS abandoning compression at the security protocol level. So you have to evaluate yourself whether the trade-off of leakage versus size gains is worth it to you.

Of course, with video being nicely encode-able with lossy methods, you can get a constant bit-rate encoding, where each unit of time of video material is encoded to the same unit of bit-output. As indicated in the other answers and the comments, this should leak very little to no information.

Now for your actual question:
(Hybrid) McEliece

McEliece is an old code-based signature scheme. It encrypts data by running it (as a vector) through a matrix-vector multiplication and then adds a limited amount of noise to the result. The decryption is more involved and essentially works off of error correction codes being applied to remove these errors. So let's go through things to figure out why it would be a good pick:

  • It is insanely fast. As you read above, it's simply a binary matrix-vector multiplication and a binary vector addition with some carefully generated noise. As such it is essentially, naturally, a lagre bunch of AND and XOR gates along with the output of a HW RNG, which can be built to be quite fast somewhat easily.
  • It is post-quantum resistant. McEliece (well, variants of it) are currently considered for the NIST post-quantum competition and McEliece has stood the test of time against quantum algorithms for a few decades now.
  • It has a large public key. Given that you don't actually seem to want to transmit the public key, this shouldn't be a problem in your case and even then, you mostly transmit video data, an extra Megabyte for the public key won't end the world.
  • Decryption is somewhat complicated. But this doesn't seem to be much of an issue for you, as far as I can tell.
  • It is rather badly supported. That is, it is used very sparsely. Given that you roll your own ASIC, you seem to be able to set your own standard here, but make sure to run things through proper cryptographers and don't just take the word of a random internet potato!
  • It lacks a lot of standardisation. When you use it "raw", that is not for some hybrid encryption as would be usual these days, you need to look around a bit to find a padding scheme that makes McEliece IND-CCA2 secure, which is really a security notion you want, but again, consult a proper cryptographer on this!

Now for your actual problem: The slow speed of asymmetric cryptogaphy. Well, there the solution of hybrid encryption. That is you take your favourite encryption scheme (such as McEliece), encrypt a lot of random bytes with it, prepend the ciphertext to the message and use the hash of the bytes as the key for authenticated symmetric encryption. This has the advantage that you can now keep the key for a (short) period of time in volatile registers and use the fast symmetric crypto to do the bulk of the work. Of course you can also pair hybrid encryption with slow asymmetric crypto such as RSA and just continuesly run the RSA encryption in a loop, generating a new session key once a second or so. The advantage of the hybrid encryption is that you need to spend less area on the asymmetric crypto (because you need less parallel instances / less area-time-trade-offs) and more on your actual logic and of course the fact, that you should have no problem finding pre-made IP for such symmetric encryption modules.

  • 3
    $\begingroup$ Not compressing the video stream would be really wasteful and also just unnecessary, because video can be compressed very efficiently with lossy codecs. Just choose a constant bitrate to avoid a side-channel attack on the compression ratio. $\endgroup$ Mar 5 '18 at 13:26
  • $\begingroup$ @leftaroundabout and from a very practical standpoint non-compressed video at anything beyond very low resolution uses more bandwidth than almost any consumer connection can provide. If I did the math right, 1080p, 60hz, 24 bit color is ~350 megabytes/second. You'd need a multi-gigabit fiber connection to service even one such stream. Even 640x480x30hz would need >200 megabits. $\endgroup$ Mar 5 '18 at 22:09
  • 3
    $\begingroup$ @DanNeely yes, that's what I meant by “really wasteful”. Completely uncompressed digital video is almost never used; even low-latency applications that have access to lots of bandwidth will generally use some light intra-frame compression. Even the pretty low-tech DV standard did this. $\endgroup$ Mar 5 '18 at 23:54

When using asymmetric encryption, you do not, actually, encrypt the data asymmetrically. Instead, you use hybrid encryption, which goes thus:

  • You generate a random symmetric key $K$.
  • You encrypt $K$ with the intended recipient's public key, using an asymmetric encryption algorithm such as RSA.
  • You encrypt the data itself with an efficient symmetric encryption algorithm, e.g. AES, using the key $K$.

This combines the efficiency of symmetric encryption, with the safety of not hardcoding a given symmetric key $K$. The sender (the camera) generates $K$ randomly and keeps it in RAM only, just for the time to encrypt the data. Basically, $K$ would be generated when the camera connects with the recipient, and a new $K$ is produced each time a new connection is made. Alternatively, if the camera simply broadcasts the stream and has no notion whether somebody is listening or not, then the camera could simply make a new key $K$ every second. For the cost of one RSA encryption per second, on a small value (size of $K$ would be 128 bits or so), you can encrypt all the stream with AES.

Note that using a random key $K$ means that you can replace the "encryption with RSA" with a key exchange algorithm such as Diffie-Hellman.

As for compression: since encrypted data is mostly indistinguishable from randomness, applying compression after encryption should not work (or, if it works, then the "encryption" is pure junk and should be ditched). Thus, if you compress at all, then do so before encrypting.

Encryption hides data contents, not data length. Therefore, if compressing, then the compression ratio will be accessible to eavesdroppers. This is usually not critical information; for a movie on a DVD, where data bandwidth varies between 5 and 13 Mbit/s, this can be used to distinguish between action scenes and boring dialogue. If you really want to hide such information, choose a (lossy) compression algorithm that yields a fixed output bandwidth.

  • 1
    $\begingroup$ I guess that key wrapping can be used, but ECIES and RSA-KEM derive the key rather than wrapping it. ECIES might be rather efficient as the private key operation will be much faster than RSA-decryption. Encryption of video streams is generally useless; the streams themselves are already compressed - nobody sane starts with an uncompressed data stream and then streams is on the fly because the amount of data of an uncompressed stream is huge. $\endgroup$
    – Maarten Bodewes
    Mar 4 '18 at 22:37

Is there an asymmetric encryption algorithm like RSA (which is unfortunately not efficient to encrypt a video stream), that is efficient at encrypting a video stream and that can also be implemented in hardware (like on an ASIC chip)?

The normal approach is to use a hybrid encyrption scheme. You generate a random symmetric key and use public key encryption to send it to the recipient. Other answers have gone into more detail on this.

To minimise the damage in the event that the camera is compromised this secret key should be kept only in ram and should be replaced frequently. For reliability I would suggest sending the (encrypted) secret key to the receipiant at both the start and end of it's life.

Would you recommend the video stream being compressed before being encrypted?

Yes but you need to be careful.

Video compression is essential to producing acceptable quality video at manageable bit rates. Compressing after encrypting is impractical so we need to compress before encrypting.

However carelessly implemented compression can easily leak information. Encryption hides the content of the data packet but not it's size or timing. Care must be taken to ensure that the compression and packetisation system produces fixed-size packets at fixed intervals for encryption.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.