ROS2中的安全加密通信——sros2工具和身份验证

ROS2安全通信使用DDS的安全机制,创造enclave安全飞地(直译,也可称为安全域),在安全飞地内,安全飞地内的进程受安全保护,进程相互之间进行安全通信。安全飞地内的进程与安全飞地外的进程通信受限(根据用户安全设置)。

具体使用了流程可以参考官网Security — ROS 2 Documentation: Humble documentation

以下说明以FastDDS为例简单介绍一些ROS2中的安全机制:

sros2工具

ROS2安全通信使用安全证书进行签名、身份认证、密钥交换等操作,开发调试环境可由本地用户担任server角色(也可采用专门的安全server),本地用户可同时担任server与client。

安全证书由ros2的sros2模块包创建和管理,生成的证书被放置在密钥库中。一个典型的密钥库包含以下结构:

其中,public与private为安全CA证书目录,enclaves为安全飞地证书目录,放置用户节点进程证书。

  • public

主要包含ca.cert.pem,为CA公共证书, client验证指纹使用,所有客户端共用一份;identity_ca.cert.pem和 permissions_ca.cert.pem为指向 CA公共证书的链接,代替CA公共证书分别处理身份验证、访问控制等场景下的验证身份操作。

  •  private

主要包含ca.key.pem,为CA私钥,CA签名证书使用,由server自行保存;identity_ca.key.pem和 permissions_ca.key.pem为指向 CA私钥的链接,代替CA公共证书分别处理身份验证、许可等场景下签名操作。

  • enclaves

cert.pem:此enclave实例的x.509证书(由IdentityCA 签名),包含公钥。

key.pem:此enclave实例的私钥。

identity_ca.cert.pem :指向身份验证插件信任的 CA 的 x.509 公共证书(“Identity”CA)的链接。

permissions_ca.cert.pem :指向访问控制插件信任的 CA 的 x.509 公共证书的链接。

governance.p7s :链接,指向访问控制插件指定保​​护域规则的 XML 文档(由CA 签名)

permissions.xml: 指定此特定 enclave 实例对访问控制插件的权限的 原始XML 文档.

permissions.p7s:以上permissions.xml经过CA签名后的副本,实际通信操作中使用此副本。

另外enclaves目录下有个公共的governance.p7s :为以上的安全飞地governance.p7s 链接指向的xml文档,由CA签名,governance.xml:为governance.p7s未经CA签名的原始xml文件。

证书身份验证与密钥交换

初始化CA根证书,可以client内置也可以终端首次运行时从服务端获取。

生成enclaves证书并上传服务器进行CA签名,同时本地保存好enclaves私钥,服务器使用根证书签名后返回证书。后续 DomainParticipant 就可以使用这个证书进行发现服务的身份鉴定。证书交换、签名过程如下:

Client使用CA根证书,通过验证证书的签名验证本地安全证书的合法性。

Client验证证书身份通过后,进入握手环节。

1)握手环节中p1(即participant1)验证远端p2(即participant2)证书后,生成本地随机数,经过一定的密钥算法计算为dh1后,将dh1与p1随机数用公钥加密后发给远端p2;

2)p2验证远端p1证书后,使用私钥解密获得dh1,生成本地随机数,计算生成dh2,将dh1、dh2、p2随机数用公钥加密后发给远端p1;p2使用本地随机数及dh1生成共享对称密钥。

3)p1使用本地随机数以及dh2计算生成共享对称密钥。

5)p1、p2经过计算获得协商后的对称加密密钥,完成握手及密钥交换。后续采用对称加密密钥进行加密通信。

ROS2使用插件实现身份验证、数据加密、访问控制等功能,其中实现身份验证的插件名为“DDS:Auth:PKI-DH”, 符合 DDS 安全规范。DDS:Auth:PKI-DH 插件使用受信任的证书颁发机构(CA) 和 ECDSA 数字签名算法来执行相互身份验证。它还使用椭圆曲线 Diffie-Hellman (ECDH) 密钥协商方法建立共享密钥,此共享密钥可以被其他安全插件如加密插件等使用。使用身份验证插件时,需要配置的主要属性包括身份_ca路径、身份证书路径、私钥路径。配置示例如下所示:

