背景介绍:
最近收到一个网友问题,说他们设备不兼容客户的zrtp SHA 80的加密,他们搞了几天没有完成,问是否可以协助一下。
最初定位是因为不支持SHA80的,那做一下兼容就可以了吧,所以借鉴freeswitch中的实现,告知了一下如何修改,可以参考github库:
https://github.com/signalwire/freeswitch/tree/v1.6/libs/libzrtp/src
需要注意的是,最新的master分支已经移除的该部分代码。个人本地代码是https://github.com/signalwire/freeswitch/releases/tag/v1.6.17。
但是过了几天反馈说不行。然后重新看了一下他们的代码。
原来之前使用的是libzrtp的库,但是这个库已经10年多没更新了,
而客户用的是linphone,而linphone依赖的是自研bzrtp的库,他们的app和客户的进行协商时,就会导致协商失败,无法支持对方的加密算法。通过linphone抓包,可以看出部分commit参数异常导致无法匹配:
客户linphone的log:
行 623: 2023-05-13 13:37:13:879 [linphone/bzrtp] MESSAGE zrtp channel [0x128696bc0] creates a commit message with algo: Cipher: AES-256 - KeyAgreement: K25519-Kyber512 - Hash: SHA-512 - AuthTag: HMAC-SHA1-80 - Sas Rendering: Base32
网友app和linphone的log:
行 545: 2023-05-13 12:33:44:215 [linphone/bzrtp] MESSAGE zrtp channel [0x12556c760] creates a commit message with algo: Cipher: AES-128 - KeyAgreement: DHM-3072 - Hash: SHA-256 - AuthTag: HMAC-SHA1-80 - Sas Rendering: Base32
可以看出linphone目前已经支持到AES-256, KeyAgreement: K25519-Kyber512, Hash: SHA-512的加密了,网友的还停留在AES-128, KeyAgreement: DHM-3072, Hash: SHA-256,而客户期望网友能够兼容,所以开始了此次踩坑之旅。
zrtp介绍
ZRTP 是一种密钥协商协议,可为 IP 语音 (VoIP) 呼叫提供端到端加密。它旨在比 SRTP(VoIP 的标准密钥协商协议)更安全。
ZRTP 使用 Diffie-Hellman 密钥交换在 VoIP 通话的双方之间建立共享秘密。然后使用此共享秘密来加密音频数据。ZRTP 还包括许多使其比 SRTP 更安全的功能,例如:
- 预共享密钥:ZRTP 可以使用预共享密钥对 VoIP 通话中的双方进行身份验证。这为防止窃听提供了额外的安全层。
- 密钥滚动:ZRTP 可以在 VoIP 通话期间自动轮换加密密钥。这有助于防止试图恢复加密密钥的攻击。
- 拒绝服务保护:ZRTP 包括许多有助于防止拒绝服务攻击的功能。
- 总的来说,ZRTP 是比 SRTP 更安全的密钥协商协议。它提供了许多功能,使其更能抵抗窃听和拒绝服务攻击。
ZRTP 相对于 SRTP 的一些优势包括:
- ZRTP 更安全。它使用 Diffie-Hellman 密钥交换在 VoIP 通话的双方之间建立共享秘密。然后使用此共享秘密来加密音频数据。ZRTP 还包括许多使其比 SRTP 更安全的功能,例如预共享密钥、密钥滚动和拒绝服务保护。
- ZRTP 更灵活。它可用于范围更广的 VoIP 设备和协议。
- ZRTP 更易于使用。它不需要任何特殊配置或设置。
ZRTP 相对于 SRTP 的一些缺点包括:
- ZRTP 没有得到广泛支持。并非所有 VoIP 设备和协议都支持 ZRTP。
- ZRTP 更复杂。它是比 SRTP 更复杂的协议,这会使其更难实施和排除故障。
- ZRTP 可能会更慢。ZRTP 会增加 VoIP 呼叫的一些开销,这会使它们比未使用 ZRTP 加密的呼叫慢。、
具体过程可以参考如下链接进行深入学习:
https://petsymposium.org/popets/2017/popets-2017-0025.pdf
踩坑
bzrtp又分别以来的以下几个库:
之后一个一个库分别下载进行编译,当然编译过程中碰到很多问题,在此归结汇总一下,大概以下几类:
(1)部分依赖库bzrtp不再支持了:
主要修改的地方,关闭PolarSSL选项:
(2)bcunit等以来的库缺失,以及cmake文件没有正确配置
主要修改的地方:增加Bcunit_DIR的路径
(3)输出目录没制定,采用了默认的目录。而默认目录又没有权限进行创建和写入,导致异常;
主要修改的地方:
(4)静态库和动态库指定了一样的名称,导致输出冲突;
主要修改的地方:
由于同时开启static和shared两个选项,所以编译输出冲突,因此选择一个选项开启,或者将其中一个输出成果物重命令即可。个人选择重名了,方便一次编译多个场景使用。
(5)bctoolbox中Tester目录报错,导致编译失败。
主要修改的地方:
(6)bzrtp所以来的几个库,版本不一致导致部分文件无法正确匹配,接口函数,头文件都存在冲突
主要修改的地方:
经过在官网上逐一排查不同分支的支持程度,分别更新了bctoolbox的master,release5.1, release5.2的分支之后,才发现与客户bzrtp匹配的是release5.2分支,所以重新编译了release5.2分支才能正常编译bzrtp的库。
经过九九八十一难之后,终于完成编译了。
最后编译成功之后
目前成果物已经编译完成,接下来就是做对应的兼容了,因为bzrtp的接口和libzrtp的接口完全不一样,所以兼容这个过程比较长了,就交给网友自主实现吧。
当然如果有人想要深入学习如何使用bzrtp,那可以推荐linphone的开源库mediastreamer2,里面有介绍如何使用,并且可以用linphone apk进行调试。
参考文献
https://gitlab.linphone.org/BC/public/mediastreamer2
https://datatracker.ietf.org/doc/html/rfc6189
https://github.com/traviscross/libzrtp
https://petsymposium.org/popets/2017/popets-2017-0025.pdf
https://blog.csdn.net/QTVLC/article/details/123275659
https://gitlab.linphone.org/BC/public
https://datatracker.ietf.org/doc/html/rfc6189
作者:Fenngtun | 来源:公众号——MediaStack
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。