#peer-id #trust #key-pair #trust-graph #node #p2p #signature

fluence-keypair

基于 libp2p-identity 的统一密钥对 API

11 个不稳定版本

0.10.4 2023年12月25日
0.10.3 2023年7月4日
0.10.2 2023年6月29日
0.10.0 2023年3月16日
0.4.0 2021年9月30日

1641魔法豆 中排名

Download history 109/week @ 2024-04-08 175/week @ 2024-04-15 121/week @ 2024-04-22 83/week @ 2024-04-29 51/week @ 2024-05-06 300/week @ 2024-05-13 322/week @ 2024-05-20 166/week @ 2024-05-27 246/week @ 2024-06-03 53/week @ 2024-06-10 71/week @ 2024-06-17 210/week @ 2024-06-24 53/week @ 2024-07-01 28/week @ 2024-07-08 145/week @ 2024-07-15 417/week @ 2024-07-22

653 次每月下载
用于 9 仓库(8 个直接使用)

Apache-2.0

59KB
1K SLoC

信任图

概述

在 Web 2.0 中,通过集中式证书授权机构(CA)解决了访问控制和权限问题。然而,考虑到 Web 3.0 的去中心化特性,此类问题更加紧迫且更具挑战性。信任图是我们对这个挑战的解决方案的看法。

信任图是开放 p2p 网络的信任底层:每个节点都可以提供类似 SSL 的证书,并在网络上推广。服务提供商和节点可以根据其证书集对其持证人进行不同的处理。

信任图是一个基本组件,允许存储和管理证书,无需额外的逻辑来决定信任谁以及将谁视为不可靠。

为什么它很重要?

在P2P网络中,同伴选择和优先级的问题非常紧迫。如果没有对任何网络参与者的信任,我们无法可靠和可预测地使用网络。我们还应该标记并避免恶意同伴。此外,我们需要在运行时控制应用程序的访问和权限,以确保其连续运行,不受中断和重新部署的影响。

它是什么?

TrustGraph基本上是一个至少有一个根的有向图,顶点是同伴ID,边是两种类型的加密关系之一:信任和撤销。

是一个我们无条件信任直到其被删除的同伴ID,由节点所有者定义。每个根都有代表信任链最大长度的特征。

作为到根的路径,我们考虑只有信任边的路径,给定以下规则:链 R -> A -> ...-> C 如果A撤销了C,则它不是一个路径。

信任是一种表示同伴A在信任到期或被撤销之前信任同伴B的加密关系。信任关系是可传递的。如果同伴A信任同伴B,而同伴B信任同伴C,则结果是同伴A通过传递信任同伴C。信任关系意味着你基于你的业务逻辑和选择的指标信任连接、计算或存储。例如,如果你要执行某些计算,一些知名同伴也在做这件事,并且他们被你信任的人所信任,因此你可以安全地使用他们进行计算,但不用于存储敏感信息(个人密钥等)。

信任数据结构包含以下字段

  • 同伴ID,信任是颁发给
  • 创建时间戳
  • 过期时间戳
  • 发行者签名的签名,包含所有之前字段签名的签名

因此,信任是通过设计进行了签名和防篡改的。

证书是以自签名根信任开始的信任链。考虑到信任和证书数据结构,可以跟踪信任关系的链:链中第一个信任的issued_for字段指示根同伴ID,第二个——根信任谁,等等。因此,如果我们在证书中有链 R->A->B->C,它看起来像以下信任的链: R->RR->AA->BB->C。证书是不可篡改的,因为它是由已签名的信任组成的。

image

因此,如果同伴A在TrustGraph实例中与同伴B之间有路径,则同伴A被同伴B信任。证书的选择是主观的,由节点所有者通过选择根和最大链长度来定义。目前,对于通用情况还没有默认指标。

撤销是一种表示同伴A认为同伴C是恶意或不可靠的加密关系。例如,包含从A到C路径的所有链将不会被处理为有效。因此,如果A信任同伴B,而B信任同伴C,同伴A对C的信任将不会是传递的,否则会。

image

每个同伴都有一个权重。权重表示2的幂或零。如果没有从任何根到同伴的路径,考虑到撤销,其权重为零。越靠近根,权重越大。权重也是主观的,在局部TrustGraph范围内相关。

image

TrustGraph是内置的,意味着每个节点都捆绑了一个TrustGraph实例和预定义的证书。

在密码学关系方面,信任是可传递的。另一方面,由于根的选择,每个网络参与者对信任和证书的子集是主观的。

如何在 Aqua 中使用它

如何导入

import "@fluencelabs/trust-graph/trust-graph-api.aqua"
import "@fluencelabs/trust-graph/trust-graph.aqua"

