如何实现端到端加密,该如何设计

设备(端)的定义

我们对“设备”有特殊的含义。作为用户,我可能有多个设备(桌面客户端、一些网络浏览器、Android 设备、iPhone 等)。当我第一次使用客户端时,它应该将自己注册为新设备。如果我注销并以其他用户身份再次登录,则客户端必须注册为新设备。至关重要的是,客户端必须为每个“设备”创建一组新的密钥。

设备的寿命将取决于客户端。在 Web 客户端中,我们会在您每次登录时创建一个新设备。在移动客户端中,如果登录会话过期, 如果用户相同,则可以重新使用该设备。切勿在不同用户之间共享密钥。

设备由它们标识device_id(在给定用户的范围内是唯一的)。默认情况下,/loginand/register 端点会自动生成 adevice_id并在响应中返回它;客户端也可以自由生成自己device_id的设备,或者如上所述,重用设备,在这种情况下,客户端应该 device_id在请求正文中传递 。

设备的寿命和access_tokens密切相关。device_id在每次登录时都会创建一个新设备的简单情况下,a和 an之间存在一对一的映射access_token。如果客户端device_id在登录时重用 a,将会有几个 access_tokens 与给定的关联device_id- 但是,我们仍然希望其中只有一个同时处于活动状态(尽管我们目前在 Synapse 中没有强制执行)。

端到端加密中使用的密钥

Ed25519指纹密钥对

Ed25519 是用于签署消息的公钥加密系统。

Curve25519 身份密钥对

Curve25519 是一种公钥密码系统,可用于建立共享秘密。

Curve25519 一次性键

除身份密钥外,每个设备还创建多个 Curve25519 密钥对,这些密钥对也用于建立 Olm 会话,但只能使用一次。隐私部分再次保留在设备上。

在启动时,Alice 创建了许多一次性密钥对,并将它们发布到她的家庭服务器。如果 Bob 想与 Alice 建立一个 Olm 会话,他需要获取 Alice 的一个一次性密钥,并创建一个他自己的新密钥。这两个密钥与 Alice 和 Bob 的身份密钥一起用于在 Alice 和 Bob 之间建立 Olm 会话。

Megolm 加密密钥

Megolm 密钥用于加密组消息(实际上它用于派生 AES-256 密钥和 HMAC-SHA-256 密钥)。它用随机数据初始化。每次发送消息时,都会对 Megolm 密钥进行哈希计算,以导出下一条消息的密钥。因此,可以与用户共享 Megolm 密钥的当前状态,允许他们解密未来的消息,但不能解密过去的消息。

Ed25519 Megolm 签名密钥对

当发件人创建 Megolm 会话时,他还会创建另一个 Ed25519 签名密钥对。这用于对通过该 Megolm 会话发送的消息进行签名,以验证发件人。再一次,密钥的私有部分仍保留在设备上。公共部分与加密密钥旁边的房间中的其他设备共享。

创建和注册设备密钥

此过程仅在设备首次启动时发生一次。

它必须创建 Ed25519 指纹密钥对和 Curve25519 身份密钥对。这是通过调用olm_create_account libolm 来完成的。通过调用来检索(base64 编码的)键 olm_account_identity_keys。应存储该帐户以备将来使用。

然后它应该将这些密钥发布到主服务器,这是通过使用keys/upload 接口的device_keys属性来 完成的。

创建和注册一次性密钥

客户端应跟踪主服务器为其存储了多少一次性密钥,并在必要时生成并上传更多。

这可以通过检查响应的device_one_time_keys_count 属性来实现。/sync/

libolm 支持的最大活动键数由 olm_account_max_number_of_one_time_keys. 客户端应该尝试在主服务器上保持这个数字的一​​半左右。

