1 个不稳定版本
0.1.0 | 2019年12月14日 |
---|
#2163 in 加密学
在 py-pkstl 中使用
130KB
2.5K SLoC
公钥安全传输层
常见问题解答 (FAQ)
什么是 PKSTL
PKSTL (公钥安全传输层) 是一个安全层,确保两个程序在任意网络(互联网、局域网或其他)之间的通信的真实性和机密性。
PKSTL 对底层网络协议无感知,只要它允许交换二进制消息即可。
例如,PKSTL 与 WebSocket 协议兼容,但它不依赖于 WebSocket 协议。
先决条件
两个程序中的每一个都必须有一个 Ed25519 密钥对。发起连接的程序(在客户端/服务器通信的情况下)必须首先知道用户希望联系的服务器的 ed25519 公钥。
为什么要使用它?
最常见的安全通信协议需要生成由认证机构签名的证书。
这并不是一种去中心化的方式,因为您必须获得“认证机构”的认证。然而,谁决定谁可以成为认证机构呢?
此外,证书的生成要么成本高昂,要么需要对区块链服务器的最终用户进行复杂且频繁的技术操作。
在 Duniter/G1 生态系统中,所有区块链服务器都有自己的 Ed25519 密钥对。我们可以利用这一点,因此我们不需要证书,从而允许最终用户自动拥有安全的服务器(零配置)。
### 它是如何工作的
通信通过通过 Diffie-Hellman 交换生成的共享秘密进行对称加密。
两个程序之间交换的前两条消息是明文但已签名的,它们构成了协商阶段。此协商阶段用于生成共享秘密并验证另一个程序是否拥有与其实际公钥对应的私钥。
一旦协商阶段完成,所有交换的消息都进行散列和加密(在这个阶段不再需要签名,因为消息的散列也进行了加密,因此中间人无法无痕迹地更改它)。
约定
字节序
所有数字(整数和浮点数)都使用大端序编码。
类型定义
u8:无符号8位整数。
u16:无符号16位整数。
u32:无符号32位整数。u64:无符号64位整数。
协商阶段
协商阶段是完全对称的,因此观察者无法区分“客户端”和“服务器”。这使得PKSTL可以在对等和客户端/服务器环境中使用。
每个程序发送一个CONNECT消息和一个ACK消息。ACK消息是对另一个程序CONNECT消息的响应。协商阶段的进展可以用两个线程各3步来描述。
本地线程
- 准备CONNECT消息
- 已发送CONNECT消息
- 已收到有效的ACK消息
远程线程
- 等待来自另一个程序的CONNECT消息
- 接收有效的CONNECT消息
- 已发送有效的ACK消息
当两个线程达到第3步时,则认为协商阶段成功完成。
共享密钥
共享密钥由Diffie-helman交换生成。出于安全原因,每个程序用于DH交换的密钥对是临时的密钥对,为一次性使用随机生成。
加密算法的种子是通过HMAC_SHA384派生得到的,HMAC函数的盐是两个临时公钥中的较大值。
加密算法
对称加密算法是Chacha20/Poly1305。
加密密钥对应于种子的前32字节。nonce对应于下一个12字节,而aad对应于最后4字节。
消息格式
所有消息的格式如下
字段 | 大小 | 类型 | 值 |
---|---|---|---|
MAGIC_VALUE | 4 | - | 0xE2C2E2D2 |
VERSION | 4 | u32 | 1 |
ENCAPSULED_MSG_LEN | 8 | u64 | |
MSG_TYPE | 2 | u16 | {0,1,2} |
MSG_CONTENT | *X | [u8;X] | |
SIGNATURE | 0或64 | [u8;64] | |
HASH | 0或32 | [u8;32] |
*X = ENCAPSULED_MSG_LEN - 2
MAGIC_VALUE := 识别这是PKSTL协议消息的特殊值。
VERSION := 允许对PKSTL协议进行版本控制,因此可以未来进化。
ENCAPSULED_MSG_LEN := 封装消息长度(MSG_TYPE + MSG_CONTENT)
MSG_TYPE
值 | 消息类型 |
---|---|
0 | USER |
1 | CONNECT |
2 | ACK |
如果MSG_TYPE == 2
,则所有消息都是加密的。否则,所有消息都是明文。
MSG_CONTENT := 按消息类型查看详细信息
SIGNATURE := 仅用于CONNECT和ACK消息。Ed25519签名所有前面的字节。
HASH := 仅用于USER消息。Sha256哈希所有前面的字节。
CONNECT消息
MSG_CONTENT
字段 | 大小 | 类型 | 值 |
---|---|---|---|
EPK | 32 | [u8;32] | |
SIG_ALGO | 4 | u32 | 1 |
SIG_PUBKEY | 32 | [u8;32] | |
CUSTOM_DATAS | *Y | [u8;Y] |
*Y = X - 68
APK := 临时公钥。
SIG_ALGO := 1
表示 Ed25519
算法。此字段存在是为了预测未来将使用不同的算法。
SIG_PUBKEY := 远程程序的签名公钥。
CUSTOM_DATAS := 可选的免费用户应用程序数据(明文)。
ACK消息
MSG_CONTENT
字段 | 大小 | 类型 | 值 |
---|---|---|---|
CHALLENGE | 32 | [u8;32] | 远程EPK的Sha256 |
CUSTOM_DATAS | *Z | [u8;Z] |
*Z = X - 32
CHALLENGE := 远程临时公钥的Sha256哈希。
CUSTOM_DATAS := 可选的免费用户应用程序数据(明文)。
USER消息
字段 | 大小 | 类型 | 值 |
---|---|---|---|
CUSTOM_DATAS | *X | [u8;X] |
CUSTOM_DATAS := 用户应用程序数据(加密)。
依赖关系
~5.5–8MB
~233K SLoC