func my_function(peer_id: string) -> u32:
   on HOST_PEER_ID:
       result <- get_weight(peer_id)
   <- result

如何添加根

  • set_root(peer_id:PeerId,max_chain_len: u32) ->SetRootResult
  • add_root_trust(node:PeerId,peer_id:PeerId,max_chain_len: u32) -> ?Error

让我们将我们的对等方ID设置为中继上的根,并添加自签名信任

func set_me_as_root(max_chain_len):
  result <- add_root_trust(HOST_PEER_ID, INIT_PEER_ID, max_chain_len)

  -- if you use peer_id different from INIT_PEER_ID
  -- you should add keypair in your Sig service
  if result.success:
     -- do smth
     Op.noop()
  else:
     -- handle failure
     Op.noop()
  • 你也可以使用 set_root + add_trust 来实现相同的目标
  • 如何将密钥对添加到Sig服务
  • 只有服务所有者才能添加根
  • max_chain_len 指定了根的信任链中的信任数量。对于只包含根信任的链,为零。

如何颁发和添加信任

  • issue_trust(issuer:PeerId,issued_for:PeerId,expires_at_sec: u64) -> ?Trust, ?Error
  • import_trust(trust:Trust,issuer:PeerId) -> ?Error
  • add_trust(node:PeerId,issuer:PeerId,issued_for:PeerId,expires_at_sec: u64) -> ?Error

让我们发行信任,并将其导入到我们的中继

func issue_trust_by_me(issued_for: PeerId, expires_at_sec: u64):
  trust, error <- issue_trust(INIT_PEER_ID, issued_for, expires_at_sec)
  if trust == nil:
     -- handle failure
     Op.noop()
  else:
     on HOST_PEER_ID:
        error <- import_trust(trust!, INIT_PEER_ID)
        -- handle error
  • add_trustissue_trustimport_trust 的组合
  • 如果你想不是通过 INIT_PEER_ID 发行信任,请查看Sig服务的 文档

如何撤销信任

  • issue_revocation(revoked_by:PeerId,revoked:PeerId) -> ?Revocation, ?Error
  • import_revocation(revocation:Revocation) -> ?Error
  • revoke(node:PeerId,revoked_by:PeerId,revoked:PeerId) -> ?Error

让我们通过我们的对等方ID撤销一些对等方

func revoke_peer(revoked: PeerId):
  revocation, error <- issue_revocation(INIT_PEER_ID, revoked)
  if revocation == nil:
     -- handle failure
     Op.noop()
  else:
     on HOST_PEER_ID:
        error <- import_revocation(revocation!)
        -- handle error
  • revokeissue_revocationimport_revocation 的组合
  • 如果你想不是通过 INIT_PEER_ID 发行撤销,请查看Sig服务的 文档

如何获取证书

  • get_all_certs(issued_for:PeerId) ->AllCertsResult
  • get_all_certs_from(issued_for:PeerId,issuer:PeerId) ->AllCertsResult
  • get_host_certs() ->AllCertsResult
  • get_host_certs_from(issuer:PeerId) ->AllCertsResult

让我们获取我们向我们的中继对等方ID(HOST_PEER_ID)颁发的所有证书

func get_certs_issued_by_me() -> AllCertsResult:
  on HOST_PEER_ID:
     result <- get_host_certs_from(INIT_PEER_ID)
  <- result
  • get_host_certs 只是 get_all_certs(HOST_PEER_ID) 的别名
  • _from 调用的结果只包含由 issuer 颁发的证书

如何获取权重

  • get_weight(peer_id:PeerId) ->WeightResult
  • get_weight_from(peer_id:PeerId,issuer:PeerId) ->WeightResult

让我们获取我们的中继为我们包含信任的证书的权重

func get_our_weight() -> ?u32, ?string:
  weight: ?u32
  error: ?string
  on HOST_PEER_ID:
     result <- get_weight_from(INIT_PEER_ID, HOST_PEER_ID)
     if result.success:
        weight <<- result.weight
     else:
        error <<- result.error
  <- weight, error
  • get_weight 返回所有证书的结果,另一方面,get_weight_from 仅返回包含发行者信任的证书

如何在 TS/JS 中使用它

  1. 如Aqua 文档 中所述,添加 export.aqua

  2. 将以下内容添加到您的依赖项中

    • @fluencelabs/trust-graph
    • @fluencelabs/aqua
    • @fluencelabs/aqua-lib
    • @fluencelabs/fluence
    • @fluencelabs/fluence-network-environment
  3. 导入依赖项

