注意
网络部署和测试正在进行中。 可能会有小的修订。 请参阅 SPEC 获取官方规范。
概述
标准Base 32 (“b32”) 地址包含目标的哈希值。 这对于加密的ls2(提案123)不起作用。
您不能为加密的LS2(提案123)使用传统的base 32地址, 因为它仅包含目标的哈希值。它不提供非盲化的公钥。 客户端必须知道目标的公钥、签名类型、 盲化签名类型以及可选的秘密或私钥 才能获取和解密leaseset。 因此,单独的base 32地址是不够的。 客户端需要完整的目标(包含公钥)或仅公钥本身。 如果客户端在地址簿中有完整的目标,并且地址簿 支持按哈希的反向查找,则公钥可以被检索。
因此,我们需要一个新的格式,将公钥而不是哈希放入 base32地址中。此格式还必须包含 公钥的签名类型和盲化方案的签名类型。
本提案记录了这些地址的新b32格式。 虽然我们在讨论中将这种新格式称为“b33”地址, 但实际的新格式保留了通常的“.b32.i2p”后缀。
目标
- 包含非盲化和盲化签名类型以支持未来的盲化方案
- 支持大于32字节的公钥
- 确保b32字符都是或大多数是随机的,尤其是在开头 (不希望所有地址以相同字符开头)
- 可解析
- 指示需要盲化秘密和/或每客户端密钥
- 添加校验和以检测拼写错误
- 最小化长度,保持DNS标签长度少于63字符用于正常使用
- 继续使用base 32以实现不区分大小写
- 保留通常的“.b32.i2p”后缀
非目标
- 不支持包含盲化秘密和/或每客户端密钥的“私人”链接; 这将是不安全的。
设计
- 新格式将包含非盲化的公钥,未盲化的签名类型, 和盲化的签名类型。
- 可选地包含秘密和/或私钥,仅用于私人链接
- 使用现有的“.b32.i2p”后缀,但长度更长。
- 添加一个校验和。
- 加密leasesets的地址由56或更多编码字符 (35或更多解码字节)标识,相对于传统base 32地址的52字符(32字节)。
规范
创建和编码
构造一个主机名为{56+ 字符}.b32.i2p (35+ 字节二进制),如下:
flag (1 byte)
bit 0: 0 表示一字节签名类型,1 表示两字节签名类型
bit 1: 0 表示无秘密,1 表示需要秘密
bit 2: 0 表示无每客户端认证,
1 表示需要客户端私钥
bits 7-3: 未使用,设置为0
public key sigtype (1 or 2 bytes as indicated in flags)
如果是1字节,上位字节假定为零
blinded key sigtype (1 or 2 bytes as indicated in flags)
如果是1字节,上位字节假定为零
public key
字节数量由签名类型隐含
后处理和校验和:
构造如上的二进制数据。
将校验和视为小端。
计算校验和 = CRC-32(data[3:end])
data[0] ^= (byte) checksum
data[1] ^= (byte) (checksum >> 8)
data[2] ^= (byte) (checksum >> 16)
hostname = Base32.encode(data) || ".b32.i2p"
b32末端的任何未使用位必须为0。 对于标准的56字符(35字节)地址,没有未使用的位。
解码和验证
从主机名中去掉“.b32.i2p”
data = Base32.decode(hostname)
计算校验和 = CRC-32(data[3:end])
将校验和视为小端。
flags = data[0] ^ (byte) checksum
如果是1字节签名类型:
pubkey sigtype = data[1] ^ (byte) (checksum >> 8)
blinded sigtype = data[2] ^ (byte) (checksum >> 16)
否则 (2字节签名类型) :
pubkey sigtype = data[1] ^ ((byte) (checksum >> 8)) || data[2] ^ ((byte) (checksum >> 16))
blinded sigtype = data[3] || data[4]
根据flags解析余下内容以获取公钥
秘密和私钥位
秘密和私钥位用于向客户端、代理或其他 客户端代码表明解密leaseset时需要秘密和/或私钥。具体实现可能会提示用户提供 所需数据,或在所需数据缺失时拒绝连接尝试。
正当性
-通过将前3字节与哈希进行XOR操作提供了有限的校验能力, 并确保所有base32字符在开头是随机的。 只有少数标志和签名类型组合是有效的,因此任何拼写错误都可能造成无效组合并将被拒绝。
- 在通常情况下(1字节签名类型,无秘密,无每客户端认证), 主机名将为{56字字符}.b32.i2p,解码为35字节,与Tor相同。
- Tor 2字节校验和具有1/64K的错误否定率。通过3字节,减去一些忽略字节, 我们的接近百万分之一,因为大多数标志/签名类型组合是无效的。
- Adler-32对于小输入和检测小变化选择很差 。 改用CRC-32。CRC-32速度快且被广泛使用。
缓存
尽管不在本提案的范围内,路由器和/或客户端必须记住并缓存 (可能是持久性的)公钥与目标的映射,反之亦然。
说明
- 通过长度区分新旧口味。旧b32地址始终为{52字字符}.b32.i2p。新地址为{56+字字符}.b32.i2p。
- Tor讨论线程:https://lists.torproject.org/pipermail/tor-dev/2017-January/011816.html
- 不要期望2字节签名类型会发生,我们仅到13。现在无需实现。
- 如果需要,新格式可以像b32一样用于跳转链接(并由跳转服务器提供)。
问题
- 任何大于32字节的秘密、私钥或公钥将会超过DNS最大标签长度63字符。浏览器可能不在意。
迁移
没有向后兼容的问题。旧软件中长的b32地址将无法转换为32字节的哈希。