要生成新的一次性密钥:

  • 调用olm_account_generate_one_time_keys以生成新密钥。

  • 调用olm_account_one_time_keys以检索未发布的密钥。这将返回一个带有单个属性的 JSON 格式的对象 curve25519,它本身就是一个对象映射键 id 到 base64 编码的 Curve25519 键。例如:

    {

      "curve25519": {

        "AAAAAA": "wo76WcYtb0Vk/pBOdmduiGJ0wIEjW4IBMbbQn7aSnTo",

        "AAAAAB": "LRvjo46L1X2vx69sS9QNFD29HWulxrmW11Up5AfAjgU"

      }

    }

  • 每个密钥都应该以与之前的身份密钥有效负载相同的方式进行签名,并使用keys/upload接口的one_time_keys属性进行 上传。

  • 调用olm_account_mark_keys_as_published以告诉 olm 库不要从未来调用返回相同的键 olm_account_one_time_keys

curve25519-aes-sha2

事件内容的sender_key属性给出了发送者的 Curve25519 身份密钥。客户应该为他们与之交谈的每台设备维护一个已知的 Olm 会话列表;建议通过 Curve25519 身份密钥对它们进行索引。

Olm 消息为每个接收设备单独加密。 ciphertext是来自接收设备的 Curve25519 身份密钥的对象映射。接收客户端当然应该在这个对象中寻找自己的身份密钥。(如果它没有被列出,则没有为它发送消息,并且客户端无法解密它;它应该显示一个错误,或者类似的)。

这应该会产生一个具有属性type和的对象body。“0”类型的消息是“prekey”消息,用于在两个设备之间建立新的 Olm 会话;类型“1”是在会话中收到消息后使用的普通消息。

当收到一条消息(任一类型)时,客户端应首先尝试使用该发送者的每个已知会话对其进行解密。有两个步骤:

  • 如果(且仅当)type==0,客户端应 olm_matches_inbound_session使用会话和body. 这将返回一个标志,指示消息是否使用该会话加密。
  • olm_decrypt客户端通过会话调用,type和 body。如果成功,则返回事件的明文。

如果客户端无法使用任何已知会话解密消息(或者如果还没有已知会话),并且消息的类型为 0, 并且 olm_matches_inbound_session对于任何现有会话都不是真的,那么客户端可以尝试建立新会话. 这是按如下方式完成的:

  • olm_create_inbound_session_from使用 olm 帐户调用,sender_key以及body消息的和。
  • 如果会话建立成功:
    • 调用olm_remove_one_time_keys以确保不能重复使用相同的一次性密钥。
    • olm_decrypt与新会话通话。
    • 存储会话以供将来使用。

最后,客户端有望成功解密有效载荷。

除了typecontent属性外,明文有效负载还应包含许多其他属性。每一项都应检查如下2

  • sender: 发件人的用户 ID。客户端应检查这是否与sender事件中的 匹配。

  • recipient: 收件人的用户 ID。客户端应检查这是否与本地用户 ID 匹配。

  • keys:具有属性的对象ed25519,keys被验证时,客户端应检查此属性的值是否与发送者的指纹密钥匹配。

  • recipient_keys:具有属性的对象ed25519。客户端应检查此属性的值是否与其自己的指纹密钥匹配。

aes-sha2

