连续/小型UDP数据加密的最佳实践

29

我正在使用一款应用程序,需要通过UDP网络每秒发送多个小数据。应用程序需要实时发送数据(无需等待)。我想加密这些数据,并确保我的操作尽可能安全。

由于我使用的是UDP,因此无法使用SSL/TLS,所以我必须仅对每个数据包进行加密,因为该协议是无连接/不可靠/未受监管的。

现在,我正在使用从用户密码短语派生的128位密钥和CBC模式下的AES(使用AES-CBC的PBE)。我决定在密码短语中使用随机盐来派生128位密钥(防止字典攻击密码短语),当然还要使用IV(防止用于数据包的统计分析)。

但我担心几件事情:每个数据包仅包含少量数据(例如每个数据包仅包含几个整数值),这将使得加密数据包易受已知明文攻击(这会使破解密钥更容易)。此外,由于加密密钥是从密码短语派生的,因此密钥空间将变得非常小(我知道盐会有所帮助,但我必须将盐一次性发送到网络上,任何人都可以获取它)。鉴于这两点,任何人都可以嗅探和存储发送的数据,并尝试破解密钥。虽然这个过程可能需要一些时间,但一旦破解了密钥,所有存储的数据都将被解密,这对我的应用程序将是一个真正的问题。

因此,我的问题是,使用无连接协议(UDP)发送/加密连续小数据的最佳实践是什么?我的方法是最好的方法吗?……有点冗长?……过于复杂?

请注意,我并不要求100%安全的解决方案,因为不存在这样的东西。


仅作通知:截至今天(2014年5月12日),Spark Core在与服务器(云)通信时使用AES-128-CBC。它每15秒至少向服务器发送一次约8字节的消息,加密后需要2 + 128字节。当用户决定发送/接收更多数据时,数据会迅速累积(特别是在3G网络下)。 - Paweł Szczur
免责声明,我不是安全专家。DTLS是一个标准选项。但作为自定义协议的基本想法,您可以使用非对称密钥(使用TLS)交换第一个对称密钥和加密算法;对于进一步的数据报,使用对称密钥;通过将新密钥附加到数据来定期更改此对称密钥。密钥更新会导致最小的开销,不可预测的数据(类似盐),并且没有足够的时间来破解您的密钥。 - S.M.Mousavi
另外还要看一下CoAP。它是一个简单的应用层协议,建立在UDP之上,专门为物联网设计,特别适用于支持无连接和面向连接通信的小数据包,并具有观察者机制,可以解决您所遇到的问题。另一个选择可能是MQTT。这两种协议都支持加密。 - S.M.Mousavi
7个回答

19

您有多种选择。您可以使用DTLS,它是适用于数据报的TLS版本。它在RFC中进行了规定,并在openssl库中实现。您还可以使用IKE/IPsec协议,并使用IPsec部分的UDP封装。通常,IPsec在操作系统级别可用。您还可以使用OpenVPN,它看起来是基于TLS密钥交换和专有的基于UDP的数据包加密协议的混合体。


DTLS/IPSec对我的问题是有趣的协议。它们可能有助于加强密钥生成,但我怀疑它们无法解决小数据问题,这是我自己需要处理的。我会更深入地探索它们。谢谢。 - temp
我对“小数据”问题不是很清楚,但另一个选择是使用SRTP协议,RFC 3711。DTLS用于密钥管理,SRTP用于数据(RFC 5764)是IETF为安全VoIP选择的方案,其中有许多来回传递的小帧。 - President James K. Polk
2
@temp 什么是“小数据问题”?如果您的数据包太小,以至于它们限制了熵,那么它可能会危及安全性,唯一的解决方法是,除非在累积足够的输入之后,从不向不受信任的客户端发出提供此类信息的响应。当然,这取决于您的应用程序是否难以或容易实现。此外,Amnon的填充建议也可以使用;稍微浪费一些空间。 - Steven Lu

4
如果您的问题是数据太小,那么考虑使用随机字节扩展数据吧。这将使明文更难猜测。

是的,你说得对。我考虑过这个问题,但上面没有提到,因为我还没有实现它。我会看看别人有什么建议。 - temp
我对加密不太了解,但也许你可以使用一些策略来随机化随机字节的位置,当客户端读取数据包的数据时,它可以轻松地找出要跳过哪些字节,但这也许会增加外部人员分析加密数据的难度。 - rsethc

1
这个问题有点老了,但是使用类似一次性密码本的方法怎么样?你可以使用安全可靠的传输机制(如HTTPS)将一次性密钥从服务器传输到客户端。可以有两组密钥--一组用于客户端到服务器,另一组用于服务器到客户端。然后每个数据报都包括一个序列号(用于标识一次性密钥),然后是加密消息。因为每个密钥仅用于一个数据报,所以不应该暴露小数据问题。话虽如此,我不是这方面的专家,所以在使用之前一定要检查这个想法...

0
考虑使用 ECIES 无状态加密https://cryptopp.com/wiki/Elliptic_Curve_Integrated_Encryption_Scheme,其中发送设备使用中心系统的公钥和暂时性密钥生成对称密钥对,然后是 KDF,最终采用 AES-256-GCM。您将获得适度大小、无状态且完整的数据包,无需专门的带外密钥协定协议。互联网上有很好的示例,例如:https://github.com/insanum/ecies/blob/master/ecies_openssl.c。我正在使用这样的系统通过不安全的信道交付移动设备的遥测信息。

0

使用 Ecdh 密钥交换(使用密码加密客户端私钥;留在客户端)代替密码。这是一个非常强大的密钥。

Aes cbc 对您没有帮助;消息太短,您需要防止重放攻击。用计数器(从 0 开始)填充您的 64 位消息(两个整数)。64 位意味着可以发送 2^64 条消息。将块加密两次(aes ecb),并发送 e(k;m|count)|e(k;e(k;m|count))。接收者仅接受单调递增的计数,其中第二个块是第一个块的加密。这些是适合于 udp 数据包的 32 字节消息。

如果 2^64 条消息太少,请查看您的消息是否可以更小(3 字节整数意味着计数器可以为 80 位);或者一旦接近限制(例如 2^64-2^32),则返回步骤 1(至少一方的新私钥)。


“Few a second” 意味着 2^64 个数据包实际上是无限的。您不必重置密钥。 - Warren MacEvoy

0

你可以随包发送一对新的IVs。


0

现在好的流密码是最佳选择。ChaCha20使用AES作为密钥流。块密码是需要填充的密码。

但这只是部分内容。不要自己编写加密算法。DTLS可能是一种成熟的选项。还要考虑QUIC,它正在出现并逐渐普及到网络上。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接