import * as tg from "./generated/export";
import { Fluence, KeyPair } from "@fluencelabs/fluence";
import { krasnodar, Node } from "@fluencelabs/fluence-network-environment";
  1. 创建一个客户端(如果您是节点所有者,请指定密钥对 链接
await Fluence.start({ connectTo: relay /*, KeyPair: builtins_keypair*/});
  1. 添加一个根并发行根信任。
let peer_id = Fluence.getStatus().peerId;
let relay = Fluence.getStatus().relayPeerId;
assert(peer_id !== null);
assert(relay !== null);
let max_chain_len = 2;
let far_future = 99999999999999;
let error = await tg.add_root_trust(relay, peer_id, max_chain_len, far_future);
if (error !== null) {
 console.log(error);
}
  1. 默认情况下,使用客户端的私钥签名的信任/撤销。要使用不同的密钥签名,请参阅Sig服务的 文档
// issue signed trust
let error = await tg.issue_trust(relay, peer_id, issued_for_peer_id, expires_at_sec);
if (error !== null) {
 console.log(error);
}

用例

创建可信子网络

您可以使用您选择的信任或选择的标准来组织子网络,因此您可以将对等方(或密钥)提供的信任视为证据。

让我们假设我们有对等方A、B和C

  • 选择一个对等方A作为权威,将其设置为所有对等方的本地TrustGraphs的根
  • 由对等方A签发并放置自签名的信任作为根信任
  • 由对等方A对对等方B和对等方C签发信任,并将它们放置在所有对等方上
  • 因此,对于调用 get_weight_from(targetPeer, peerA) 将反映目标对等方是否在子网络ABC中

服务权限管理

您可以根据本地的信任图(证书、权重)在运行时指定谁可以访问服务功能。可以通过四元组来检查证明的来源。例如,只有具有非零权重的对等节点才能执行服务函数trusted_call(weight: WeightResult) -> u8

因此,如果您想进行服务权限管理,应遵循以下步骤:

  • WeightResult从信任图传递到您需要控制的函数。
...
weight_result <- get_weight(INIT_PEER_ID)
result <- MyService.trusted_call(weight_result)
...
  • 在您的服务内部,您需要检查类似这个的四元组,以确保它们来自本地的信任图。
  • INIT_PEER_ID或另一个选定的密钥作为根。
  • 对可以调用此函数的对等节点颁发信任。
func grant_access(issued_for: PeerId, expires_at_sec: u64):
  error <- add_trust(INIT_PEER_ID, issued_for, expires_at_sec)
  if error != nil
     -- handle error

标记可信对等节点并在这些节点上执行计算

查看示例

常见问题解答

  • 权重会在时间中改变吗?

    • 如果到根的最短路径改变,在信任过期、导入或撤销的情况下,权重也会改变。
  • 零权重意味着什么?

    • 零权重表示没有任何信任和从任何根到目标对等节点的路径。
  • 我们如何解释证书和/或对等节点的权重?

    • 证书包含从根到我们要寻找的目标对等节点的路径。权重表示这些证书和对等节点与根的接近程度。
  • 权重是如何计算的,基于什么反馈?

    • 权重是根据从根到信任链的存在来计算的。例如,如果我们有一个最大链长度等于4的根,有一个链R -> A -> B -> C,那么相应对等节点的权重分别是8421。如果路径没有变化,权重是相同的。只要我们没有度量标准,所有信任/撤销逻辑都是信任图用户的责任。
  • 我如何将所有权重设置为不可信,然后随着时间的推移增加对等节点的信任?

    • 所有对等节点默认情况下都是不可信的。信任不可测量,权重表示对等节点与根的距离,权重越大,距离根越近,所以如果您想增加目标对等节点的权重,您应该从根或比该对等节点更接近根的对等节点获得信任。
  • 我如何知道其他对等节点是否使用相同的流程来更新权重?

    • 权重是基于包含不可变签名的信任证书本地计算的。权重是主观的,只对本地此对等节点有意义。
  • 我可以启动自己的信任图实例,还是只有全球版本可用?

    • 每个Fluence节点都附带内置的信任图实例,但如果您是节点所有者,您可以更改或删除任何您想要的服务。

API

高级API定义在trust-graph-api.aqua模块中。API参考很快将在文档中提供。

目录结构

  • src 是包含所有信任图逻辑的主要项目

  • keypair 目录是一个抽象的加密层(密钥对、公钥、签名等)

  • service 是一个提供 marine API 的包,可以被编译成 Wasm 文件。它使用 SQLite 作为存储

  • example 是一个 js 脚本,展示了如何使用 Trust Graph 为对等节点打标签

  • builtin-package 包含生成内置包的蓝图、配置和脚本,本地或通过 CI 生成

  • admin 是一个 js 脚本,用于生成 builtin-package/on_start.json,其中包含 Fluence Labs 节点的证书

学习 Aqua

依赖

~4–15MB
~220K SLoC