使用此算法的加密事件应具有sender_keysession_idciphertextcontent 属性。如果room_id和 对应于已知的 Megolm 会话(见 sender_key下文,则可以通过将密文传递给 来解密密文。session_idolm_group_decrypt

为了避免重放攻击,客户端应该记住 他们为每个会话解密的每个事件message_index返回的 megolm。olm_group_decrypt如果客户端解密一个与 message_index它已经使用该会话接收到的事件相同的事件,那么它应该将该消息视为无效。但是,当一个事件被多次解密时,必须小心不要将其标记为重放攻击。例如,当客户端解密事件时,可能会发生这种情况,该事件从客户端的缓存中清除,然后客户端回填并重新解密该事件。处理这种情况的一种方法是确保在message_index清除客户端的事件缓存时适当地清除 es 的记录。另一种方法是记住事件的 event_idorigin_server_tsmessage_index. 当客户端解密一个与 message_index先前解密的事件匹配的事件时,它可以比较它记住的event_id和,如果这些字段匹配,则应该正常解密消息。origin_server_tsmessage_index

当事件被已验证时,客户端应检查发送者的指纹密钥是否与 keys.ed25519建立 Megolm 会话的事件的属性相匹配。

为房间内的用户下载设备列表

在发送加密消息之前,有必要为房间中的每个用户检索设备列表。这可以主动完成,也可以推迟到发送第一条消息。用户还需要这些信息来验证或阻止该消息。

客户端应该使用device_keys接口,在请求的属性中 传递房间成员的 ID 。

客户端必须使用DeviceKeys返回 的对象的签名。为此,它应该删除和属性,将其余部分格式化为规范 JSON,并将结果传递到 ,使用参数的 Ed25519 密钥和参数的相应签名。如果签名检查失败,则不应在设备上进行进一步处理。signaturesunsignedolm_ed25519_verifykeysignature

客户端还必须检查对象中的user_iddevice_id字段是否与顶级映射3中的字段匹配。

客户端应该检查user_id/是否device_id对应于它之前看到的设备。如果是,客户端必须检查 Ed25519 密钥是否未更改。同样,如果它已更改,则不应在设备上进行进一步处理。

否则,客户端将存储有关此设备的信息。

发送加密消息事件

在房间中发送消息时,客户端首先检查它是否具有活动的出站 Megolm 会话。如果没有,它首先会创造一个。如果存在出站会话,它应该检查是否该 替换它,如果是则创建一个新会话。

然后客户端构建一个加密有效载荷,如下所示:

<span style="color:#333333"><span style="background-color:#ffffff"><span style="color:black"><code class="language-text">{
  "type": "<event type>",
  "content": "<event content>",
  "room_id": "<id of destination room>"
}</code></span></span></span>

并调用olm_group_encrypt加密有效载荷。然后将其打包到事件内容中,如下所示:

<span style="color:#333333"><span style="background-color:#ffffff"><span style="color:black"><code class="language-text">{
  "algorithm": "m.megolm.v1.aes-sha2",
  "sender_key": "<our curve25519 device key>",
  "ciphertext": "<encrypted payload>",
  "session_id": "<outbound group session id>",
  "device_id": "<our device ID>"
}</code></span></span></span>

最后,加密的事件被发送到房间 PUT消息

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.项目代码功能经验证ok,确保稳定可靠运行。欢迎下载使用!在使用过程中,如有问题或建议,请及时私信沟通。 2.主要针对各个计算机相关专业,包括计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师或企业员工使用。 3.项目具有丰富的拓展空间,不仅可作为入门进阶,也可直接作为毕设、课程设计、大作业、初期项目立项演示等用途。 4.当然也鼓励大家基于此进行二次开发。 5.期待你能在项目中找到乐趣和灵感,也欢迎你的分享和反馈! 【资源说明】 基于Python的端到端数据流量伪装加密研究项目源码(含说明文档+详细注释).zip 如何运行 + 运行本地 ``` python server_local.py ``` + 运行远程 ``` python server_remote.py ``` 仅支持TCP,不支持UDP + Socks5代理仅支持IPv4,不支持IPv6 简介 + 在配置正确的情况下,python3、java、Android版本的local和remote可以配合使用。 + local实现了HTTP(S)、SOCKS5、SNI的自动代理,仅需一个口,即可自动识别各种代理类型。 + local支持pac文件解析,可将流量分为直连和走remote两种。 + local到remote可以套上一层HTTP(S),表现行为与Websocket无异,经测试**可过CDN与Nginx**。 + local到remote支持简单的用户名密码验证。 + 支持一种特殊模式,该模式下将数据原封不动加密转发,remote解密后识别特征再进行HTTP(S)、SOCKS5、SNI的自动代理。 + 包含了一个不成熟的DNS服务器实现,可以通过DNS over HTTPS查询结果,再以UDP报文的方式返回结果。 相关Repo | 项目名称 | 简介 | | ------------- | ------------- | python3实现,包含local、remote ## :star:一句话说明 将本地代理数据伪装成指向远程的HTTP(S) WebSocket流量。端到端数据流量伪装加密研究

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值