V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
raw0xff
V2EX  ›  程序员

多节点间加密通信的安全问题

  •  
  •   raw0xff · 154 天前 · 3796 次点击
    这是一个创建于 154 天前的主题,其中的信息可能已经有所发展或是发生改变。

    多节点间通信,节点每 2 秒会收到 10<n<100 条加密数据,每 2 秒要发送 n<10 条,每条数据<1kb 。 节点有自己的公私钥,ECC 算法,接收时用本地私钥解密收到的数据,发送时用接收方公钥加密。

    请问这种场景选用 ECC 公钥加密私钥解密方式是否合理?会有哪些问题?大佬有什么建议?

    我不太懂私钥安全性是否会有磨损,每天百万次解密运算是否可以长期使用?

    另一个话题,私钥在本地如何安全存储?

    43 条回复    2023-11-29 00:07:55 +08:00
    CaoUsDog
        1
    CaoUsDog  
       154 天前 via iPhone
    TLS 不就是用这玩意交换加密密钥的吗?如果能磨损,那银行、谷歌之类的网站不得几分钟就换证书了
    zmaplex
        2
    zmaplex  
       154 天前
    你这个方案不如 MQTT 加 TLS 来得成熟可靠。
    GeekGao
        3
    GeekGao  
       154 天前
    ECC 加密和解密的计算复杂度较高,这可能会影响到系统的性能;
    其次,如果私钥被泄露,那么所有的数据都可能会被解密,这对系统的安全性构成了威胁;
    因此,需要确保私钥的安全,并定期更换私钥;
    最后,ECC 加密和解密的过程可能会导致数据的增长,这可能会增加网络的压力;

    私钥在本地如何安全存储? 最简单直接的方式是使用可信的密钥管理系统 (KMS) ,例如 HashiCorp Vault
    raw0xff
        4
    raw0xff  
    OP
       154 天前
    @zmaplex MQTT 需要消息代理服务器,不适用
    raw0xff
        5
    raw0xff  
    OP
       154 天前
    @GeekGao 私钥泄露的问题,我认为可以降低私钥的重要性,节点接收到的信息都是用户私钥签名过的,不涉及敏感内容。所以即便私钥泄露,顶多节点不能使用,数据本身也是明文+用户签名,作恶者只有节点私钥没有用户私钥,做不得假。不知道这样想对不对?

    KMS 不太适用于我这个场景。

    每天百万次的加密解密用什么云主机起步? 2c4g 应该能扛得住吧?

    肉眼看 ECC 加密后数据量会增加 2 倍,买点流量应该能兑付
    leonshaw
        6
    leonshaw  
       154 天前 via Android
    为什么不用通行的密钥交换?私钥安全用硬件 TPM ,有钱上 HSM
    raw0xff
        7
    raw0xff  
    OP
       154 天前
    @leonshaw ECDH ? 用 aes 比直接公钥加密的优势是?

    私钥安全用硬件 TPM ,有钱上 HSM
    用轻量云主机,没钱哈哈
    GeekGao
        8
    GeekGao  
       154 天前
    @raw0xff
    一定程度是正确的,但是严格的讲是有现实隐患的:
    首先,你忽略了一个重要事实,就是私钥泄露可能会带来严重安全问题。如果一个节点的私钥泄露了,攻击者就可以假冒这个节点,这对整个系统的安全都造成威胁。攻击者可能会伪造消息或者修改已经存在的消息,从而影响系统正常运行。

    其次,即使数据本身是明文,私钥泄露也意味着攻击者可能会试图窃取或者修改这些数据。在某些情况下,这可能会带来严重后果,比如如果数据包含用户个人信息,那这些信息就可能泄露。

    最后,你忽略了私钥泄露不仅意味着一个节点的私钥泄露,更可能会导致更多私钥泄露。比如,如果一个节点的私钥泄露了,攻击者就可以利用这个节点获取其他节点的私钥。到时候攻击者就可能控制整个系统了。
    GeekGao
        9
    GeekGao  
       154 天前
    假如 QPS < 100 ,加解密底层实现是基于 C/C++ 的,盲猜 2c4g 配置够用。
    leonshaw
        10
    leonshaw  
       154 天前
    @raw0xff 一方面是性能,一方面大概要自己实现分组加密的模式,容易有漏洞。用云主机就主打一个信任,做好常规安全加固吧。
    baobao1270
        11
    baobao1270  
       154 天前   ❤️ 3
    @GeekGao
    @raw0xff

    看来各位对密码学都有一定的误解。建议去把 HPKE 的 RFC 仔仔细细读一遍。总的来说:
    1. 现代的加密手段不再使用固定的公钥/私钥对,也就是很多 HTTPS 科普中「使用证书的公钥/私钥来加密/解密」已经是错的了。现代的加密机制,每个 connection 都会进行一次独立的 DH/ECDH ,目前最快的算法是 X25519 。
    2. 为什么要 AES 进行实际的加密/解密,而不是直接用公钥/私钥?因为慢。即使 ECC 比 RSA 快,但是和 AES 比仍然有十倍左右的速度差距。如果你的设备以嵌入式为主,CPU 没有 AES 加速功能,建议使用更快的 ChaCha20-Poly1305 算法。
    3. 在进行加密通信时,永远使用 AEAD 而不是单纯的 AES——如果决定使用 AES ,必需使用 AES-GCM 模式;如果不使用 AES ,建议使用 ChaCha20-Poly1305 算法。
    4. 现代的 TLS 流程:ECDH 交换随机数->用 HKDF 从随机数派生 AES/Poly1305 密钥 (此时服务端握手已经完毕) ->服务器用证书私钥签名发送给客户端 (发送的证书已经用派生密钥加密)->客户端验证证书 (1.5RTT 握手完成) -> 进入 Application Data 通信模式
    5. 对于运行在云上的设备,KMS 永远是最好的存储密钥的方法。对于本地设备,建议使用 TPM/HSM ,其实 FIDO2 密钥也能当 HSM 用。
    xiangyuecn
        12
    xiangyuecn  
       154 天前
    几 kb 数据量,直接非对称加密就行,没有压力。

    存储,密钥随便放就行,只要不被匿名访问到,不要有压力。你要相信,当你的密钥可以被别人访问到,你做什么努力都是白费的。
    raw0xff
        13
    raw0xff  
    OP
       154 天前
    @GeekGao
    首先,你忽略了一个重要事实,就是私钥泄露可能会带来严重安全问题。如果一个节点的私钥泄露了,攻击者就可以假冒这个节点,这对整个系统的安全都造成威胁。攻击者可能会伪造消息或者修改已经存在的消息,从而影响系统正常运行。
    -- 同意私钥泄露是严重的安全问题,我们假定节点是可以被攻击者取得 root 权限的,我们又不能用 KMS ,也不能用 TPM 硬件存私钥,那么我们能做的且有效的是降低节点私钥的重要性。比如明文且有签名的信息是类似微博的内容,敏感信息如用户名用户设置等用用户公钥加密,只有客户端有私钥才能看到和修改。您认为这个思路可行吗?

    其次,即使数据本身是明文,私钥泄露也意味着攻击者可能会试图窃取或者修改这些数据。在某些情况下,这可能会带来严重后果,比如如果数据包含用户个人信息,那这些信息就可能泄露。
    -- 节点私钥泄露不代表攻击者拥有用户私钥,所以做不到伪造和篡改数据,节点只存用户公钥。假如攻击者新增或删除了用户公钥,我们前提是“多节点间”,其他节点并不认可,所以只能使此节点不能正常运转,不影响整个网络。(假定攻击者只能 root 其中一个节点)

    最后,你忽略了私钥泄露不仅意味着一个节点的私钥泄露,更可能会导致更多私钥泄露。比如,如果一个节点的私钥泄露了,攻击者就可以利用这个节点获取其他节点的私钥。到时候攻击者就可能控制整个系统了。
    -- 这种情况有考虑到,有对应的方案

    还是想确认 ecc 公钥加密私钥解密用在每天数百万次加解密场景中是否合适,对比的方案是 ECDH+aes ,还请大佬给分析一下。
    raw0xff
        14
    raw0xff  
    OP
       154 天前
    @xiangyuecn 字数虽少,特别认同,就是不知道正不正确。
    raw0xff
        15
    raw0xff  
    OP
       154 天前
    @baobao1270 看来还是得换 x25519 。 使用 ECDH 的话一定要用 TLS 吗?交换的随机数即使暴露了好像也没关系吧?已知没搞明白。 还有,抗量子性方面有什么建议吗? AI 发展这么快,有点担心。
    mantouboji
        16
    mantouboji  
       154 天前
    这种还不如直接 https 或者建一堆 wireguard 连接得了,何必自己瞎写。
    GeekGao
        17
    GeekGao  
       154 天前
    针对你提到的“看来各位对密码学都有一定的误解。建议去把 HPKE 的 RFC 仔仔细细读一遍”
    我也给你找点反例吧:
    1. 性能问题:每次连接都需要进行密钥交换,💡这会增加加密和解密的计算开销,特别是在资源受限的设备上,例如轻量级的物联网设备

    2.安全性问题:尽管 X25519 算法在理论上是安全的,但在实际应用中可能存在一些问题。例如,如果在密钥交换过程中随机数值泄露,任何知道该随机数值的人都可以使用该随机数产生签名值恢复私钥。此外,如果同一个用户对两个不同的消息签名时,采用了相同的随机数,则任何人都可以通过两个签名值恢复出私钥。怎么实施保护性措施?
    💡除非你假设 OP 一定会科学恰当的使用现代成熟的 TLS 方案。

    3.兼容性问题:使用 X25519 算法的设备可能与使用其他加密算法的设备不兼容,这可能会限制它们的互操作性。💡除非你假设了 OP 无所谓自己的学习曲线、也无需考虑后续入方的接入成本。
    GeekGao
        18
    GeekGao  
       154 天前
    对于 ECDH+AES 的方案,ECDH 可以用来生成一个共享密钥,然后使用 AES 进行数据的加密和解密。
    这种方案的优点:ECDH 的密钥交换速度快,适合于需要频繁交换密钥的场景,而 AES 的加密和解密速度快,适合于需要大量加解密的场景。

    ECDH+AES 的缺点:它需要两种不同的加密算法,这可能会增加系统的复杂性和实现难度。

    关于对抗量子计算的攻破,已知道的是 ECC 在面对量子计算机的攻击时有概率会被破解。因为量子计算机的构建和实现还在初级阶段,重点是:目前还没有量子计算机能够实现大规模的量子比特控制和稳定性。
    因此,如果一个大规模的量子计算机能够实现,并且能够破解 ECC ,那么 RSA 的破解也就不会远了 1 。
    微软的研究团队正在研究如何使用量子计算机来破解 ECC ,他们发现,要破解 ECC ,需要的量子比特数量是 RSA 的 6 倍。
    raw0xff
        19
    raw0xff  
    OP
       154 天前
    @mantouboji wireguard 行,我去了解学习一下先


    @GeekGao 感谢对 OP 的考虑,是这样的,在选择方案上特别耗精力。查阅资料给出的特性不一定完全适用于自己的场景,实践的精力成本还是比较高的,所以才开贴求助一下有经验的大佬给点建议。
    keepMyselfClam
        20
    keepMyselfClam  
       153 天前
    这样的方案有很多问题,基础完整性保护都没有.
    直接用成熟的 TLS/DTLS 就行了,不要用自己随便拍脑袋的想法和行业几十年的积累去比较
    抗量子性啥的压根就不用考虑,遵循现在的主流标准就够了.天塌有高个子顶着,民用产品担心啥.
    patrickyoung
        21
    patrickyoung  
       153 天前 via iPhone
    TLS 1.3 +MQTT 就是你要的
    swulling
        22
    swulling  
       153 天前 via iPhone
    100 QPS 还没有到担心性能的地步,除非你的设备是非常慢的嵌入式设备。

    此外用 mTLS 就完了,何必自己造轮子。
    swulling
        23
    swulling  
       153 天前 via iPhone
    最后一点,除非用可信硬件,否则不要杞人忧天的考虑本地设备被人拿了 root 怎么办,因为本身就是凉拌。

    用 mTLS 可以定期轮换证书,可以主动撤销证书就完了。
    baobao1270
        24
    baobao1270  
       153 天前
    @raw0xff
    不是叫你换 x25519 ,只是叫你换一个 ECDH 算法——x25519 只是目前最火的。ECDH 和 TLS 没有关系,ECDH 是算法,TLS 是实现。但是建议你使用 TLS ,因为自己去实现密码学相关的东西很容易出错。现阶段没有必要考虑 PQC 。

    @GeekGao
    1. 性能问题:说到底还是 trade-off 。ECDHE 主要还是为了 PFS ,个人认为物联网设备建立连接并不是一个非常频繁、需要并发的场景,即使建立连接慢一点其实也无所谓,同时由于 ECDHE 参数在 TCP 连接建立前就算好了所以也不会给服务器造成负担。个人觉得用这个换 PFS 是值得的。
    2. TLS 中随机数本来就是明文传输的,至于为什么去看 ECDHE 的原理。「同一个用户对两个不同的消息签名时,采用了相同的随机数」,不可能,至于为什么去看 AEAD 的原理。
    3. 「使用 X25519 算法的设备可能与使用其他加密算法的设备不兼容」——首先,如果你的设备和软件都是新的,那么完全可以直接上 X25519 。其次,X25519 只是 TLS 选用 ECDHE/DHE 算法之一,你也可以选择其他的 ECDHE/DHE 算法。遵循标准 TLS 1.3 协议的客户端和服务器,应该支持 TLS 1.3 所规定的大部分算法。最后,我也没有说「一定要用 X25519 」,如果 OP 选择了一个成熟的 TLS 库方案,那么自然说是库支持什么就用什么,只需要排除不安全的 chiper 即可。
    4. ECDH 是密钥交换算法,AES 是块加密算法,是不同的领域:ECDH 只能用来协商密钥,而 AES 只能用来对称加密,必需两个结合在一起才能组成完整的加密通信协议。感觉你 #18 写的东西没有逻辑。
    Explr
        25
    Explr  
       153 天前 via Android
    可以了解一下 Signal 算法
    GeekGao
        26
    GeekGao  
       153 天前
    @baobao1270 关于 4 ,你去了解下 Bluetooth 4.2 (LE Secure Connection) 就知道我的逻辑了。
    hxndg
        27
    hxndg  
       153 天前
    命题本身就不是很清楚,你要做的是分布式环境下的保密还是认证?
    如果只是加密分布式的环境用 secure scuttbutt 啥的协议通信。就可以了

    现代通信网络,做认证必然引入第三方。
    本地的安全存储看你的需要的程度,可以拆分为内存可信,系统可信,等级别。这个不说清楚细节没法给回复的,即使是使用 kms 也有认证的问题。当时做协议和 kms 的时候都有非常实际的问题

    而且怎么回复里面还有胡说八道的?恢复私钥??
    GeekGao
        28
    GeekGao  
       153 天前
    @hxndg “胡说八道的?恢复私钥??”
    你自己研究吧 https://www.instructables.com/Understanding-how-ECDSA-protects-your-data/#step14
    hxndg
        29
    hxndg  
       153 天前
    @GeekGao

    不好意思,我理解错了,你的意思是说,完全自己实现的交换模式,ecdsa 传输的所有信息都泄露,用户可以完全拿到包括签名结果,要签名的内容之类的东西是吧。就你的情况而言,确实。

    我理解的是,就 tls1.3 而言,本身的报文加密,攻击者不会拿到明文的通信内容,所以不可能泄露。
    mightybruce
        30
    mightybruce  
       153 天前
    @baobao1270
    赞同你写的,这上面很多人都在凭空想象,不去多看看基本密码学和网络安全协议设计的书 或 RFC 标准。
    zmaplex
        31
    zmaplex  
       152 天前
    @raw0xff https://www.emqx.io/zh docker 私有部署在你 api 服务器上就行了
    gjquoiai
        32
    gjquoiai  
       152 天前
    密码学第一定律,不要自行发明密码学设施;
    另外提醒一下使用椭圆曲线算法加密/解密要用 ECIES ;
    椭圆曲线算法目前唯一的问题是常用的几条曲线参数没人知道是怎么来的;
    最后就是,为啥不用 tls 。。
    raw0xff
        33
    raw0xff  
    OP
       152 天前
    @baobao1270 我是在用 ecc 公钥加密私钥解密时发现使用姿势不对,看到了 ecdh ,curve25519 也有现成的库,但是我还没有实践。有个不明白的点是,基于连接的对象是固定的,各方公钥是已知的且公开的,那么传输中有必要使用 tls 吗?


    @gjquoiai 在用 ecies
    baobao1270
        34
    baobao1270  
       151 天前
    @GeekGao @hxndg 看来我们遇到了一点自然语言表述不清的缺陷。我说的「随机数」是 TLS 1.3 ClientHello 中的随机数,它是用来参与后期 KDF 的,会明文发送,自然不可能用来恢复私钥。你说的「随机数」是用来生成 ECDHE Key Pair 的随机数,这个自然是需要保密、并且保证抗时序攻击的。
    此外,我看了 BLE 的标准,其实和 TLS 是一样的——先用 ECDH 交换密钥,然后用 KDF 生成对称加密密钥,最后用对称加密算法 (RC4/AES) 进行加密通信。所以不可能只依赖 DH/ECDH ,也不可能只依赖对称加密,必需两者结合使用。

    @gjquoiai 不一定要用 ECIES 吧,其实说到底还是一套 DH + Symmetric Crypto + AD 的 Hybrid Encryption 方案,TLS 、BLE 、ECH 都是自己实现组合而不是依赖 ECIES ,ECIES 只是一个通用的、被证明没有太大安全漏洞方案吧。
    baobao1270
        35
    baobao1270  
       151 天前
    @raw0xff #33 TLS 主要是实现 Forward Security ,也就是假如有一个中间人捕获了你的通信,虽然无法解密但是依然保存通信的内容。万一有一天你的私钥泄漏了,如果没有 FS ,那么中间人就能解密你的所有通信;如果用了 FS ,那么就只能解密未来的通信(如果你没有更换私钥),无法解密过去的通信。

    TLS 实现 FS 的方式就是 ECDH ,如果你能使用「正确的方式」进行 ECDH 的话,那么自然不需要使用 TLS——但是鉴于大多数人实现密码学的方式都容易犯错,因此「建议」使用 TLS 。
    hxndg
        36
    hxndg  
       151 天前
    @baobao1270
    我不觉得有继续争论或者解释的必要,
    你和我说的都是机制,无论是 tls 还是 hpke (我建议你可以更公开的解释下这个东西,我搜了一下,google 的第一个结果还是我很早写的一篇笔记,我觉得看不懂的人还是看不懂)
    而 @GeekGao 说的是具体的里面的算法,针对算法的特定实现做出质疑。
    这两个事情并不是直接关联,说到底每个人都看到了一个方面,争论有什么意义呢?
    raw0xff
        37
    raw0xff  
    OP
       151 天前 via iPhone
    @baobao1270 你们神仙尽管打架,不妨碍我问小白问题。

    我用 wss 通信还要再加一层 tls 吗?
    “ DH + Symmetric Crypto + AD 的 Hybrid Encryption 方案” 中 AD 是指?
    我用的 ecies 库也说自己未经安全审查,正在找标准库组合。
    julyclyde
        38
    julyclyde  
       151 天前
    @baobao1270 并不是“已经是错的了”而是“从来都是错的”
    那些所谓科普大部分都是半桶水水平的人写的

    非对称加密应该是从来没有使用在大流量数据交换中,而一直都只是用作交换对称密钥的时候保障对称密钥的安全性
    GeekGao
        39
    GeekGao  
       151 天前
    @baobao1270
    @hxndg

    😂 我想了一下,觉得解决这个理解问题的最好办法是给 OP 提供一种现实使用的方法而非任何理论性的甚至优劣解释。
    干脆,OP 参考 shadowsocks 的加解密过程算了,不用争论了,我觉得满足之前你们所述的算法特征了吧。
    关于 shadowsocks 的加密原理,自行 Google 。
    raw0xff
        40
    raw0xff  
    OP
       151 天前
    @GeekGao 别啊大佬,你们据理力争的时候我都在拿本子边查边记呢


    @julyclyde 所以 ecc 只用来签名验证是高效的?公私钥加解密功能只有三方库有,标准库只有签名验证没有加解密,不知道什么原因
    julyclyde
        41
    julyclyde  
       151 天前
    @raw0xff 具体实现为什么缺这个功能,我也不了解呢
    没看过 lib 的代码

    不过 GnuPG 这种“产品”是可以用非对称进行加解密的,实际上底层还是用对称密码术的,所以可以实现“加密给多个收件人”的功能,就是把一个对称密钥分别非对称加密给多个收件人
    baobao1270
        42
    baobao1270  
       151 天前
    @raw0xff 我记得 WSS 就是 WebSocket over TLS 啊,还是我记错了……
    AD 是输入法打字被吃了,指的是 AEAD

    其实我们讲这么多,都是密码学方案和算法的问题。大家都离题万里,其实楼主要的也是一个可以实行的方案,这里楼主出一个吧:
    X.509 ECC (secp256r1) 证书 + TLS 1.3 双向认证,密钥直接保存在文件里

    下面是对方案的解释:
    1. 楼主想要用 ECC Keypair ,那么就选 secp256r1 吧。从代码可维护和减少编码工作量的角度考虑,建议复用现有格式,也就是 X.509 证书。自己用 openssl (或者其他你喜欢的加密库)自建一个离线 CA ,然后给客户端/节点发证书就行。
    2. 通信协议方面,个人建议 TLS 1.3 。楼主喜欢 WSS 的话也可以用 WSS ,和 TLS 安全性差不多。TLS 1.3 目前所有的 cipher 都是安全的,只要禁用 TLS 1.1-1.2 即可。如果有必要可以开双向认证。用现有协议而不是。WSS 相比 TLS 1.3 的好处是可以走 CDN 。此外,如果楼主还没有决定序列化方案的话,gRPC 也是很不错的选择。
    3. 鉴于你的成本,KMS 就别想啦。用云服务器的话是不可能「安全存储密钥」的——只要云服务商想看就能看。阿里云有卖带 TPM 的云服务器,但是也是贵的离谱。真要做什么的话,你可以在创建服务器的时候勾选「加密磁盘」,至少如果放你云服务器的物理机磁盘被偷了不会导致你的私钥泄露。不过轻量云好像不支持加密磁盘的功能。私钥安全性也不会有什么磨损,不泄漏就行。

    @GeekGao 其实楼主的问题只是问个可以实操到加密通信方案,结果被我们话题歪到密码学原理去了。或许这就是论坛有意思的地方吧,让我看到思维碰撞的火花(
    此外某小飞机的算法算不上高明,比起 Reality 来说设计的失误还是挺多的,Reality 可以说是「源于 TLS 1.3 ,高于 TLS 1.3 」了
    raw0xff
        43
    raw0xff  
    OP
       151 天前
    @baobao1270 gRPC 试过了,因为连接对象有节点对节点也有节点对浏览器,grpc 对浏览器适配不如 ws ,而且项目初期通信内容经常变,已经用 JSON 搞了一套,先不折腾了。

    现在反思在 wss 下,还用端到端加密解密是否多余,因为关键信息到达前已经被 user 手里的公私钥加密和签名,服务端只验证和存储。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1108 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 18:11 · PVG 02:11 · LAX 11:11 · JFK 14:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.