DomainParticipantQos pqos;

// Activate DDS:Auth:PKI-DH plugin
pqos.properties().properties().emplace_back("dds.sec.auth.plugin",
        "builtin.PKI-DH");

// Configure DDS:Auth:PKI-DH plugin
pqos.properties().properties().emplace_back(
    "dds.sec.auth.builtin.PKI-DH.identity_ca",
    "file://maincacert.pem");
pqos.properties().properties().emplace_back(
    "dds.sec.auth.builtin.PKI-DH.identity_certificate",
    "file://partcert.pem");
pqos.properties().properties().emplace_back(
    "dds.sec.auth.builtin.PKI-DH.identity_crl",
    "file://crl.pem");
pqos.properties().properties().emplace_back(
    "dds.sec.auth.builtin.PKI-DH.private_key",
    "file://partkey.pem");
pqos.properties().properties().emplace_back(
    "dds.sec.auth.builtin.PKI-DH.password",
    "domainParticipantPassword");
身份验证的代码实现分析
  • 初始化

在ros2/rmw_fastrtps/rmw_fastrtps_shared_cpp/participants.cpp,新建participants函数中,从rmw_security_options_t结构中获取密钥库路径、配置安全插件,包括配置启用“身份鉴定”插件、配置根证书、安全飞地证书、安全飞地私钥的路径等。

  • 验证本地证书合法性

建立participants后,在eProsima/Fast-DDS/src/cpp/rtps/security/SecurityManager.cpp的SecurityManager::init()函数中调用

validate_local_identity()函数(函数实现在eProsima/Fast-DDS/security/authentication/PKIDH.cpp的PKIDH类中,该类继承自Authentication类),使用根证书,验证本地Participant的identity_certificate证书合法性,此函数返回当前 participant 的句柄IdentityHandle,以及在 DDS 网络中唯一的身份标识GUID_t。

  • 其它participant初始化操作

在SecurityManager::init()函数中相继调用validate_local_permissions(),check_create_participant(),get_permissions_credential_token(),set_permissions_credential_and_token(),get_participant_sec_attributes()等函数,完成participant初始化。

  • 握手

在PDPSimple.cpp的PDPSimple::assignRemoteEndpoints( )->SecurityManager.cpp的

SecurityManager::discovered_participant()函数中(即在发现远端participant时),调用

validate_remote_identity(),该函数实现在PKIDH.cpp中,验证远端证书合法性。

在PDPSimple.cpp的PDPSimple::assignRemoteEndpoints( )->SecurityManager.cpp的

SecurityManager::discovered_participant()->SecurityManager::on_process_handshake ()中根据paticipant握手状态分别调用begin_handshake_request()函数、begin_handshake_reply()函数与process_handshake()函数,这三个函数实现也都在PKIDH.cpp中。

on_process_handshake ()中,判断认证状态,若为未发送请求状态,调用begin_handshake_request()函数;若为未发送请求状态,调用begin_handshake_reply()函数;若为等待应答与等待结束状态,调用process_handshake()函数。

begin_handshake_request()函数对应“证书身份验证与密钥交换”节中握手的步骤1),本机发起握手请求,主要功能包括将dh1与p1随机数用公钥加密后发给远端(p1随机数本地保留),具体过程参见2.2.4节。

begin_handshake_reply()函数对应“证书身份验证与密钥交换”节中握手的步骤2),本机收到握手请求后回复握手请求,计算 dh2 发给 remote并使用本地随机数以及 dh1 生成共享对称密钥。

process_handshake()函数对应“证书身份验证与密钥交换”节中握手的步骤3),处理握手回复,使用本地随机数,以及 dh2 生成共享对称密钥。

握手及身份验证成功后,即可开始数据加密相关操作。在on_process_handshake ()中,身份认证成功后,调用get_shared_secret():获得协商后的对称加密密钥。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值