aes 是一种流式加密,加密时需要按照顺序,比如第 1 ,2 ,3 个数据包依次加密。解密也是类推,需要第 1 ,2 ,3 个包依次解密。
然而,UDP 会掉包。也就是解密会遇到 1 ,2 ,4 这种情况。由于第三个包掉了,那么后面数据包全部都无法顺利解密。
那么问题来了,遇到这种情况,应该选什么加密算法?
![]() | 1 TomVista 2024-06-14 15:20:51 +08:00 我更好奇的是你在哪层网络能够对数据包依次加密 |
![]() | 2 b821025551b 2024-06-14 15:20:58 +08:00 首先,aes 是分组加密; tcp 是流式传输; 其次,所有的加密都需要校验,只是 tcp 帮你做了而已; 那么到 udp ,需要自己做校验,比如 crc ,然后自己实现重发机制。 |
![]() | 3 tool2dx OP @TomVista 就是最普通的 UDP 数据,用 socket api 写的,数据包在网络裸奔太危险,但是暂时没想到很好的加密方式。 也许能用一个随机数做种子,类似 rsa 加密 padding 那种。填充不同,加密后的数据不同。 可惜 RSA 加密太慢了,要不然还挺合适的。UDP 都是固定长度,而且分包都很小。 |
![]() | 4 tool2dx OP @b821025551b 好的 UDP 协议应该允许一定程度的丢包,现在都是全球互联网,晚高峰跨国发数据丢个包,实在是太正常了。 如果都按照 TCP 的方法,1234 数据包都依次排序,严格校验数据包漏发和错发,那是可以用 AES 的,但就是失去了 UDP 的优势和意义。 |
![]() | 5 forvvvv123 2024-06-14 15:33:42 +08:00 ![]() @tool2dx OP 看一下 CTR 模式,AES 的话就是 AES-CTR ,每个分组可以并行解密不依赖顺序,适合你的场景。 |
![]() | 6 tool2dx OP |
![]() | 7 duanxianze 2024-06-14 15:58:37 +08:00 ![]() 我不懂 upd,aes ,但我觉得你都搞加密了,使用 udp 带来的节省似乎不足以抵消你加密造成的消耗,还不如老老实实用类似 https ,wss 之类的现成协议了 |
![]() | 8 byte10 2024-06-14 16:44:26 +08:00 楼上说的 AES-CTR 就是流式加密,你说的那个分组加密不行,但是流式加密 也需要知道包的 index 位置,所以丢失了还是不行,头大。对 UDP 不熟悉,如果你加上重传,又把校验加上,还不是又绕回来 tcp 这边了么。 |
![]() | 9 tool2dx OP @byte10 TCP 丢包惩罚太凶,交通拥堵的时候,就很容易进入不可用状态。虽然开 BBR 能缓解一定效果,但是这是单向的开关,下载快,上传还是很慢。 客户端要开启 BBR ,好像要最新的 WIN11 ,就觉得没太大必要。 国内服务器 TCP 确实够用了,可惜有国外业务,只能硬着头皮上 UDP 了,要不然真的太卡了。 |
![]() | 10 ryan4290 2024-06-14 17:13:35 +08:00 QUIC 能尝试一下,解决你的问题吗? |
![]() | 11 caola 2024-06-14 17:19:39 +08:00 ![]() @tool2dx 有现成的 QUIC 协议 或 HTTP/3 直接拿来就用,不用自己关心底层是怎么实现的,你就当他是普通的 TCP 就可以了 |
![]() | 12 w3b5h3ll 2024-06-14 17:51:42 +08:00 加密不是应用层,更 udp 没关系吧 |
![]() | 13 ysc3839 2024-06-14 17:54:30 +08:00 via Android 要 UDP+加密的话,为什么不直接用 DTLS ? |
![]() | 14 cheng6563 2024-06-14 17:55:44 +08:00 @byte10 楼上说的 AES-CTR 就是流式加密,你说的那个分组加密不行,但是流式加密 也需要知道包的 index 位置,所以丢失了还是不行,头大。对 UDP 不熟悉,如果你加上重传,又把校验加上,还不是又绕回来 tcp 这边了么。 还是有点不一样,udp 客户端可以手动控制重复发包,比如检测到网络波动就双倍发包 |
15 ho121 2024-06-14 18:02:22 +08:00 via Android 把每个 udp 报文都当作一个新的流不行吗? 就像加密文件一样,每个 udp 包都当作独立的文件。 |
![]() | 16 slack 2024-06-14 18:11:48 +08:00 via Android 能的,最近在研究 i2p ,里面就是用的 ssu2 。 |
![]() | 17 minami 2024-06-14 21:31:12 +08:00 这个倒不用担心,一般人不会直接用 UDP ,都是用 SRTP 或者 QUIC 这些更上层协议,它们都有加密功能 |
![]() | 18 leloext 2024-06-14 21:44:26 +08:00 有重传机制就没问题了,如果 udp 真不能用 aes 加密的话,那么 kcptun 也不会存在;想知道底层的话可以看看它的源码。 |
19 mt7620 2024-06-14 22:41:13 +08:00 github -> kcptun |
20 leonshaw 2024-06-14 23:14:24 +08:00 via Android 抄 ESP 呗,每个包都是独立解密的,分组是指一个包内部分成 block |
21 0o0O0o0O0o 2024-06-14 23:17:53 +08:00 先挑一个基于 UDP 的可靠传输协议 |
![]() | 22 flynaj 2024-06-15 01:52:31 +08:00 via Android 楼主是想发明一个 QUIC ,建议你先看看 quic 的代码。 |
23 sduoduo233 2024-06-15 09:07:59 +08:00 via Android udp 可以 AES shadowsocks 的 udp 就是 AES GCM AEAD 的 |
24 jheroy 2024-06-15 09:48:11 +08:00 via Android ![]() 楼主这是把加密算法和加密模式弄混了,首先 ECB 模式是肯定可以用的,不过相同明文的会得到相同密文对抗分析较弱,然后就是 CTR ,只依赖包的序号,丢包也无所谓丢的宝内容虽然没了但是丢的哪些序号的包是知道的(自己维护顺序) |
25 GrayXu 2024-06-15 14:56:56 +08:00 中间加一层 kcp/quic? |
26 panda1001 2024-06-16 05:58:11 +08:00 via Android ss 就是干这个的,参考其实现,其中的流加密算法都适用。 https://github.com/shadowsocks/shadowsocks-libev/blob/master/src/udprelay.c#L1310 流加密基于字节的,包在字节之上,ss 只考虑加解密(传输层),无法解密的包一样扔掉,掉包是上层程序(应用层)考虑的事情 https://github.com/shadowsocks/shadowsocks-libev/blob/master/src/udprelay.c#L872 |