秘密特工的-BeagleBone-指南-全-

秘密特工的 BeagleBone 指南(全)

原文:annas-archive.org/md5/35eb0aa239041e00017adee7caf26ebd

译者:飞龙

协议:CC BY-NC-SA 4.0

前言

BeagleBone Black 以不同的方式激发了嵌入式黑客的兴趣。有些人把它看作是一个小型机器人控制板,而另一些人则将其视为一个低功耗网络服务器。在本书中,我们将 BeagleBone Black 视为个人安全和隐私的捍卫者。每一章将讨论一种技术,并提供一个项目来加强对该概念的理解。

让我们开始吧!

本书内容

第一章,创建你的 BeagleBone Black 开发环境,通过展示如何设置 Emacs 来最大化你的嵌入式黑客之旅,开启了这段旅程。

第二章,使用 Tor 桥接绕过审查,讲解了如何将 BeagleBone Black 转变为一个带有前面板界面的 Tor 服务器。

第三章,使用 CryptoCape 添加硬件安全,研究了生物识别认证和专用安全芯片。

第四章,使用受信平台模块保护 GPG 密钥,向你展示了如何利用 BeagleBone Black 来保护电子邮件加密密钥。

第五章,离线聊天,详细介绍了如何在 BeagleBone Black 上运行 IRC 网关,以加密即时消息。

附录,参考书目,列出了本书中引用的所有参考文献。

本书所需的工具

本书包含多个独立的项目,涉及各种软件包和硬件组件。所有软件都是开源的,安装说明贯穿于每一章。所有必要的硬件清单都列在www.sparkfun.com/wish_lists/93119的 SparkFun Electronics 愿望清单上。每一章会列出该项目所需的组件,因此最好先阅读该章内容,再收集必要的硬件。

本书适合的人群

如果你对个人安全和互联网隐私感兴趣,那么你应该会喜欢这本书。如果你有安全背景,但对嵌入式计算不太熟悉,那么你会觉得这些项目具有挑战性,但也非常有收获。相反,如果你精通电子学,并且正在使用 GNU/Linux 发行版,但尚未学习本书中提到的安全技术,那么你应该会喜欢每一章中关于这些技术的讨论。

使用约定

在本书中,你会看到一些不同的文本样式,用于区分不同类型的信息。以下是一些样式的示例及其含义的解释。

文本中的代码词、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟网址、用户输入和 Twitter 用户名都如下所示:“由FrontPanelDisplay类控制的 LCD 通过 BBB 的 UART 4 以 9600 波特率写入串口/dev/ttyO4。”

一段代码如下所示:

self.clear_screen()
up_str = '{0:<16}'.format('Up:   ' + self.block_char * up)
dn_str = '{0:<16}'.format('Down: ' + self.block_char * down)

self.port.write(up_str)
self.port.write(dn_str)

当我们希望引起您对代码块中特定部分的注意时,相关行或项目会以粗体显示:

import Adafruit_BBIO.UART as UART
import serial
class FrontPanelDisplay(object):

  def __init__(self):
    self.uart = 'UART4'
    UART.setup(self.uart)
 self.port = serial.Serial(port="/dev/ttyO4", baudrate=9600)
    self.port.open()

任何命令行输入或输出都写成如下格式:

Mar 25 21:37:43.000 [notice] Tor has successfully opened a circuit. Looks like client functionality is working.
Mar 25 21:37:43.000 [notice] Bootstrapped 100%: Done.

新术语重要单词以粗体显示。您在屏幕上看到的文字,菜单或对话框中的文字例如,会这样出现在文本中:“要连接到您的桥接设备,请启动 Tor 浏览器并在启动时点击打开设置。”

注意

警告或重要说明会以类似这样的框框形式出现。

提示

提示和技巧如下所示。

读者反馈

我们始终欢迎读者的反馈。告诉我们您对本书的看法——喜欢什么或可能不喜欢什么。读者反馈对我们开发您真正能够充分利用的书籍非常重要。

若要向我们提供一般反馈,只需发送电子邮件至<feedback@packtpub.com>,并在邮件主题中提及书名。如果您在某个话题上有专业知识,并且有兴趣写书或为书籍做贡献,请参阅我们在www.packtpub.com/authors上的作者指南。

客户支持

现在,您已成为 Packt 书籍的骄傲拥有者,我们为帮助您最大化购买收益,提供了若干帮助资源。

下载示例代码

您可以从www.packtpub.com的账户下载您购买的所有 Packt 书籍的示例代码文件。如果您从其他地方购买了本书,可以访问www.packtpub.com/support并注册,以便将文件直接通过电子邮件发送给您。

勘误

尽管我们已经尽一切努力确保内容的准确性,但错误还是可能会发生。如果您在我们的书籍中发现错误——可能是文本或代码中的错误——我们将非常感激您向我们报告。通过这样做,您可以帮助其他读者避免困扰,并帮助我们改进后续版本的书籍。如果您发现任何勘误,请访问www.packtpub.com/submit-errata提交,选择您的书籍,点击勘误提交表格链接,并输入您的勘误详情。一旦您的勘误被验证,我们将接受您的提交,并将勘误上传至我们网站,或添加到该书籍现有勘误列表中的勘误部分。任何现有的勘误可以通过选择您的书籍,从www.packtpub.com/support查看。

盗版

网络上的版权侵权问题是所有媒体面临的持续性问题。在 Packt,我们非常重视对版权和许可证的保护。如果您在互联网上发现我们作品的任何非法复制,无论是什么形式,请立即提供相关地址或网站名称,以便我们采取必要的措施。

如发现涉嫌盗版的资料,请通过<copyright@packtpub.com>与我们联系,并提供相关链接。

我们感谢您在保护我们的作者以及帮助我们提供有价值内容方面的支持。

问题

如果您在书籍的任何方面遇到问题,请通过<questions@packtpub.com>与我们联系,我们将尽力解决。

第一章:创建你的 BeagleBone Black 开发环境

本书是为秘密特工编写的。詹姆斯·邦德是最容易想到的秘密特工,但在今天这个高度互联的世界中,真正的秘密特工应该是在 Q 部门。诸如伪装、窃听设备和掌纹武器等间谍技巧对现场特工有用,但在网络环境中我们需要其他工具。这些工具就像现场特工所使用的工具一样,使你能够在人群中隐藏、保护秘密通信,并验证其他特工的身份。本书中的软件和硬件项目使用了那些被举报人、保护消息来源的记者以及在高度审查的国家寻求访问未经过滤信息的普通公民所依赖的工具。

BeagleBone BlackBBB)是一个完整的计算机,体积可以放进一个 Altoid 的薄荷糖铁盒里。它的小巧外形、低功耗和强大的性能使得这个设备能够帮助你保护隐私并确保在线通信的安全。在我们构建这些工具之前,我们首先需要了解如何与 BBB 互动。本章将介绍 BBB,并建议一个开发环境,你可以在其中构建后续项目。

本章内容包括:

  • 了解 BBB 及其背后的开源原则

  • 安装并使用 Emacs 编辑器

  • 将 Emacs 配置为嵌入式开发环境

  • 为可用性定制你的 SSH 配置

  • 调查加密学、电子学和 Linux 的背景信息资源

介绍 BBB

从 BeagleBoard 网站(BeagleBoard.org)上获取,BeagleBoard 是 BeagleBoard-xM、BeagleBone 和 BBB 背后的非营利基金会,BBB 是一个低成本、社区支持的开发平台,适用于开发人员和爱好者。最新版本 Rev C 的规格令人印象深刻,包括 TI Sitara AM3358 1GHz ARM Cortex-A8 处理器、512MB DDR3 内存以及 4GB 嵌入式多媒体卡eMMC)作为板载闪存。当你查看这块板时,你会看到两个 46 引脚的扩展头。如果你将它与其他同价位的爱好者板进行比较,你会得出结论,其他板的扩展能力远不如 BBB。BBB 支持更多的 输入/输出IO)选项,包括三条 I2C 总线、多个串口、65 个 通用输入输出GPIO)、多个 脉冲宽度调制PWM)和七个带有内置 模拟到数字转换器ADC)的模拟输入。如果你不懂这些术语,没关系,我们将在项目中逐步解释所使用的系统。

来自BeagleBoard.org的文档质量非常出色。你应该阅读 BBB 的系统参考手册SRM),这是 BBB 的官方手册,位于github.com/CircuitCo/BeagleBone-Black/blob/master/BBB_SRM.pdf?raw=true。这是一本完整的手册,涵盖了连接 BBB、电源选项和启动顺序。许多在 BeagleBoard 邮件列表和 IRC 频道上提出的问题,可以在这本手册中快速找到答案。本书的作者假设你至少浏览过 SRM 的第 3、4 和 5 章,这意味着你已经了解了 BBB 的基本功能并熟悉其物理连接器。没有比这份文档更好的 BBB 参考资料了。

欣赏 BBB 对开源硬件的承诺

BBB 还有一个非常重要的特点:它是开源硬件OSHW)。OSHW 是一个相对较新的概念,其确切定义可能会让人感到困惑。然而,有一个组织——开源硬件协会OSHWA),其使命是教育和推广 OSHW。他们的定义可以在他们的网站上找到:www.oshwa.org/definition/。和大多数组织一样,达成统一的定义可能会非常困难。OSHW 的定义内容超过了一页。将 OSHW 从开源软件中区分出来的难点在于,硬件是一个物理存在。硬件的设计文件用于制造硬件,但同时也有物理组件。为了做一个类比,硬件的编译器就是制造商。因此,OSHW 的定义是精心构建的,通常适用于硬件的设计文件。

注意

OSHWA 的执行董事 Alicia Gibb 在 TEDx 上做了一个名为专利的死亡及其后果的演讲(www.youtube.com/watch?v=z__Sbw1Ax4o)。演讲阐述了硬件设计如何跨越版权和专利法的界限。Alicia 还提供了一些关于专利和 OSHW 背后动机的有趣见解。

BBB 是 OSHW,因为它发布了文档、原理图、计算机辅助设计CAD)文件、物料清单BOM)和生产文件(Gerber 文件),所有这些都在 Creative Commons 许可下发布。这意味着你不仅可以研究完整的设计,还可以自由制作你自己的衍生版 BBB。

开箱 BBB 并提供电源

与树莓派不同,BBB 开箱即用。最近的 BBB 会预装 Debian 发行版的 GNU/Linux(以下简称 Debian)在 eMMC 中。eMMC 是 BBB 上的闪存内存。当电源接入主板时,BBB 将开始从 eMMC 启动。如 SRM 的第三节所示,你可以用随附的 USB 线将 BBB 直接连接到你的 PC。BBB 还可以通过 5V 的圆形插孔供电,此时你需要一个能提供最大 1A 电流的墙面适配器。如果你计划将一个迷你液晶显示器LCD)连接到 BBB,你可能需要使用一个 2A 的适配器。你通常可以在适配器上找到输出电压和电流的规格。如果蓝色用户发光二极管LED)闪烁,你就可以判断主板是否已经通电并在运行。具体来说,LED USER0 会以心跳模式闪烁。

注意

每个用户 LED 都有一个默认含义,表示特定的 BBB 活动。为了进一步激励你阅读 SRM,含义在第 3.4.3 节第 6 步启动主板中定义。

提示

在选择电源时要非常小心。BBB 需要 5VDC ±0.25V。连接更高电压的电源会损坏主板。

BBB 可以支持多种外设,例如键盘、鼠标和显示器。然而,在本书中,我们将以无头配置使用 BBB,这意味着没有显示器。SRM 的第三部分详细介绍了各种连接场景。

使用 Emacs 创建嵌入式开发环境

在启用 BBB 电源后,我们需要找到一种与其互动的方式。我们需要一套可以连接到 BBB、发送 Shell 命令并传输文件的工具。这套工具就是你的开发环境。开发环境是个人的选择,选择很多。找到一个合适的环境非常值得花时间去做,因为它将是你与 BBB 交互的主要工具。你的环境需要具备执行你所需任务的技术能力,同时还需要具有可配置性和可扩展性。这里描述的环境完全包含在 Emacs 编辑器中。

注意

如果你更愿意使用一个特定的集成开发环境IDE),例如 Eclipse,你可以查看一些有用的教程:derekmolloy.ie/beaglebone/setting-up-eclipse-on-the-beaglebone-for-c-development/janaxelson.com/eclipse1.htm

理解嵌入式开发的复杂性

Emacs 的历史几乎与现代计算的历史一样长。作为一个编辑器,Emacs 常常被忽视,因为它有过时和难以学习的名声。由于其界面与大多数现代界面不同,Emacs 可能让人感觉不知所措。而且,快捷键是在现代图形用户界面GUI)发明之前就创建的,因此这些快捷键与通常使用的快捷键不太相同。然而,针对各种 Emacs 的启动包正在积极开发,它们能提供更顺畅的 Emacs 体验。如果你记住 Emacs 早于你的操作系统,你可能会更容易接受 Emacs 的工作方式。

注意

许多早期著名的程序员曾在 Emacs 上工作,包括盖·斯蒂尔(Guy Steele)、理查德·斯托尔曼(Richard Stallman)、詹姆斯·高斯林(James Gosling)和杰米·扎温斯基(Jamie Zawinski)。Emacs 的设计由理查德·斯托尔曼于 1981 年在 ACM 文本处理会议上提出;完整文本可在www.gnu.org/software/emacs/emacs-paper.html获取。

嵌入式开发比网页或桌面开发稍微复杂一些,因为通常涉及两台机器:主机(你的计算机)和目标机(你的嵌入式平台)。嵌入式系统的能力各不相同,有些系统甚至没有操作系统,这种情况下当然无法支持运行编译器。在这种情况下,用户需要在主机上为目标机交叉编译代码。虽然可以在 BBB 上进行交叉编译,但在 BBB 上本地编译小程序并不会花费太长时间。

对于在 BBB 上的开发,常见的建议是通过安全外壳SSH)连接到设备,并使用命令行工具。这是一种有效的技术,但它将你限制在命令行和终端仿真器中。这些工具非常强大,在这种情况下,限制并不意味着功能受限,而是界面受限。

Emacs 在嵌入式开发中的一个有用特性是透明远程访问多协议TRAMP)模式。简而言之,TRAMP 模式允许你在主机计算机上运行 Emacs,而主机计算机通常比 BBB 更强大,但你可以像访问本地文件一样访问 BBB 上的文件并运行命令。在 TRAMP 模式中,这是透明的;在这种环境下工作,就像是在主机上工作,而不是在嵌入式平台上。以下截图展示了 Emacs 的 TRAMP 功能:

了解嵌入式开发的复杂性

这张截图是在 Mac OS X 上运行 Emacs 时拍摄的,但连接到了主机名为 slartibartfast 的 BBB 上。屏幕上的一切都在 BBB 上运行。左上角的框显示了与 GNU 调试器GDB)进行的一个简单 C 程序的实时调试会话。左下角的框显示了从 BBB 上运行 gcc 得到的编译结果。右上角的框显示了交互式的 gdb 会话。最后,右下角的框显示了当前目录和一个 shell。接下来的章节将提供如何安装 Emacs 并设置此开发环境的详细信息。

提示

要为你的 BBB 命名,你需要修改两个文件。第一个文件是 /etc/hostname,然后你需要在 /etc/hosts 中进行相同的更改。如果你在选择合适的名称时遇到困难,可以参考以下 XKCD 漫画来得到些许安慰:

xkcd.com/910/

安装 Emacs 24

我们需要 Emacs 24.x 版本来使用 Bozhidar Batsov 的 prelude 启动包。Prelude 由 Batsov 和专注的 prelude 用户持续维护。代码托管在 GitHub 上(github.com/bbatsov/prelude),那里有详细的 README 文档。该软件是可选的,但它提供了许多便捷的功能和合理的默认配置设置。Emacs 的安装程序因操作系统不同而大不相同,但你可以参考以下表格来查找软件的位置:

操作系统 链接
Windows ftp.gnu.org/gnu/emacs/windows/
Mac OS X emacsformacosx.com/builds
来源 ftp.gnu.org/gnu/emacs/emacs-24.3.tar.gz

如果你是 Windows 用户并且在安装 Emacs 时遇到问题,请参考 www.gnu.org/software/emacs/manual/html_mono/efaq-w32.html 中的指南。Mac 用户应该会发现前一节列出的二进制文件足够使用。如果你使用 *nix 系统,可以通过包管理器安装 Emacs,或者从源代码编译。如果你使用包管理器,确保安装 Emacs 的主版本 24。在基于 Debian 的系统中,命令是 apt-get install emacs24

安装 prelude

可以通过输入以下命令来安装 Emacs prelude 软件:

curl -L http://git.io/epre | sh

提示

下载示例代码

你可以从你的账户中下载所有购买的 Packt 图书的示例代码文件,访问 www.packtpub.com。如果你是从其他地方购买的这本书,你可以访问 www.packtpub.com/support 注册并将文件直接通过电子邮件发送给你。

如果你对缩短的 URL 感到不放心,请查看引言 README,其中包含备用安装说明,可在 github.com/bbatsov/prelude 获取。安装程序会报告任何缺少的需要安装的软件包。完成后,应运行 Emacs。如果已为您的操作系统安装了二进制版本,则双击图标即可。在命令行上,只需输入 emacs 即可启动程序。在初始启动时,Emacs 将尝试访问 Emacs 包管理器并下载额外的软件。然后将源文件进行字节编译,因此需要一两分钟的时间。完成后,请关闭 Emacs 并重新打开;您应该看到类似以下屏幕的内容:

安装 prelude

注意

是的,Emacs 拥有自己的包管理器和专用于 Emacs 的仓库,提供 Emacs Lisp Package。查看 Batsov 的以下博文,深入了解 Emacs 包管理:

batsov.com/articles/2012/02/19/package-management-in-emacs-the-good-the-bad-and-the-ugly/

学习如何学习 Emacs

Emacs 有太多功能了。这里有一个开玩笑的笑话:Emacs 是一个需要好编辑器的操作系统。本节将展示使用 Emacs 所需的基本技能,更重要的是,学习如何使用 Emacs。Emacs 最好的功能之一是其庞大的内置帮助系统。如果您以前从未运行过 Emacs,请按 Ctrl-h t,缩写为 C-h t。这意味着在按住 Ctrl 键的同时,按 h,然后释放它,然后按 t。还请注意,Emacs 命令区分大小写。C-H T 意味着按下 Ctrl + Shift + H,然后按 Shift + T,而 C-h t 则不需要按下 Shift 键。您将看到交互式的 Emacs 教程。在教程中,您将看到关于元键的引用,这在您的键盘上可能很难找到。命令序列,如 M-x,意味着按住元键并同时按下 x。根据您的系统,元键可能是 AltOption。如果这两者都不起作用,您可以按下 Esc 键并释放它以提供元键功能。

教程非常好,本章的其余部分假设您已经完成了此教程或具备了相当水平的知识,以理解更高级的功能。

注意

学习 Emacs 的其他一些有用资源包括 Sacha Chua 的如何学习 Emacs图示(sachachua.com/blog/wp-content/uploads/2013/05/How-to-Learn-Emacs-v2-Large.png)和官方的Emacs 24 参考卡www.gnu.org/software/emacs/refcards/pdf/refcard.pdf)。

提示

如果您是 vi 用户,Emacs 中有一种模式可以模拟大多数 vi 键绑定,称为 viper 模式(www.emacswiki.org/emacs/ViperMode)。

精简 SSH 连接

即使您不使用 Emacs,您也会经常通过 SSH 连接到 BBB。如果您通过连接到 PC 的 USB 电缆运行 BBB,那么 BBB 的默认 IP 地址将是192.168.7.2。然而,如果您想直接将软件下载到 BBB,就像您完成这些项目所需的那样,您必须将 PC 的互联网连接转发到 BBB。另外,当通过 USB 直接供电时,通常会有限制 500mA 的电流。当 BBB 为扩展板或其他外设供电时,需要通过能够提供最多 1A 电流的 5V 直流插头来供电。由于这两个问题,您可能会发现通过 5V 电源运行 BBB,并将以太网电缆直接连接到您的家庭网络中会更方便。

当您这样做时,IP 地址通常会由您的路由器分配,并且只有路由器知道该地址。这将使您一直盯着 BBB,琢磨着它的 IP 地址。

发现您的网络中 BBB 的 IP 地址

有几种方法可以发现设备的 IP 地址。第一种方法是登录到路由器并查找 IP 地址。这是一个快速方法,但由于路由器种类繁多,您需要查阅路由器的文档,了解如何实现这一操作。

您还可以使用nmap工具在网络上执行快速ping 扫描。假设您已经熟悉自己网络的 IP 地址,您应该能看到一个新的设备。如果您使用的是基于 apt 的发行版,您可以通过sudo apt-get install nmap来安装nmap。如果您使用 Mac,您可以使用 homebrew 包管理器(brew.sh/),并通过brew install nmap来安装它。Windows 用户应该从nmap.org/download.html#windows下载二进制文件。安装后,您可以运行类似以下的命令:

nmap -sn 192.168.1.0/24

192.168.1.0替换为您网络的相应地址。/24无类域间路由CIDR)表示法,用于子网掩码。在这种情况下,/24表示使用 24 位 1 的子网掩码,即255.255.255.0-sn选项指示nmap执行 ping 扫描。

如果你仍然无法确定 IP 地址,可以购买一根 USB 到串口的适配器电缆。BBB 有一个串口调试头,位于 P9 头针的内部。你可以将 USB 到串口适配器连接到 BBB 的串口调试头,如下图所示:

发现网络上 BBB 的 IP 地址

在此图中,针脚 1(黑色线)为接地,针脚 4 为接收,针脚 5 为发送。连接好后,你需要一个终端仿真器通过串口连接。GNU Screen 是一款广泛可用、免费的强大软件,可以通过以下命令进行连接;只需将 /dev/tty.XXXX 替换为你的连接文件:

screen /dev/tty.PL2303-004014FA 115200

最后,你可以为你的 BBB 设置静态 IP。你的路由器可能支持静态租约功能,这将在设备进行 动态主机配置协议DHCP)请求时将你选择的 IP 分配给设备。此请求的租约可以是无限期的,因此实际上提供了一个 静态 IP。你也可以在设备上静态设置 IP,但那样你就必须手动管理冲突。因此,推荐的方法是让路由器来处理这种情况。

提示

要查找串口调试电缆,请参阅 eLinux 页面:elinux.org/Beagleboard:BeagleBone_Black_Serial

为了充分利用下一节中的 SSH 配置选项,建议设置静态 IP。否则,每当路由器重启或 BBB 断开连接几天后,你都需要重复前面的步骤来确定设备的 IP 地址。

提示

如果你更喜欢使用 WiFi 连接而非以太网,请注意某些 USB 网卡可能存在问题。请参考这个 eLinux 页面以了解支持的适配器:elinux.org/Beagleboard:BeagleBoneBlack#WIFI_Adapters

编辑 SSH 配置文件

为了连接到 BBB,你需要输入类似以下的命令,但要使用前面章节中的 BBB 的 IP 地址:

ssh debian@192.168.1.10

提示

如果你是 Windows 用户,考虑在主机上使用更多类似 Unix 的工具,因为 BBB 运行的是 Debian 系统。你可以安装 Cygwin (www.cygwin.com/),它将为你提供一个不错的 shell 以及相关的命令行工具。或者,你也可以考虑下载 VirtualBox (www.virtualbox.org/) 并在虚拟机中安装一个 GNU/Linux 发行版。

默认的用户名是 debian,默认密码是 temppwd。如果你只有一个设备,输入此命令可能是可以管理的。一旦你开始收集多个 BBB、Raspberry Pi、pcDuino、Cubieboard、带 WiFly Shield 的 Arduino 等设备,你就需要记住每个设备的 IP 地址、用户名和密码。这样会很麻烦。幸运的是,有一些技巧可以帮助你改善这种情况。

首先,您需要一个 SSH 私钥。如果您还没有密钥,可以使用以下命令在您的主机上生成一个:

ssh-keygen -t rsa -b 4096

现在编辑~/.ssh/config文件。如果您在 Emacs 中进行此操作,可以按C-x C-f,然后键入~/.ssh/config。Emacs 键绑定都绑定到 Emacs Lisp 命令(技术上,有几个基本命令是用 C 实现的)。键绑定C-x C-f绑定到find-file函数。打开文件的另一种,尽管更长的方式是按M-x,输入find-file,然后打开您选择的文件。

在您的~/.ssh/config文件中添加以下部分,将 HostName 替换为 BBB 的 IP 地址:

Host bbb
 HostName 192.168.1.10
 User debian

http://www.cyberciti.biz/faq/howto-regenerate-openssh-host-keys/:
rm /etc/ssh/ssh_host_*
dpkg-reconfigure openssh-server

这将删除您现有的 SSH 主机密钥,并从头开始生成它。由于主机密钥已更改,我们需要更新您主计算机上的 SSH 客户端。如果您再次登录到 BBB,可能会收到警告,指纹不匹配,因为您已更改。您可以通过输入以下内容从您的客户端中删除旧条目(您可能需要使用 IP 地址而不是bbb):

ssh-keygen -R bbb

或者,您可以直接编辑~/.ssh/known_hosts并删除条目。

有了新的 SSH 密钥,并删除了known_hosts中的旧条目,请务必重新登录到 BBB,以确保一切正常。重新退出并返回到您主机上的终端。执行以下命令后,您将不再需要输入密码:

cat .ssh/id_rsa.pub | ssh bbb 'cat >> .ssh/authorized_keys'

这将复制您的公共 SSH 密钥到 BBB 上,在 SSH 握手中被识别为授权密钥,因此不需要您输入debian用户的密码。

很可能您需要再次执行此操作,而您可能不想参考本书来查找此命令。您可以将此功能添加到您的.bashrc文件或其他等效文件以进一步提高使用便捷性:

ssh_upload(){
  if [[ $# -ne 1 ]]; then
    echo "usage: host\nNOTE: host should be set in ~/.ssh/config"
    else
    cat ~/.ssh/id_rsa.pub | ssh $1 'cat >> ~/.ssh/authorized_keys'
    fi
}

然后,您可以将您的密钥添加到服务器中:

ssh_upload bbb

别忘了重新加载您的.bashrc文件以获得此功能:

source ~/.bashrc

退出并重新登录也将起作用。

运行 SSH 代理程序以控制对 SSH 密钥的访问。

现在,您不必每次登录到 BBB 时输入debian账户密码,但现在您需要输入 SSH 私钥密码。这同样令人讨厌。但是,我们可以通过运行ssh-agent来解决这个问题。安装和配置ssh-agent取决于操作系统,并且在线上很容易找到说明。一旦ssh-agent运行,通常情况下,当您登录时需要输入 SSH 私钥密码,如果在一定时间内进行 SSH 连接,您将立即连接到远程服务器,无需额外输入密码。

使用 TRAMP 连接到 BBB

现在我们已经配置了 SSH,连接到 BBB 将变得更容易。Emacs 内置了一个目录编辑器,叫做dired,可以通过按C-x d来调用。我们想要在 BBB 上打开dired以查看远程文件。按C-x d,然后输入目录/ssh:bbb:/home/debian。应该会立即打开一个类似下面的屏幕,显示你主目录的内容:

通过 TRAMP 连接到 BBB

所有基本的 Emacs 导航命令都适用于dired,因此你可以在目录中导航并按下回车键来打开文件或另一个目录。^键将带你到父目录。你也可以点击目录或文件来打开它们。

提示

如果tramp-default-method变量被设置为ssh,你可以将 URL 简化为/bbb:/home/debian。你可以通过评估该变量来查看其状态。要评估 Emacs Lisp,按M-:,然后输入tramp-default-method,迷你缓冲区应该会显示ssh

如果你想了解更多关于dired或任何 Emacs 相关的内容,可以按下C-h r来查看内置文档。如果你滚动或搜索(按下C-s),你会在页面上找到dired手册。该手册使用信息查看器,你可以按C-h i来获取主信息页面,然后按h来了解相关内容。

Emacs 的一个特点是其可扩展性。假设你将经常连接到 BBB,按C-x d并输入/ssh:bbb:/home/debian可能会觉得有些麻烦。我们可以定义一个新的键序列来简化这一过程。切换到 Emacs 中的 scratch 缓冲区。按C-x b,输入*scratch,然后按Tab + Enter。粘贴以下代码:

(global-set-key
 [(control x) (control y)]
 (lambda ()
   "Open a dired buffer on the BBB"
   (interactive)
   (dired "/ssh:bbb:/home/debian")))
 press *C-x C-y* and you should see the home directory of BBB. Congratulations! You've just customized Emacs! If you restart Emacs, however, you'll lose this convenient function, so you need to save it. If you are using the Emacs prelude, customizations should go in ~/.emacs.d/personal/foo.el. You can save this buffer with *C-x C-s* and specify the filename.

如果你喜欢使用 Emacs,你可能也会喜欢修改 Emacs,而这可以通过 Emacs Lisp 来实现。当然,Emacs 包含了一本非常好的手册来学习 Emacs Lisp,Emacs Lisp 编程入门。你可以通过按C-h i d来访问,然后你可以滚动到手册部分,或者按 m,输入Emacs Lisp,然后按Tab进行自动补全,找到Emacs Lisp Intro

从 Emacs 运行命令

如果你当前在 Emacs 中查看dired缓冲区,那么 Emacs 就知道你正在使用远程机器。某些命令是 TRAMP 感知的,会远程执行。例如,M-!将执行一个 shell 命令。当在 TRAMP 上使用时,它将远程执行 shell 命令。尝试使用M-!执行touch test.txt命令。现在按g刷新dired,你应该能看到test.txt。如果你通过在dired中导航到该文件并按Enter来编辑它,你实际上是在远程编辑该文件。从技术上讲,你是在编辑该缓冲区的本地副本,但当你按C-x C-s保存时,修改会被传输到 BBB。

这个系统有一个好处。如果 SSH 连接因某种原因断开,缓冲区仍然保存在你本地机器的内存中。一旦连接恢复,Emacs 会保存该缓冲区。Emacs 充当你远程连接的会话管理器,并在需要时自动重新连接。

如果你在 Emacs 中打开一个 C 文件,Emacs 会应用 C 语言语法高亮,但它也可以通过 TRAMP 进行编译和调试。要进行编译,按 M-x,输入 compile,并提供编译命令。如果有 makefile,make 就足够了;否则,提供完整的 gcc 编译命令。使用编译功能的好处是 Emacs 会识别编译错误,并且你可以通过 C-x跳转到每个错误。最后,如果你在 BBB 上安装了gdb,你可以从主机计算机上使用 gdb进行调试。假设你已经使用调试符号编译了程序,如果你在当前缓冲区查看源代码,你可以按 *M-x*,然后输入gdb`。

你需要提供gdb命令,类似于gdb nameofexec -i=mi。Emacs 会远程启动 gdb 并打开交互式会话。如果你设置了断点,Emacs 会切换到代码缓冲区,并显示指令指针在代码中停止的位置。

最后,你还可以在 Emacs 中运行远程系统上的 shell。如果你在一个支持 TRAMP 的缓冲区中,按下 M-x 然后输入 shell 将打开一个远程 shell。你可以在不离开 Emacs 的情况下进行所有开发操作。Emacs 还可以充当你的邮件阅读器、计算器、IRC 客户端,甚至可以玩俄罗斯方块(通过按 M-x 然后输入 Tetris)。Emacs 是一个跨平台的编辑器,因此一旦你学会了如何使用 Emacs,你就可以在任何机器上将其作为开发环境使用。

小贴士

XKCD 漫画 378 的粉丝,应按 M-x 然后输入 butterfly。务必回答 yes,以确认是否真的想释放蝴蝶的力量。关于 M-x 蝴蝶的背景,请参见 xkcd.com/378/

使用 Emacs dired 从 BBB 复制文件

另一个常规且繁琐的任务是从主机复制文件到目标机器或反之。你可能会使用命令行工具,如 scp,来来回回地传输文件。Emacs 的 dired 配合 TRAMP 会使这个任务变得更加简单。在 dired 缓冲区中,按 C 调用 dired-do-copy 功能。这会提示你输入目标地址。如果你指定了像 /ssh:bbb:/home/debian 这样的远程地址,那么 dired 会通过 SSH 复制文件。你可以通过按 m 标记多个文件,然后按 C 进行复制。反向操作,即从 BBB 复制文件到主机,也是同样的过程。这避免了你必须跳转到 shell 使用 scp

网上有很多资源可以用来学习 Emacs。如果你是 IRC 用户,那么在 Freenode 上的 #emacs 频道是许多经验丰富的 Emacs 用户聚集的地方。Emacs 维基也是学习 Emacs 的一个很好的起点,其中有一个 Emacs 新手条目(www.emacswiki.org/emacs/EmacsNewbie)。内建的帮助系统也非常全面。要获取帮助,可以按 C-h ?

查找更多背景信息

本书中的项目大多数都是自包含的。然而,它们假设你具备一定的 GNU/Linux 系统、电子学和加密学概念的背景知识。以下部分列出了一些每个领域的资源,供那些希望深入了解的读者参考。

查找更多加密学资源

本书中的项目都涉及某种形式的加密技术。如果你熟悉像非对称加密、数字签名和消息认证码等术语,那么你应该没问题。如果不熟悉,你仍然可以完成项目,但可能无法理解其中的理论背景。

由于这本书不是关于加密学的书籍,因此这里的入门内容不足以为初学者提供足够的细节,对于已经熟悉这些材料的人来说也远远不够。如果加密学对你来说是新领域,你仍然可以继续阅读本书。在每一章的开始部分,都会提供一些量身定制的背景知识,以帮助你理解本章的内容,这应该足够让你明白项目的目标。完成后,希望你能对加密学产生兴趣,并可以通过以下资源进一步学习。

对于该主题的温和入门,Fred Piper 和 Sean Murphy 合著的 Cryptography: A Very Short IntroductionOxford University Press, 2002)是一个不错的起点。然而,正如书名所示,它缺乏技术深度。Christof Paar 等人 编写的 Understanding Cryptography: A Textbook for Students and PractitionersSpringer, 2010)是一个更详细的介绍。对于那些更具探索精神的读者,Jonathan Katz 和 Yehuda Lindell 合著的 Introduction to Modern CryptographyChapman and Hall/CRC, 2007)是一本最新的参考书。

如果你更喜欢讲座,运气不错。Khan Academy 提供了一些有趣且免费的迷你讲座,内容涵盖从古代密码学到 RSA(www.khanacademy.org/computing/computer-science/cryptography)。另一个免费的资源是 Coursera,它提供了三门密码学课程,《密码学 I 和 II》 由斯坦福大学教授 Dan Boneh 授课,以及一门关于现代密码学的课程,由 Jonathan Katz 授课。这些课程的链接分别是 www.coursera.org/course/cryptowww.coursera.org/course/crypto2,和 www.coursera.org/course/cryptography

寻找额外的电子学资源

类似地,本书假设读者具备一些基本的电子学知识。如果你在寻找一本书,《发明者实用电子学》第三版,由Paul ScherzSimon Monk编著,Tab Books出版,2013 年,是一本扎实且易于理解的参考书。Khan Academy 提供了关于电学和磁学基本概念的系列课程(www.khanacademy.org/science/physics/electricity-and-magnetism)。Dave Jones 的 EEVBlog 是一个有趣且富有信息的视频博客,涵盖了电子学的多个领域,应该对电子爱好者很有吸引力(www.eevblog.com/)。

寻找额外的 Debian 资源

对于 Debian 新手,网上有一本全面且免费的手册,名为《Debian 管理员手册》,由Raphaël HertzogRoland Mas编写,Freexian SARL出版,2014 年,可在 debian-handbook.info/browse/stable/ 查阅。至少,你应该阅读本书的第六章,维护和更新:APT 工具,该章节详细介绍了如何使用 apt 工具集进行包管理。Linux Foundation 和 edX 还提供了一门免费的课程,叫做Linux 入门www.edx.org/course/linuxfoundationx/linuxfoundationx-lfs101x-introduction-1621)。这门课程比较新,似乎并没有使用 Debian 发行版,但看起来它是关于通用 Linux 信息的代表性课程。最后,Debian 社区在 OFTC IRC 网络上有几个 IRC 频道。大多数频道以 #debian 开头,你可以在那里提问。BeagleBoard 的频道是 #beagle,位于 Freenode,你也可以在那里找到帮助回答问题的人。

摘要

在本章中,你学习了如何连接到你的 BBB。BeagleBoard.org 已简化了开箱体验,因此设备本身的设置非常简便。你了解了 BBB 的权威参考手册是系统参考手册,它应当是你查找关于 BBB 硬件相关问题的第一站。你还了解了 Emacs,以及如何使用 Emacs 创建嵌入式开发环境。最后,我们列出了几种资源,帮助你获取关于密码学、电子学和 Linux 的额外信息。

在本书的其余部分,你将围绕最流行且信任的软件安全包构建项目:Tor、GNU 隐私指南和离线消息,这些软件都在积极使用并维护中。在下一章中,我们将使用 Tor 和 BBB 来帮助增强一个抗审查的网络。

第二章:通过 Tor 桥接绕过审查

在本章中,你将配置你的BeagleBone BlackBBB)以在 Tor 网络中运行一个桥接。这个桥接将允许你和其他人更加匿名地访问互联网,并提供一个反审查的网关。我们将为 BBB 添加一个简单的硬件控制界面,以便我们实时查看和调整桥接的带宽使用情况。我们将这个项目命名为 BeagleBridge。

本章将讨论以下内容:

  • Tor 简介

  • Tor 中继与桥接的区别

  • 混淆 Tor 代理

  • 如何在 BBB 上下载和安装 Tor

  • 如何配置 BBB 作为运行混淆代理的 Tor 桥接

  • 如何向前面板添加硬件控制来调整桥接

了解 Tor

在本项目中,你将学习如何使用 Tor,这是一个旨在保护你在线匿名性的工具和网络。Tor 最初源自美国海军研究实验室资助的关于洋葱路由的研究(Dingledine, Mathewson, 和 Syverson,2004)。在洋葱路由中,客户端在一个覆盖网络中建立一个节点电路,覆盖网络是建立在现有网络之上的网络。Tor 网络是一个运行在互联网中的覆盖网络,尽管它也可以运行在单独的网络上。客户端将消息发送给每个节点,该消息是专门为该节点加密的,请求该节点将消息转发给电路中的下一个节点。每个节点解开一层加密并将结果转发给电路中的下一个跳点,因此有了洋葱类比。最后一个节点包含客户端的实际消息,并将其转发给目标服务器。

洋葱路由提供匿名性,因为目标服务器无法知道客户端的 IP 地址。通常,当你使用浏览器访问互联网时,浏览器会创建一个传输控制协议TCP)连接,该连接从你的系统发起,并在你尝试访问的网站处终止。TCP 的地址由互联网协议IP)提供。每个 IP 数据报包含源 IP 地址和目标 IP 地址。当数据报到达服务器时,服务器可以读取源 IP 地址。这通常是有用的,因为服务器需要这个地址来返回你的数据。然而,这也意味着服务器知道你的 IP 地址,即你在互联网上的位置。仅仅是你的 IP 地址就能透露你的一些信息,比如你所在的国家和你的互联网服务提供商ISP)。通过 IP 地址进行地理定位可以准确到邮政编码级别,以美国为例。

注意

Tor,最初是洋葱路由器The Onion Router)的缩写,现在简单地称为Tor,而不是TOR。当你在 Tor 邮件列表或 IRC 频道上提问时,Tor 开发者会很感激你注意到这一细微差别。

下图展示了这一路由过程。在这个例子中,Alice 是一个客户端,她连接到她电路中的第一个节点,这个节点恰好运行在你的 BBB 上。这个 BBB 解开一层并将 Alice 的通信转发到中间节点。中间节点也执行相同的操作,将信息转发到最终(出口)节点。出口节点将 Alice 的原始消息发送到名为 Bob 的目标服务器。从图中绿色箭头所示,表明 Tor 内部的连接是加密的。出口节点到 Bob 的连接则显示为未加密连接,因为这部分流量不属于 Tor 网络的一部分。从 Bob 的角度来看,这个连接的 IP 发起者是出口节点。然而,真正的发起者是 Alice,她的 IP 地址被 Tor 网络隐藏了。

了解 Tor

许多个人对此信息的反应是:

"那又怎样?为什么我关心我访问的网站知道我的 IP 地址?"

该网站现在知道了你请求的数据,并且还知道了你的位置信息。这些信息可能与其他公共信息结合使用,例如,进行关联攻击。关联攻击是通过将来自多个来源的信息结合起来进行的去匿名化尝试。例如,假设你在寻找有关某种罕见疾病的信息。你在一个论坛上以化名发布问题,询问相关信息。然而,该网站以及任何被动监控你连接的人(如果连接没有加密)都知道你的大致位置以及你提出的问题。你的疾病在七十多岁的西班牙裔女性中最为常见。通过将你的 IP 地址与疾病信息结合起来,可以进行关联攻击,可能使用公共人口普查数据来揭示你的身份。

Tor 通过加密你的流量并通过 Tor 网络进行传输,同时隐藏你的 IP 地址,从而防范此类攻击。对于远程网站来说,你的 IP 地址将是 Tor 网络中最后一个节点的 IP 地址,这个节点被称为出口中继。

欣赏 Tor 的各种用户

各种各样的人使用 Tor 进行日常的互联网访问。那些不希望 ISP 收集他们访问网站信息的人,可能是因为他们正在寻求敏感话题的信息,使用 Tor。政府代理人和军方也使用 Tor。毕竟,如果你连接的 IP 地址是fbi.gov,那么在网上卧底就很困难。像爱德华·斯诺登这样的举报人也使用 Tor 向媒体披露信息。当政府封锁互联网访问时,普通公民也会使用 Tor。例如,在 2014 年 3 月底,当土耳其政府试图封锁 Twitter 时,土耳其的 Tor 用户数量从约 25,000 人激增至不到 70,000 人,仅用了大约两周时间。

注释

Tor 通过各种交互式图表发布了关于谁在使用 Tor 以及他们来自哪里的大量指标。在metrics.torproject.org/users.html?graph=userstats-relay-country&start=2014-01-04&end=2014-04-04&country=tr&events=off#userstats-relay-country 上的图表中可以看到土耳其的用户激增。

了解 Tor 中继

Tor 中继是 Tor 网络中的单独节点。一个节点是运行 Tor 软件的计算机。 这些中继将消息在整个网络中传递。出口节点是电路中的最后一个节点,将客户端的消息发送到目标服务。Tor 的一个有趣之处在于,大多数节点都是由志愿者运行的。这些中继操作员自愿提供带宽、时间和能源费用,以增加 Tor 网络的容量。Tor 项目鼓励个人运行中继,以增加网络的多样性。该建议背后的动机是,藏身在一个人群中更容易——在一个只有一个人的人群中藏身是很困难的。

了解 Tor 桥接

2006 年,随着互联网审查的加强,Tor 项目增加了一个反审查功能,叫做桥接中继,简称为桥接(Dingledine, 2006)。桥接是一种特殊形式的中继——它不会出现在公共中继目录中。强大的互联网审查者能够通过几种方法阻止访问 Tor。其中一个有效的方法是查找所有公共中继,那时大约只有一千个左右,并拒绝访问那些 IP 地址。因此,桥接中继是通过不太公开的方式创建和分发的,以便用户能够访问 Tor 网络。如果客户端能够访问桥接(它已经连接到 Tor),那么客户端就可以访问互联网。在这种情况下,不太公开意味着一种不通过公共中继列表的分发机制。

使用混淆代理和可插拔传输

审查者仍然能够阻止访问 Tor;一种技术是识别由 Tor 生成的流量模式并阻止连接。在 2010 年,Tor 项目的 Jacob Appelbaum 和 Nick Mathewson 提出了一个方法,通过混淆客户端和桥接之间的 Tor 流量,以应对深度包检测。由于混淆机制可能需要变化,实际上也发生了变化,Tor 项目希望有一个通用协议,以允许不同的混淆代理运行。这种抽象被称为 可插拔传输

在本章中,我们将设置您的 BBB 作为 Tor 桥接运行,运行一个混淆代理,使用 obfs3 可插拔传输。

意识到 Tor 的局限性

Tor 是目前保护匿名性最好的工具之一。然而,像本书中讨论的所有安全工具一样,它的保护也有局限性。首先,Tor 的威胁模型无法应对全球被动对手。这样的对手可以被动地监视整个互联网。如果对手能够监视整个互联网,那么他们就可以将进入 Tor 网络的流量与离开网络的流量进行关联,从而可能揭露 Tor 客户端的身份。这种设计的一个折衷是,Tor 是一个低延迟系统,这意味着你可以使用像 HTTP 这样的正常协议访问互联网,而不会遇到太多的延迟。这也是 Tor 网络中多样性重要的原因之一。如果所有的中继节点都在某个特定国家,那么这个国家可能会更容易监视流量。然而,尽管最近爱德华·斯诺登提供了泄露的信息,目前仍认为这样的对手很难监视整个互联网。

注意

Tor 项目的 Roger Dingledine 就 NSA 利用 Tor 漏洞做出如下评论:

"好消息是,他们[NSA]利用了浏览器漏洞,这意味着没有迹象表明他们能够破解 Tor 协议或对 Tor 网络进行流量分析。感染笔记本、手机或桌面仍然是了解键盘背后人的最简单方法。"

完整文本和更多评论可见于 Tor 网站(blog.torproject.org/blog/yes-we-know-about-guardian-article)。

此外,Tor 并不会自动加密你所有的流量。如果你请求的是未加密的 HTTP 信息,那么你使用的 Tor 退出节点会将这些未加密的信息转发到目标地址。恶意的退出节点可能会监视或操控你的流量;因此,最好在 Tor 上使用加密的会话,如 HTTPS。Tor 并不会仅仅因为你运行了 Tor 就保护你所有的流量。应用程序通常需要配置以使用 Tor。即使你在家庭网络上设置了一个透明代理,并将所有流量通过该代理路由,浏览器中的恶意软件或漏洞也可能泄露你的身份。这就是为什么 Tor 项目建议你使用 Tor 浏览器的原因,Tor 浏览器本质上是 Mozilla Firefox 的一个分支版本,经过特别修补以避免泄露你的身份。最后,如果你选择揭示你的身份,Tor 就无法保护你的身份。如果你决定通过 Tor 登录 Facebook,你就等于告诉了 Facebook 你是谁,而且你正在使用 Tor,因为所有 Tor 退出节点都是公开的。

提示

使用 Tor 更安全的一个简单方法是仅从 Tails(tails.boum.org/)使用它,Tails 是一个定制的 Linux 发行版,可以从各种媒体启动。Tails 是一套免费的软件,并包含多个已正确配置的工具,帮助保护你的隐私和匿名性。

运行 Tor 桥接的影响和好处

那么,为什么要在 BBB 上运行 Tor 桥接呢?Tor 的影响力和好处体现在网络中。Tor 服务器越多,网络中的资源就越丰富。许多发达国家的用户拥有比在互联网受限的国家更快的互联网连接速度,这种差距是数量级别的。桥接节点的流量通常会比中继节点少,因为桥接用户比正常的 Tor 用户少。桥接的性能瓶颈很可能是家庭网络的上传速度。如果你运行的是中继节点,这可能会成为限制因素,但作为桥接节点,你很可能是在帮助那些面临不稳定互联网环境的人,任何捐赠的带宽都是值得感激的。最后,在 BBB 上运行桥接的额外优势是对电费的影响较小,因为根据 BeagleBone Black 系统参考手册,BBB 加载网页时的功耗大约为 460mA。

在 BBB 上安装 Tor

以下章节提供的指令是针对在家庭网络上运行 BeagleBridge 的用户。桥接节点会消耗一些本来未使用的带宽,并将其捐赠给 Tor 网络。在运行服务器之前,你应该检查你的 ISP 的服务条款,确认是否允许运行此类服务。此外,你还需要配置家用路由器的端口转发。由于有各种各样的设备,每个设备都有不同的配置方式,你应该查阅路由器手册,了解如何启用端口转发。

从开发库安装 Tor

官方 Debian 仓库中的 Tor 镜像版本并不如 Tor 项目提供的版本更新。我们将使用 Tor 项目的开发仓库来获取最新的软件。这对于运行桥接节点特别重要,因为桥接节点和可插拔传输软件的更新频率较高。

注意

最新的指令以及最新的 GPG 指纹可以在 Tor 项目官网找到(www.torproject.org/docs/debian)。以下步骤解释了安装过程,但你应该与发布的官方指令进行对比。

编辑 /etc/apt/sources.list,添加以下内容:

deb http://deb.torproject.org/torproject.org wheezy main
deb http://deb.torproject.org/torproject.org tor-experimental-0.2.5.x-wheezy main

接下来,添加用于签名这些 Tor 软件包的 GPG 密钥:

gpg --keyserver keys.gnupg.net --recv 886DDD89
gpg --export A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89 | sudo apt-key add -

然后,输入以下命令:

sudo apt-get update

Tor 项目建议你通过以下命令添加 GPG 密钥环:

sudo apt-get install deb.torproject.org-keyring

Tor 需要更新的时间,因为它会对证书进行时间有效性检查。在后续章节中,我们将向您展示如何使用专用的 实时时钟RTC)保持时间。现在,您可以通过 网络时间协议NTP)来更新您的时钟,方法如下:

sudo ntpdate -b -u pool.ntp.org

安装 Tor:

sudo apt-get install tor

然后,安装 obfsproxy。Obfsproxy 是实现混淆代理的软件,支持各种可插拔传输。Obfsproxy 使用 Python Twisted 库,这是一个事件驱动的网络引擎,总共会安装大约 17 MB 的软件包:

sudo apt-get install obfsproxy

在安装软件时,让我们安装 Stem Python 包。Stem 是一个用于 Tor 的 Python 控制库,我们稍后将使用它与我们的桥接进行交互。最简单的方法是通过 pip 安装:

sudo pip install stem

配置 Tor 以支持 BBB

在 Debian 系统中,Tor 的配置文件是 /etc/tor/torrc。在编辑 /etc/tor/torrc 之前,您应该先进行备份。此 torrc 文件可以在 github.com/jbdatko/beagle-bone-for-secret-agents/blob/master/ch2/torrc 下载。我们将在后续章节中讨论此配置文件的更多有趣方面。当你准备好时,将 /etc/tor/torrc 替换为以下内容:

# We are running a relay, no need for the SocksPort
SocksPort 0
# Extra logging is nice
Log notice file /var/log/tor/notices.log
# Run in the background
RunAsDaemon 1
# The following two lines are so we can connect with the
## Tor Stem library over the control port
ControlPort 9051
CookieAuthentication 1
# The is the Onion Router (OR) Port for normal relay operation
ORPort 9001
# Your bridge's nickname, change!
Nickname changeme
# Bandwidth settings
RelayBandwidthRate 520 KB # Throttle traffic to 520 KB/s
RelayBandwidthBurst 640 KB # But allow burts up to 640 KB/s
# You put a real email here, but consider making a new account
## or alias address
ContactInfo Random Person <nobody AT example dot com>
# Do not exit traffic
ExitPolicy reject *:* # no exits allowed
# Yes, we want to be a bridge
BridgeRelay 1
# Use the obfs3 pluggable transport
ServerTransportPlugin obfs3 exec /usr/bin/obfsproxy managed
# Enable extra bridge statistics collection
ExtORPort auto
# A nice option for embedded platforms to minimize writes
# to eMMC or SD card
AvoidDiskWrites 1

将联系信息添加到 torrc 文件

至少,您应该更改 Nickname 字段和 ContactInfoNickname 字段是对您的桥接节点的简短引用;不过,您的桥接指纹始终是最好的方法,因为它是唯一的。ContactInfo 字段允许 Tor 项目在您的桥接出现问题时向您发送电子邮件。如果您担心收到垃圾邮件,可以创建一个电子邮件别名。只需确保定期查看该账户,以便接收 Tor 项目偶尔发送的邮件。

调整桥接的带宽使用

Tor 的手册页将详细描述大多数这些设置,但其中一些设置需要额外的解释。带宽设置 RelayBandwidthRateRelayBandwidthBurst 是可调的带宽设置,稍后我们将连接硬件控制来操作这些设置。速率和突发带宽单位是千字节每秒,而不是更常见的千位或 兆位 每秒,因此请注意单位。

理解 Tor 出口策略

桥接节点,按照定义,是 Tor 网络的入口点。因此,出口策略应允许流量从服务器退出 Tor 网络,应该如下设置:

ExitPolicy reject *:*

这可以防止您的服务器作为出口节点运行。如果您决定运行出口节点,请准备好收到来自您的 ISP 的一些投诉,尤其是当您在家庭网络上运行时。因此,Tor 项目和电子前沿基金会(EFF)建议您 不要 在家庭网络上运行出口中继。电子前沿基金会准备的详细法律常见问题解答可以在 www.torproject.org/eff/tor-legal-faq.html.en 找到。

设置桥接特定的配置

有三个与桥接相关的设置:BridgeRelayServerTransportPluginExtORPortBridgeRelay设置是关键设置,用来定义你的中继节点为桥接节点。你的桥接节点的元数据信息将发布到桥接数据库,而不是公共目录服务器,从而使桥接节点的 IP 地址比 Tor 中继节点的 IP 更不容易暴露。ServerTransportPlugin定义了你的桥接节点支持的可插拔传输代理。目前,ScrambleSuit 是最新的有前景的可插拔传输技术。然而,obfs3(在我们的桥接配置示例中启用的传输方式)略微成熟一些,是更保守的推荐方式。最后,ExtORPort允许 Tor 项目收集并报告桥接节点的统计数据。

注意

对于那些有兴趣运行 ScrambleSuit obfsproxy 的人,可以查看以下链接,了解如何配置桥接:lists.torproject.org/pipermail/torrelays/ 2014-February/003886.html

启动你的新 Tor 桥接

随着时间的更新和配置的设置,现在是启动桥接的时候了。此时,桥接应该能够连接到 Tor 网络,但由于尚未从你的路由器配置端口转发,它无法接受传入连接。不过,obfsproxy端口是随机分配的,因此我们需要先启动桥接,才能找到该端口。使用以下命令重新启动 Tor 服务:

sudo service tor restart

接下来,让我们检查日志,看看 Tor 是否已正确启动:

tail -n 20 /var/log/tor/notices.log

如果你看到类似以下的内容,那么你的 Tor 客户端行为正常:

Mar 25 21:37:43.000 [notice] Tor has successfully opened a circuit. Looks like client functionality is working.
Mar 25 21:37:43.000 [notice] Bootstrapped 100%: Done.

启用端口转发

我们知道需要转发9001端口,因为它是 ORPort,但我们需要知道 obfsproxy 软件运行在哪个端口上。这将在同一个日志文件中记录,并可以通过以下命令搜索 Tor 日志来发现:

grep obfs3 /var/log/tor/notices.log

上述命令应该会返回以下搜索结果:

Mar 05 01:56:04.000 [notice] Registered server transport 'obfs3' at '0.0.0.0:59519'

我们的 obfs3 服务的obfsproxy端口是59519。从你的家庭路由器配置端口转发,从9001端口进行转发,同时从外部 IP 向 BBB 转发59519端口。如果给你的 BBB 分配一个静态内部 IP,也会有所帮助。请查阅路由器手册以获取详细指导。或者,你也可以在/etc/tor/torrc文件中使用以下行来指定端口:

ServerTransportListenAddr obfs3 0.0.0.0:xxxx

用所需的端口地址替换 x。不过,最好让 obfsproxy 随机选择一个地址;否则,Tor 项目可能会在某些端口上运行桥接节点过多,这样更容易阻止对桥接节点的访问。

一旦你转发了所需的端口,重新启动路由器。你应该能看到以下信息,表示成功:

Mar 25 21:37:43.000 [notice] Now checking whether ORPort xxx.xxx.xxx.xxx:9001 is reachable... (this may take up to 20 minutes -- look for log messages indicating success)
Mar 25 21:37:44.000 [notice] Self-testing indicates your ORPort is reachable from the outside. Excellent. Publishing server descriptor.

恭喜!你现在正在 BBB 上运行 Tor 桥接器,并且正在帮助改善互联网自由。你还在为代理,无论是秘密代理还是其他代理,提供访问未过滤互联网的能力。

向桥接器添加物理接口

现在你已经成功运行了一个 Tor 桥接器,你可以在这里停下来。如果你停下来了,你就错过了将软件与定制硬件结合使用的机会。我们的 BBB Tor 桥接器目前没有视觉反馈,所以并不明显它是否在工作。此外,控制桥接器的唯一方式是通过 SSH 登录到 BBB 并操作配置选项。Tor 桥接器是一个设备,它需要设备控制。在这一部分,我们将添加一个前面板,它将为我们提供一个简单的方法来控制桥接器的带宽,并快速指示软件是否崩溃。在接下来的部分,我们将添加软件来与桥接器进行交互并控制硬件。

注意

如果你决定运行 Tor 中继器,有一些网站可以生成带宽图并显示有关你中继器的其他信息,比如 Tor atlas (atlas.torproject.org/)。另一个也能显示桥接器信息的工具是 Globe (globe.torproject.org/)。

收集前面板组件

由于这是我们的第一个项目,我们将使用一些基本组件:发光二极管LED)、旋转电位器和液晶显示器LCD),它们都显示在下面的电路图中:

收集前面板组件

LCD 显示器可能有点棘手,但 SparkFun Electronics 将一个 16x2 的 LCD 与微控制器结合起来,使其可以使用串行接口,而不是更复杂的并行接口。串行接口更简单,因为它只需要一条数据线连接到设备,而并行接口则需要更多的连接线。

使用 LCD 显示状态信息

我们的 Tor 桥接器会生成大量元数据,例如带宽使用情况、连接数量以及一些 Tor 特有的统计信息。对于家庭网络来说,了解桥接器使用的带宽量非常有用,而且最好能够在不每次都登录 BBB 的情况下获取这些信息。在串行 LCD 显示器中,我们将绘制带宽使用的图形表示。我们将使用十个条形图,每个条形图代表可用带宽的十分之一。如果你看到五个条形图,那么桥接器正在使用一半的可用带宽。此项目选用的 LCD 是 LCD-09067(SparkFun Electronics)。

注意

SparkFun 电子公司是一个国际分销商,位于美国科罗拉多州博尔德,负责发货。本书推荐的一些常见组件,如果你想节省运费,可以用当地电子商店的等效组件替代。你无需逐个输入每个组件,它们都已列在一个汇总的愿望清单中,地址是 www.sparkfun.com/wish_lists/93119

使用电位器控制带宽

电位器就像是一个可变电阻。如果你曾调整过收音机或扬声器的音量旋钮,你大概使用过电位器。通过调整旋钮,你可以调整电位器中的电阻,从而改变输出端感应到的电压。电位器有三个引脚:一个用于电压输入,一个用于接地,最后一个是输出。

这个旋钮连接到 BeagleBridge,将控制分配给 Tor 的带宽。当旋钮调到最大时,桥接器将报告所有带宽都可用来路由流量到 Tor 网络。当旋钮调到中间位置时,桥接器将报告一半的带宽可用。如果你注意到桥接器消耗的带宽超过你想要的量(LCD 显示出来的),你可以调低桥接器的音量。这个项目的电位器和旋钮分别是 COM-09939 和 COM-10001(SparkFun 电子公司)。

你的桥接器不会立刻吸引到用户;这需要一些时间。开始时将桥接器设置为最大带宽;如果你发现它消耗的带宽超过了你的需求,可以将其调低。为了得到 Tor 桥接器是否正常工作的指示,我们将使用一个由 BBB 的 GPIO 控制的 LED,它会定期闪烁。这样你就可以查看面板,判断软件是否仍在运行。SparkFun 的 LED 是 COM-10633,LED 支架是 COM-11148。

设计 BeagleBridge 电路

以下是本项目的 Fritzing 电路图。

设计 BeagleBridge 电路

电位器通过 BBB 的模拟到数字转换器ADC)引脚连接。BBB 的模拟输入只能承受最高 1.8V,因此非常重要的是使用专用的模拟电压引脚,即 P9_32 引脚(P9 接口的第 32 引脚),它提供这个电压。不要将电位器连接到普通的 3.3V 或 5V 电源轨,因为这样会损坏处理器。我们将随意选择 P9_36 上的模拟输入 AIN5 作为输入引脚,并将其连接到电位器的中间引脚或输出端。最后,将电位器的最后一个引脚连接到专用的模拟地引脚 P9_34。

LED 和 LCD 都使用 3.3V 电压和共地。LCD 需要一个串行传输引脚,所以我们将随意选择 P9_13,它是 UART4 的传输引脚。P9_24 上的 UART1 传输或者 P9_21 上的 UART2 传输也都能正常工作。

最后,我们需要一个 GPIO 来控制 LED。同样,任何 GPIO 都可以,但我选择了 P9_15 插针。你需要一个电阻来限制 LED 的电流。根据欧姆定律计算电阻的大小非常简单;我们只需要知道 LED 的正向电压降和最大电流。这个信息可以在数据手册中找到。如果你使用的是 SparkFun 的 5mm 绿色 LED,它的最大电流为 20mA,正向电压降为 2.2V。

欧姆定律指出,电压等于电流与电阻的乘积,或者V = IR。从我们的电源电压 3.3V 中减去 2.2V,再将结果除以 0.020 安培,得到 55 欧姆。55 欧姆不是标准值,但 56 欧姆是,所以你可以使用这个值。但是,你始终可以使用更高的电阻值,LED 的亮度将会降低。这个项目中使用的电阻值为 100 欧姆。

使用原型板连接硬件

在布线这个项目时有一些特殊的考虑,因为它是为了放入一个外壳中并提供前面板。与实心线相比,绞线具有更好的弯曲和柔韧性。外壳一旦安装好,我们不期望电线会承受拉力或移动,但当你尝试将面板安装到外壳时,它们肯定会移动!我们也有几种方法将我们的项目连接到 BBB。我们可以使用带公头插针的跳线插入母头扩展插针,但这些插针很容易脱落,尤其是在你把项目放入外壳时。

我们将使用 SparkFun 的 BeagleBone Black 原型板 DEV-12774,轻松地将电路与 BBB 结合。该板将电源、接地和其他插针信号引出,以便扩展。它包括一个 EEPROM,这不仅对想要在板上存储持久数据的人有用,而且如果你要构建一个 BeagleBone Cape,它也是必需的,后者将在下一章详细讨论。原型板的优势,特别是 Beagle 原型帽的优势在于,我们可以在板上焊接公头插针,然后使用母头接线,这种方式连接会更牢固。此外,通过使用公头插针,我们可以轻松地将原型板重复用于后续项目。然而,这些原型板并不是必须的,如果你想省钱,通过一些创意布线,你也可以不使用它。

如果你使用的是原型板方法,你不必填充所有的插针。只有我们需要的公头插针被焊接到原型板 P9 插针上的相应焊盘。原型板的工作原理是每个插针旁边都会有一个相同的焊盘。将 100 欧姆电阻从 P9_15 焊接到板中间一个公头插针的底部。然后,将一根电线从公头插针连接到 LED 的正极。

完成后,您的项目应该看起来像下面的电路图。我们还没有运行控制软件,但您可以看到 LCD 显示了带宽使用情况。下图为了方便测试,未将电位器焊接连接,而是使用了 IC Hooks。在最终安装中,您将需要焊接线缆,以确保更好的机械和电气连接。

用原型帽连接硬件

使用 Python 库开发软件

该项目的软件可以免费下载,网址为 github.com/jbdatko/beagle-bone-for-secret-agents/。在本节中,我们将突出显示使用现有库的细节,并概述项目的架构。由于有多个并发活动:Tor 桥接、带宽旋钮、LCD 写入和 LED 闪烁,代码使用了这些库中的许多异步回调。为了与桥接进行交互,我们将使用 Tor 的 Stem 库 (stem.torproject.org/),而为了与硬件进行交互,我们将使用 Adafruit 的 BeagleBone Python 库 (github.com/adafruit/adafruit-beaglebone-io-python)。

使用 pyBBIO 控制硬件

我们在安装 Tor 时已经安装了 Stem 库;因此,现在我们需要通过执行以下命令来安装 Adafruit 的 BBIO 库:

sudo apt-get install build-essential python-dev python-setuptools python-pip python-smbus -y
sudo pip install Adafruit_BBIO
sudo pip install pyserial

Adafruit 库方便地启用了设备树覆盖文件,这些文件在运行时将 BBB 的硬件配置描述给内核。因此,您无需通过 sysfs 操作配置,因为一切都在 Python 库中处理。代码将每个硬件组件建模为其自己的 Python 类。由 TorFreedomLED 类建模的 LED 是最简单的。我们需要让 LED 闪烁;这是通过切换输出为高电平、让执行线程稍作休眠,然后再切换输出为低电平来关闭 LED 实现的。为了设置 GPIO,我们只需调用 GPIO.setup,并传入引脚和方向:

import Adafruit_BBIO.GPIO as GPIO
class TorFreedomLED(object):
  def __init__(self):
    self.pin = 'P9_15'
    GPIO.setup(self.pin, GPIO.OUT)

  def on(self):
    GPIO.output(self.pin, GPIO.HIGH)

  def off(self):
    GPIO.output(self.pin, GPIO.LOW)

  def blink(self):
    self.on()
    sleep(.5)
    self.off()

FrontPanelDisplay 类控制的 LCD 写入 BBB 的 UART 4 上的串口 /dev/ttyO4,波特率为 9600。LCD 仅接收信息;因此,我们只使用 BBB 的传输线。命令被写入附加的微控制器,后者驱动显示器。数据手册可在 SparkFun 网站上找到,描述了所有命令。一般而言,过程是先在显示器上移动虚拟光标,然后发送文本。

注意

SparkFun 在www.sparkfun.com/tutorials/246提供了一个更完整的串行 LCD 快速入门指南。示例代码是针对 Arduino 的,但如果你参考本章中的桥接 LCD 示例,将其移植到 Python 是非常直接的。

类似于 GPIO 示例,Adafruit 库中的串行端口可以按如下方式使用:

import Adafruit_BBIO.UART as UART
import serial
class FrontPanelDisplay(object):

  def __init__(self):
    self.uart = 'UART4'
    UART.setup(self.uart)
 self.port = serial.Serial(port="/dev/ttyO4", baudrate=9600)
    self.port.open()

如果你尝试显示的文本超过了 16 个字符,显示屏会自动换行。因此,你需要管理 LCD,以确保它正确显示。例如,让我们来看一下负责生成带宽图的 display_graph 方法:

self.clear_screen()
up_str = '{0:<16}'.format('Up:   ' + self.block_char * up)
dn_str = '{0:<16}'.format('Down: ' + self.block_char * down)

self.port.write(up_str)
self.port.write(dn_str)

第一行清除屏幕并将光标重置到 16x2 显示屏的左上角。接下来,我们格式化两行文本,使用 LCD 上的特殊块字符来显示图形。这一行是左对齐的,并且用空白填充,直到达到 16 个字符。最后,使用串行 write 方法将行写入 LCD。因为写入第一行后,光标会自动跳到第二行,所以不需要在每行之间重置光标。

最后,带宽调节旋钮在 BandwidthKnob 类中建模。此类使用 ADC 模块,并作为线程实现。模拟输入每次读取时都会产生一个值,我们将这个值与桥接器的可用带宽做比率。Adafruit 库将值归一化到 0.01.0 之间;因此,当旋钮处于中点时,调用 ADC.read(pin) 应返回 0.5。模拟信号中会有一些抖动,而我们不需要对带宽进行精确的分辨率调整。每秒采样一次应该就足够了,因为我们预计旋钮不会频繁变化。我们会四舍五入到下一个整数,这样旋钮就会有十个离散的设置。run 方法会通过消息队列向调用者报告 音量 设置是否发生了变化。然后,调用线程可以相应地更新 Tor 桥接带宽限制。

这段代码示例向你展示了如何在 BBB 上使用 Adafruit 库设置 ADC,以及如何通过消息队列将结果传递给一个等待的线程:

import Adafruit_BBIO.ADC as ADC
import threading
from time import sleep
from math import ceil, floor
import Queue
class BandwidthKnob(threading.Thread):

  def __init__(self, pin, *args, **kwargs):

    threading.Thread.__init__(self, *args, **kwargs)
    self.pin = pin
    self.setup_adc()
    self.kill = False
    self.prev_value = -1
    self.q = Queue.Queue()

  def setup_adc(self):
    'Load the Adafruit device tree fragment for ADC pins'
 ADC.setup()

  def read_value(self):
    return ceil(10 * ADC.read(self.pin))

  def stop(self):
    self.kill = True

  def run(self):
    knob = self.prev_value

    while knob != 0 and not self.kill:
      sleep(1)
      knob = self.read_value()
      if knob != self.prev_value:
 self.q.put(knob)
        self.prev_value = knob

使用 speedtest-cli 确定你的带宽

为了调整带宽速率,我们首先需要知道我们的桥接器拥有多少带宽。幸运的是,有一个很方便的脚本可以从命令行运行速度测试,它被称为 speedtest-cli。你可以使用以下命令安装它:

sudo pip install git+https://github.com/sivel/speedtest-cli.git

使用以下命令运行测试:

speedtest-cli --simple > speedtest.txt

如果你检查输出文件,你应该会看到如下内容:

Ping: 107.686 ms
Download: 28.23 Mbit/s
Upload: 5.37 Mbit/s

我们将使用该文件中的结果作为我们带宽调整的基础。目前,我们只需要记住它的位置以备后用。

使用 Stem 库控制桥接器

桥接使用 Stem 库进行控制,该库通过 Tor 控制协议与 Tor 进程进行通信。设置由 BeagleBridge 类管理。在与 Tor 进程建立连接后,此类注册两个事件监听器,用于监听 BandwidthConfiguration 变更事件。带宽事件每秒触发一次,并通过 print_bw 回调报告上秒使用的字节数。此信息用于绘制带宽图表。以下回调函数显示了回调与 LCD 的交互:

def make_bw_callback(test,lcd):
  '''Returns a callback function for the bandwidth event'''
  def print_bw(event):
    '''Obtains the bandwidth used from the last second from the
       bridge, normalizes it to the total bandwidth, and draw 
       that information to the display'''
    up = int(test.get_up_ratio(event.written))
    down = int(test.get_down_ratio(event.read))
    lcd.display_graph(up, down)

  return print_bw

注意

对于那些希望深入了解 Stem 库和 Tor 控制协议的用户,Stem 库提供了详细的在线文档和示例(stem.torproject.org/tutorials.html)。对于想要更深入了解控制协议的用户,可以参考gitweb.torproject.org/torspec.git?a=blob_plain;hb=HEAD;f=control-spec.txt

Configuration Changed 事件是一个回调,用于通知进程桥接的配置已被更改。这发生在带宽旋钮被调整时,从而触发 update_rate 方法,该方法向桥接发送更新配置的命令。最终结果是,通过调整旋钮,您直接影响桥接的带宽限制。当回调发生时,它将在 LCD 上显示新的带宽速率,以便您知道您的限制已发生变化。此回调如下所示:

def make_conf_callback(lcd):
  '''Returns a callback function for the configuration changed
     event'''
  def conf_changed(event):
    '''Reads the new bandwidth rates from the bridge and draws
       that information to the display'''
    rate = str(int(event.config['RelayBandwidthRate']) / 1024)
    burst = str(int(event.config['RelayBandwidthBurst']) / 1024)
    lcd.display_rates(rate, burst)

  return conf_changed

Python 脚本的主要部分执行类的实例化,同时向 LCD 显示一次性启动画面。它会显示桥接传输的总字节数、已建立的电路数,以及桥接指纹的最后 24 个字节。只要带宽旋钮的值不为零,桥接控制器将永远运行。当您将旋钮调到零时,程序将退出,LCD 将显示块状图案。

最后,要运行桥接控制器,请执行以下命令,第一个参数是速度测试结果的所在位置:

sudo python beaglebridge.py ~/speedtest.txt &

为了避免以 root 身份运行,您需要操作用户组和权限。Tor 进程以 debian-tor 用户身份运行,而 Adafruit 库(为您启用设备树覆盖)需要在具有启用这些功能权限的用户级别运行。您可以创建一个自定义组,并将一个用户加入到 debian-tor 组中,然后赋予该组修改设备树文件的权限,以避免以 root 身份运行。

连接到您的混淆桥接

使用 BeagleBridge,你拥有自己的 Tor 网络入口点。你可以下载并安装 Tor 浏览器,并配置它使用你的桥接。这在你处于受限或不友好的网络中时非常有用,可以更匿名地访问互联网。然而,如果你使用 你的 BeagleBridge,旁路攻击者可能会通过你连接的 IP 地址发现你的家庭网络。虽然流量是经过混淆的,但随着时间推移可能会显得可疑。最好使用通过 Tor 获取的随机桥接地址。即使你没有直接连接到自己的桥接,你的桥接仍然在为 Tor 网络提供资源,帮助大家访问一个没有审查的互联网。要连接到你的桥接,启动 Tor 浏览器并在启动时点击 打开设置。然后,回答关于你的连接是否被审查的问题时选择 。选择 输入自定义桥接,然后按如下方式输入你的桥接地址,但请将 x 替换为你的 IP 地址和桥接的端口号:

bridge obfs3 XXX.XXX.XXX.XXX:59519

继续进行与 Tor 相关的项目

这个项目只是学习 Tor 的第一步。如果你想通过 BBB 路由更多的流量,你可以将桥接更换为公共中继。中继接收更多流量,但也更加公开。你的 IP 地址将被列为公共桥接,并且即使你正在运行非出口中继,一些网站也可能拒绝为你提供内容。

你也可以在 BeagleBone 上运行 Tor 隐藏服务。使用 Tor 客户端有助于将你的 IP 地址匿名化,从而保护客户端的隐私,但 Tor 隐藏服务可以隐藏服务器的 IP 地址,避免客户端获知。如果你有一个仅希望通过 Tor 访问的服务,这将是一个非常有趣的 BeagleBone 项目。

在硬件方面,考虑将 BeagleBone 和前面板放入一个专用的外壳中。看看你附近是否有黑客空间,他们可能能帮你制作一个漂亮的激光切割外壳!如果你没有激光切割机,也可以使用像下面截图中那样的 SparkFun Electronics 盒子:

继续进行与 Tor 相关的项目

注意

洋葱标志是 Tor 项目的注册商标,经许可使用。本章中描述的 BeagleBridge 项目与 Tor 项目无关。

摘要

本章中,你了解了 Tor 以及如何通过在 BBB 上运行 Tor 桥接来绕过互联网审查。我们还展示了如何为 BBB 添加一些基本的硬件控制,以便创建前面板接口。最后,通过一些 Python 代码,我们成功地将硬件控制和 Tor 桥接结合起来。

在下一章中,我们将更深入地了解 BBB 可用的专用加密硬件,并展示如何使用这些设备。

第三章. 使用 CryptoCape 添加硬件安全

本章继续我们的定制安全硬件之旅,使用BeagleBone Black(BBB)cape。在 BeagleBone 术语中,cape是一个附加到 BBB 的子板。我们将简要介绍硬件加密设备,然后探索 CryptoCape,这是一个包含众多安全特性的 BBB cape。我们将描述如何以 CryptoCape 为例创建自己的 cape。本章介绍了 cape 上的加密芯片,并展示了如何使用 CryptoCape 和指纹扫描仪实现生物识别认证设备。

本章将讨论以下主题:

  • 基于硬件的加密技术的利与弊

  • CryptoCape 概述

  • 如何通过 Cape EEPROM 实现 BBB 的自动硬件配置

  • 如何使用 CryptoCape 的实时钟表

  • 如何从 BBB 编程 ATmega328p

  • 如何实现生物识别认证系统

探索硬件加密和软件加密的差异

在接下来的章节中,我们将讨论使用基于硬件的加密技术的优缺点。本书中的其余项目将使用嵌入式硬件加密设备,因此了解它们的功能和局限性非常重要。有关加密技术和本节中使用的术语的更多资源,请参考第一章,创建您的 BeagleBone Black 开发环境

了解基于硬件的加密技术的优势

关于硬件加密的优点,我们将重点讨论嵌入式环境,因为这正是 BBB 的目标使用场景。虽然芯片制造商可能提供一长串优点,但主要有两个类别:加密加速和密钥隔离功能。

将计算任务卸载到独立的处理器上

使用专用加密协处理器的一个优势是可以卸载计算任务,从而减少 CPU 使用率。一个典型的例子是使用硬件执行高级加密标准AES)的加密和解密操作,在传输层安全协议TLS)会话中进行。

TLS 通常与超文本传输安全协议HTTPS)一起使用。每次在线购物时,您都会使用 HTTPS 来保护您的信用卡信息。根据您的浏览器设置,您可能会注意到锁形图标或绿色条,以指示网页是否通过 HTTPS 传输。在 TLS 会话中,客户端(即您的浏览器)和服务器将协商使用相同的对称密钥。虽然可以协商多种对称加密算法,但 AES 是其中一个常用的选择。

注释

尽管一些网站会自动将你重定向到 HTTPS 版本的站点,但通常你必须手动指定。记得输入https://往往让人感到麻烦,但幸运的是,有一个跨浏览器插件可以自动将你重定向到 HTTPS 站点(如果有的话)。这个插件叫做HTTPS Everywhere,由电子前沿基金会(Electronic Frontier Foundation)维护。有关信息和软件下载链接请访问:www.eff.org/https-everywhere

在加密加速器角色中,一个加密协处理器会执行每个 TLS 记录的加密和解密。这将主 CPU 的负担转移到处理网络流量和执行预定应用程序上。BBB 实际上具有这样一个加密协处理器。德州仪器TI)为 AM335x 处理器提供的加密性能页面显示了他们使用 OpenSSL 进行基准测试的结果。使用 256 位密钥大小的 AES,并对 8192 字节的块进行操作,未使用加密加速时,测得的数据吞吐量为 8129.19 kB/sec。此测试导致 CPU 使用率为 69%。然而,使用 AM335x 上的加密协处理器时,测得的数据吞吐量为 24376.66 kB/sec,CPU 使用率降至 41%。这几乎是吞吐量性能的 200%的提升,同时 CPU 使用率下降了 40%!

注意

更多关于 AM335x 上加密加速器的信息可以在 TI 的加密性能页面找到:processors.wiki.ti.com/index.php/AM335x_Crypto_Performance

如果你的嵌入式应用程序的目的是执行计算密集型的计算,使用一个旨在卸载加密处理的加密协处理器,可以将 CPU 周期节省给你的主程序。

通过物理隔离保护密钥

使用硬件加密设备的一个主要优势是,密钥可以在设备内部生成,并且设计上难以被移除。在 Web 服务器的世界中,这些设备被称为硬件安全模块HSMs)。在 2014 年 4 月,宣布了一个影响 OpenSSL 软件的重大漏洞,通俗地称为Heartbleed。这个漏洞本身并不是加密漏洞本身,而是由于一种叫做缓冲区溢出的编程错误造成的。不幸的是,这种漏洞在 C 语言中比较常见,而 OpenSSL 正是用 C 语言编写的,因为 C 语言没有自动的数组边界检查。攻击者可以利用这个错误,查看服务器的内部内存,可能会发现敏感信息。修复这个问题的代码比这个段落还要短。

注意

以下xkcd漫画简明且有趣地解释了 Heartbleed 漏洞:

xkcd.com/1354/

这个漏洞的规模和严重性是无法过分强调的。最具破坏性的攻击是如果服务器的私钥被泄露。知道私钥后,攻击者可以冒充服务器,客户端可能会不知不觉地向伪造者披露私人信息。然而,在配备硬件安全模块(HSM)的服务器上,心脏出血漏洞的影响则更为有限。像会话 cookie 这样的敏感信息依然可能通过软件漏洞泄露,但服务器的私钥由于保存在 HSM 中,则不会泄露。

由于硬件加密协处理器作为一个物理上独立的机器运行,软件漏洞很难通过主处理器泄露硬件模块中的秘密。在嵌入式世界中,有几种芯片执行了这种密钥隔离功能。

了解硬件加密设备的缺点

添加硬件加密设备并不自动让你的项目变得安全。在接下来的章节中,我们将讨论使用加密硬件的一些缺点以及在项目中使用它们时需要解决的一些问题。

缺乏加密灵活性

硬件加密设备通常不可配置。通常这是设计使然,但其含义是很难(如果不是不可能的话)改变设备的加密行为。如果你选择了一款采用有限密钥大小进行加密的芯片,你将无法以后将设备升级为更强的密钥大小。相较而言,更新基于软件的加密系统通常更容易。

暴露硬件特定的攻击向量

虽然独立的加密处理器可能减少软件攻击或漏洞,但它往往允许更复杂的基于硬件的攻击。硬件攻击分为三类:非侵入性、侵入性和半侵入性(Skoroboga,2011)。非侵入性攻击将芯片视为黑箱,并试图操控周围的环境以进行攻击。成功的非侵入性攻击包括执行差分功率分析DPA),以监控芯片在执行加密算法时的行为。通过测量加密操作中的功率使用情况,可以通过不同的功率特征看到密钥。侵入性攻击通常涉及以某种方式物理破坏芯片,以访问其内部。半侵入性攻击可能涉及某种激光成像技术来观察或干扰芯片。

注意

要执行故障攻击,攻击者尝试通过注入故障来操控执行指令(Bar-El,2004)。安全研究员 Colin O'Flynn 提供了一个简洁明了的示例,展示了故障攻击如何导致密码验证微处理器失败:www.youtube.com/watch?v=Ruphw9-8JWE&list=UUqc9MJwX_R1pQC6A353JmJg

混淆实现细节

需要考虑的一个最终因素是,尽管芯片供应商可能会发布其设备的接口,内部细节通常是专有的。这类似于软件供应商发布软件编程接口,但仅提供已编译的二进制文件,而不提供源代码。在这种情况下,芯片被视为黑盒子,且没有验证设备的机制,你只能信任它正确运行。随着开源社区将加密库移植到独特的微控制器上,这种情况希望能够得到改善。

总结硬件与软件的争论

那么,哪个选择更好呢?像大多数复杂的技术一样,正确的答案是:这取决于具体情况。对于一个真正嵌入式系统,即使是几个字节也不能浪费,如果你不能升级你的微处理器,那么硬件安全芯片可能是唯一的选择。另外,如果由于软件漏洞导致密钥泄露的风险较高,那么独立的加密协处理器可能会有所帮助。然而,如果攻击者能够物理接触你的设备,他们可能会通过硬件攻击提取密钥。最后,如果你非常注重透明度,想要验证是否存在后门,那么只有完全开源的软件和硬件设备才能满足你的需求。

游览 CryptoCape

CryptoCape 是 BeagleBone 的首个专用安全子板。由于 BBB 已经具备了加密加速功能,CryptoCape 上的芯片提供了上一节讨论的密钥隔离特性。在 BeagleBone 社区中,子板被称为 capes,类似于 Arduino 的 shields。CryptoCape 包含了几个可以在项目中使用的加密 IC。其设计为开源硬件,因此你也可以访问 SparkFun 网站来获取设计文件。CryptoCape 包含以下主要组件:

组件 制造商 特性
AT97SC3205T Atmel TPM—RSA 2048 加密和 SHA1 哈希
ATAES132 Atmel 带有 AES-128-CCM 的加密 EEPROM
ATSHA204 Atmel SHA-2 哈希(SHA-256,HMAC-256)
ATECC108 Atmel 使用 NIST 曲线的 ECDSA
ATmega328p Atmel 微控制器
DS3231M Maxim 集成 带电池的实时时钟
CAT24C256 ON 半导体 EEPROM

如果你把 BBB 的以太网连接器想象成脖子,那么附加的子板的切口就像围绕着它一样,仿佛它穿着一件披风,因此得名“CryptoCape”。另外,BeagleBoard.org 的比格犬吉祥物 Boris,穿上披风后看起来更加可爱。

这些芯片及其相关电路在 CryptoCape 板上都有清晰的标记:

Touring the CryptoCape

在接下来的章节中,我们将简要介绍每个组件,并提供一些示例项目想法。

探索 I2C 协议

CryptoCape 上的每个芯片都使用 集成电路互联 (I2C) 总线。I2C 是由飞利浦半导体公司在 20 多年前开发的,但它今天仍在电子设计中广泛应用。I2C 需要两条信号线,一条用于 串行时钟 (SCL),另一条用于 串行数据 (SDA)。连接到总线的设备可以是主设备或从设备。每个从设备都有一个地址,且可以有多个主设备。I2C 协议支持碰撞检测,并且是真正的多主协议。

SDA 和 SCL 线被 上拉 到系统电压 VCC,通常通过连接从 VCC 到 SDA 和 VCC 到 SCL 的电阻来实现。BBB 上的处理器 AM335x 包含总线的内部上拉电阻。数据通过操控 SDA 和 SCL 线的逻辑电平来编码到总线上。例如,开始发送数据时,主设备将 SDA 拉低,同时将 SCL 保持在逻辑高电平。停止条件是通过将 SDA 从低电平拉到高电平,同时保持 SCL 高电平来发送。

注意

I2C 总线规范的第六版可以在 NXP 半导体(前身为飞利浦)的网站上找到,网址为 www.nxp.com/documents/user_manual/UM10204.pdf

以下截图展示了逻辑分析仪捕获的正常 I2C 操作。逻辑分析仪 是一种可以采样电气连接并且常常解码信号以生成人类可读格式的仪器。

发现 I2C 协议

理解扩展板 EEPROM 的好处

一眼看去,CAT24C256 电可擦可编程只读存储器 (EEPROM) 似乎并没有为主板带来太多的价值。毕竟,BeagleBone 在早期版本上配备了 2GB eMMC,在 C 版本中配备了 4GB eMMC。额外的 256 kB 内存对比格尔狗来说几乎不值一提。然而,它却有着更重要的作用;它使得 BBB 能够自动检测扩展板。

BBB 配备了两个 46 针女性扩展端口,提供比市场上任何其他爱好者开发板更强大的 I/O 能力。某些引脚实际上可以支持八种不同的模式,从模式 0 到模式 7。引脚功能与模式的映射被称为 引脚复用,即引脚多路复用。为了在某个模式下使用引脚,软件必须通过内核接口启用并配置该引脚。这可以手动执行或通过脚本进行,但最简单的方法是使用 BeagleBone 扩展板。

在内核启动过程中,软件会探测 I2C 总线,查找 Cape EEPROM。Cape EEPROM 有四个有效地址,范围是 0x54 到 0x57。因此,BBB 支持最多连接四个 Cape。BBB 会读取 Cape EEPROM,EEPROM 必须使用 BBB 系统参考手册SRM)中的格式进行编程。BBB 使用一个名为 capemgr 的软件包,capemgrCape Manager 的简称,来读取 Cape EEPROM 中的板卡名称和版本信息。然后,它会尝试将名称和版本与 BBB 上编译的设备树片段进行匹配。如果匹配成功,它会加载该片段。

注意

BBB 的最新生产文件,包括原理图和 SRM,位于 BBB Wiki 上:elinux.org/Beagleboard:BeagleBoneBlack

这个自动配置提供了两个好处。第一个是 BBB 上的引脚会自动为 Cape 配置。第二个是设备树可以指定用于 Cape 硬件的内核驱动,这意味着你的硬件驱动可以被自动加载。capemgr 提供了一种类似即插即用的体验,适用于嵌入式 Linux。

如果你正在开发一个 BeagleBone Cape,你应该考虑将你的 Cape 纳入 BeagleBone 镜像的支持中。这是一个三步过程。首先,你需要创建一个 Cape EEPROM 文件。该文件应该在制造时写入到你的 Cape 中。第二,你需要创建一个 设备树源文件DTS),遵循之前讨论的 Cape 命名规范,并在 GitHub 上向 BeagleBoard.org 提交拉取请求。最后,你需要创建一个 eLinux Wiki 网站,讨论你的 Cape。在接下来的章节中,我们将简要描述构建 BeagleBone Cape 所需的软件和硬件,并以 CryptoCape 为例。

创建一个 Cape EEPROM

如果你为 BeagleBone 开发了任何半复杂的硬件,增加一个支持 Cape 的 EEPROM 会带来好处。填充 EEPROM 的基本参考是 BeagleBone SRM 中的 Cape 板卡支持 部分。该部分包含 EEPROM 格式。为了快速开始创建你的 EEPROM 文件,你可以使用一个名为 EEPROM Cape 生成器 的工具,访问地址是:github.com/picoflamingo/BBCape_EEPROM。这个工具具有简单的命令行界面,会为你的 Cape EEPROM 提供一个框架。目前,它还没有完全实现 Cape 规格,因此你需要使用二进制编辑器设置 EEPROM 的其余值。创建 EEPROM 二进制文件的过程涉及阅读 SRM,并在正确的偏移量处写入适当的值。

你可以通过以 root 身份执行以下命令来查看 CryptoCape 的 EEPROM:

cat /sys/bus/i2c/devices/1-0057/eeprom | hexdump -C

默认情况下,CryptoCape EEPROM 位于 I2C 总线的地址 0x57。如果你有多个 cape,你可以通过在 EEPROM 旁边的 A0 或 A1 地址垫上放置焊接跳线或焊接来更改 CryptoCape EEPROM 的地址。使用之前命令读取 EEPROM 的结果将产生以下内容:

00000000  aa 55 33 ee 41 31 42 42  2d 42 4f 4e 45 2d 43 52 
 |.U3.A1BB-BONE-CR|
00000010  59 50 54 4f 00 00 00 00  00 00 00 00 00 00 00 00 
 |YPTO............|
00000020  00 00 00 00 00 00 30 30  41 30 53 70 61 72 6b 46 
 |......00A0SparkF|
00000030  75 6e 00 00 00 00 00 00  00 00 42 42 2d 42 4f 4e 
 |un........BB-BON|
00000040  45 2d 43 52 59 50 54 4f  00 00 00 11 32 30 31 34 
 |E-CRYPTO....2014|
00000050  30 30 30 30 30 30 30 30  00 00 00 00 00 00 00 00 
 |00000000........|
00000060  00 00 00 00 00 00 00 00  00 00 e0 73 e0 73 00 00 
 |...........s.s..|
00000070  00 00 00 00 00 00 00 00  00 00 00 00 a0 26 c0 06 
 |.............&..|
00000080  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00 
 |................|
00000090  00 00 a0 2f 00 00 00 00  00 00 c0 17 00 00 00 00 
 |.../............|
000000a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00 
 |................|
*
000000e0  00 00 00 00 00 00 00 00  00 00 00 00 01 f4 00 00 
 |................|
000000f0  00 00 00 00 47 50 47 20  46 69 6e 67 65 72 70 72 
 |....GPG Fingerpr|
00000100  69 6e 74 3a 20 30 78 42  35 39 31 39 42 31 41 43 
 |int: 0xB5919B1AC|
00000110  37 31 33 35 39 30 35 46  34 36 36 39 43 38 34 37 
 |7135905F4669C847|
00000120  42 46 41 35 30 33 31 42  44 32 45 44 45 41 36 0a 
 |BFA5031BD2EDEA6.|
00000130  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff 
 |................|
*
00008000

如果你浏览 SRM EEPROM 数据格式,你应该能够将字段与 CryptoCape EEPROM 中的字段对应起来。两个最重要的字段是Board Name,它从偏移量 6 开始,长度为 32 字节,以及Version,它从字节 38 开始,长度为 4 字节。从之前的示例来看,板载名称是BB-BONE-CRYPTO,版本是00A0。这两个组件在下一节中命名 DTS 文件时是必需的。从偏移量 244 开始,制造商可以放置任何非易失性信息。CryptoCape 包含了GNU 隐私保护GPG)指纹,它是作者的 GPG 公钥,用于签署软件包和电子邮件。在你的 cape 中,你可以使用软件的初始值或类似的内容来填充它。

创建 cape DTS 文件

除了 EEPROM,你还需要创建一个 DTS 文件。该文件向 Linux 内核定义你的硬件属性。CryptoCape 版本 00A0 的 DTS 文件位于 GitHub:github.com/beagleboard/linux/blob/3.8/firmware/capes/BB-BONE-CRYPTO-00A0.dts。在为你的硬件创建新的 DTS 文件时,最好先查看现有的 BeagleBone DTS 文件。随着 cape 数量的增加,很可能已经存在一个符合你硬件配置的批准 DTS 文件。

BBB 设备树覆盖系统是正在积极开发的领域之一,重要的技术细节迅速变化。如果你需要构建自己的 DTS 文件,最好查看 BeagleBoard.org 的邮件列表:groups.google.com/forum/#!forum/beagleboard

注意

2013 年 11 月,Thomas Petazzoni 在欧洲嵌入式 Linux 大会上详细介绍了 Linux 内核中的设备树系统。该演讲可以在 YouTube 上观看,链接:www.youtube.com/watch?v=m_NyYEBxfn8

让我们简要看一下 CryptoCape 的 DTS 文件的一部分。capemgr将加载该文件的已编译版本以配置硬件。由于 DTS 文件中指定了部分芯片的驱动程序,这些驱动程序也会自动加载,如以下代码所示:

fragment@2 {
        target = <&i2c2>;

        __overlay__ {
          #address-cells = <1>;
          #size-cells = <0>;

          /* Real Time Clock */
          ds1307@68 {
            compatible = "ds1307";
            reg = <0x68>;
          };

          /* TPM  */
          tpm_i2c_atmel@29 {
            compatible = "tpm_i2c_atmel";
            reg = <0x29>;
          };
        };
};
ds1307 driver. The second is the TPM driver, tpm_i2c_atmel, which is located at address 0x29\. The EEPROM driver is automatically loaded and the other chips currently do not have a native Linux kernel driver.

如果你已经完成了 DTS 文件,并希望将其包含在官方 BBB 镜像中,你可以向之前提到的包含 CryptoCape DTS 文件的仓库提交一个 pull 请求。由于这个仓库包含了 BeagleBone 固件的现有 DTS 文件,如果你正在构建自己的 cape,研究它是非常值得的。

创建一个 eLinux wiki 网站

最后一步是在eLinux.org上创建一个 Wiki 网站,并通过电子邮件<support@circuitco.com>通知他们将其链接到主 BeagleBone Cape 页面。该页面是所有 BeagleBone capes 的主站点,也是社区期望查找 cape 信息的地方。CryptoCape 页面,包含所有支持软件和数据表的链接,位于elinux.org/Cryptotronix:CryptoCape

EEPROM 是定义 cape 组件的关键。即使你没有制造 cape,仍然可以通过添加 EEPROM 并为自己的设计创建 DTS 文件,从而利用 BeagleBone 的自动硬件配置功能。

使用实时钟保持时间

在系统中同步所有时钟通常是一个假设,这对嵌入式设备来说并不成立。专用设备可能不需要知道时间来执行它们的功能。然而,在安全协议中,准确的时间保持往往是非常重要的。例如,在 TLS 中,用于证明 Web 服务器身份的 X.509 证书包含一个有效期范围。证书中有一个not beforenot after时间,指定了该证书的有效时间。如果没有准确的时间保持系统,设备无法强制执行这个日期范围,可能会接受过期或尚未生效的证书。

如果你在离线环境中使用 BBB,但仍需要准确的时间,那么你可以将一个纽扣电池插入 CryptoCape 的电池仓。当 BBB 断开电源时,RTC 将从电池获得足够的电力以保持准确的时间。

BBB 已经包含一个 RTC;然而,它缺少专用电池。虽然可以通过位于 DC 插座适配器附近的电池接入垫为整个 BBB 供电,但由于整个板子都从这些垫供电,因此需要一个更大容量的电池。

RTC 驱动程序会自动加载,你可以通过运行以下命令进行验证:

dmesg | grep rtc

这应该会导致以下结果:

[    0.729101] omap_rtc 44e3e000.rtc: rtc core: registered 44e3e000.rtc as rtc0
[    0.748605] rtc-ds1307 1-0068: rtc core: registered ds1307 as rtc1
[    0.748627] rtc-ds1307 1-0068: 56 bytes nvram
[    0.977426] [drm] Cannot find any crtc or sizes - going 1024x768
[    1.048851] omap_rtc 44e3e000.rtc: setting system clock to 2000-01-01 00:00:01 UTC (946684801)

之前的示例展示了 BBB 的 RTC,omap_rtc,注册为rtc0,并且设置了一个不太准确的时间 2000-01-01。CryptoCape 的 RTC 是rtc1,而时间值没有被修改。

安装 CryptoCape 后,你需要首先设置 RTC 时间。首先,你需要一个准确的系统时间。请参考第二章中的项目,绕过审查与 Tor 桥接,了解如何操作。使用以下命令从系统时间设置 RTC 时间:

hwclock -w -f /dev/rtc1

交叉检查时间,以确保其设置正确:

hwclock -r -f /dev/rtc1

这应该产生类似于以下的结果:

Tue 13 May 2014 07:29:27 PM UTC  -0.198319 seconds

如果你使用的是 SparkFun 电子产品的纽扣电池,它的标称容量为 47mAh。DS3231m 在电池工作时会消耗 2 安培的电流。理想情况下,这将使电池有 23,500 小时的运行时间,约为 2.7 。实际上,你会看到电池的运行时间远低于理想时间,但即使电池的寿命只有理想时间的一半,你仍然能从 RTC 中获得足够的电池续航。

使用受信计算设备与受信平台模块

受信平台模块TPM)在芯片上执行 RSA 算法。然而,它的功能远不止是一个加密芯片。TPM 规范由受信计算组织TCG)制定和维护,这是一个国际行业标准机构。

多家主要厂商的笔记本电脑都包含 TPM,包括戴尔、惠普,甚至是谷歌 Chromebook。笔记本电脑上的 TPM 通常位于低引脚计数LPC)封装中,并通过 BIOS 启用。嵌入式设备通常不支持 LPC 总线;CryptoCape 上的 TPM 通过 I2C 总线进行通信。

与 TPM 的软件下载接口是通过受信计算组织软件栈TSS)。在 Linux 中,TSS 由 TrouSerS 软件包提供。在下一章中,我们将使用 TPM 并进一步探讨 CryptoCape 上的 TPM。

使用 ATSHA204 和 ATECC108 提供硬件身份验证

ATSHA204 和 ATECC108 都是身份验证设备。身份验证是保证通信双方身份并确保数据完整性的过程。每个芯片采用不同的身份验证方法。ATECC108 设备使用椭圆曲线加密提供椭圆曲线数字签名算法ECDSA)。ATSHA024 设备使用哈希算法 SHA-256 提供基于哈希的消息认证码HMAC)。

注意

本书中没有使用这两种设备,但你可以从github.com/cryptotronix/hashletgithub.com/cryptotronix/eclet下载软件,查看 ATSHA204 和 ATECC108 的示例用法。

使用 ATAES132 加密 EEPROM 数据

ATAES132 是一个 32kb 的 EEPROM,可以使用 128 位密钥通过 AES 加密,采用 Counter with CBC-MAC (CCM) 模式。CCM 提供了一种经过认证的加密模式。通过加密的 EEPROM,你可以更安全地存储少量静态数据。ATAES132 还具有加密和解密最大 32 字节的小数据包的能力,并通过总线返回结果。AES 密钥始终保存在设备中。

写这篇文章时,ATAES132 设备还没有 Linux 驱动程序,但 Atmel 在他们的网站上提供了完整的文档和基于 AVR 的库,地址是 www.atmel.com/devices/ataes132.aspx

将 BBB 与 ATmega328p 结合

最后,CryptoCape 包含一个独立的微控制器。这个微控制器是 ATmega328p,它与 Arduino UNO 上的微控制器相同。然而,由于供电电压是 3.3V,而不是像 Arduino UNO 那样的 5V,处理器的时钟速度为 8MHz,而不是 16MHz。从这个角度来看,它更像是 3.3V 的 Arduino Pro Mini。CryptoCape 由 SparkFun 出货,包含 3.3V 的 Arduino Pro Mini 启动加载程序。像其他任何基于 Arduino 的板子一样,你可以通过将 In-System Programming (ISP) 编程器连接到 ATmega328p 旁边的 ISP 头部来重新烧录启动加载程序。SparkFun 的口袋编程器是执行此任务的廉价工具。只需确保将开关设置为 无电源目标,因为 CryptoCape 是由 BBB 提供电源的。

虽然你可以使用 ISP 编程器,也可以使用 BBB 作为编程器。BBB 包含串行 UART 和 SPI;然而,只有串行 UART,UART 4,连接到板载的 ATmega328p。就像 Arduino UNO 一样,如果微处理器被重置,它会接受通过串行线路上传的程序。

一个简单的脚本,切换连接到 ATmega 复位线的 BBB GPIO(对于 CryptoCape 是 GPIO 49),然后使用 avrdude 上传 hex 文件,便能完成任务。该脚本是 GitHub 仓库的一部分,可以使用以下命令进行克隆:

git clone https://github.com/jbdatko/BBB_ATmega328P_flasher.git

在这个代码库中,有一个 upload.sh 脚本,其主要逻辑包含以下代码片段:

(echo 0 > /sys/class/gpio/gpio49/value \
    && sleep $tts \
    && echo 1 > \
    /sys/class/gpio/gpio49/value) &

avrdude -c arduino -p m328p -b 57600 -v \
    -P /dev/ttyO4 -U flash:w:$1

第一部分将 ATmega 的复位线拉低并睡眠 $tts,目前定义为 0.9 秒。然后,脚本将复位线设置回高电平,允许 ATmega 运行。接下来的这一行是用于上传 hex 文件的 avrdude 命令。你需要使用以下命令安装 avrdude

sudo apt-get install avrdude

然后,运行脚本,执行以下操作:

sudo ./upload Blink.cpp.hex

在烧录 Arduino 草图之前,你必须拥有一个要烧录的草图。根据你的开发偏好,有几种选择。你可以在 BBB 上使用 makefile 和 gcc-avr 构建 AVR 程序,或者你可以使用 Atmel 的免费 AVR Studio 或 Arduino IDE 构建程序。无论你选择哪种方式,你都需要找到编译后的 hex 文件,并使用 sftp 或类似的工具将其下载到 BBB 上。

在将草图上传到 CryptoCape 的 ATmega 之前,你需要执行一个非常重要的步骤:你需要将跳线连接到两个 Program Jumper 引脚。如果没有跳线,ATmega 将无法与 BBB 串行线路电气连接。这是一个安全功能。使用 Arduino 启动加载程序,可以通过串行 UART 上传 hex 文件。因此,在安装跳线后,CryptoCape 上 ATmega 的草图可以随时进行修改。现在想象一下,如果 BBB 被感染了恶意软件,但跳线被拆除了,这个恶意软件就无法更改 ATmega 上的软件。它仍然可以做很多其他恶意事情,包括重置 ATmega,但除非跳线连接,否则无法上传新的固件。

构建一个双重身份验证的生物识别系统

由于 CryptoCape 上有独立的处理器,我们可以创建一些有趣的应用程序。由于 ATmega 只有在物理跳线连接到板上时才能从 BeagleBone 刷写,我们可以将其视为 受信任 处理器。在本项目中,我们将实现一个带指纹传感器和 CryptoCape 的生物识别身份验证系统。我们将使用 ATmega 来防止在你用指纹 向 ATmega 进行身份验证之前访问 CryptoCape 上的安全 IC。

在消费电子设备中,指纹生物识别的一个著名例子是苹果在 iPhone 5s 上的 Touch ID 技术。iPhone 上使用的传感器比我们在本项目中使用的传感器更为复杂且昂贵。但通过完成本项目,你应该能够理解使用生物识别技术的能力与挑战。在 Touch ID 支持页面上,苹果通过以下论点说明了该技术的使用理由:用指纹解锁手机比没有密码更安全,而且比每次输入密码更为便捷。在后续章节中,我们将讨论生物识别系统的弱点。

本项目所需的主要组件列在下表中。列出的 SparkFun 零件是实际使用的零件,但你可以自由替换为等效的组件。CryptoCape 仅由 SparkFun Electronics 生产,是开源硬件,其板卡设计文件采用 Creative Commons 许可协议,因此你也可以根据需要制作自己的 CryptoCape。你还需要一个基本的焊接工具和相关配件。

组件 SparkFun SKU
指纹传感器 SEN-11792
CryptoCape DEV-12773
JST 跳线连接线 PRT-10359
母头跳线 PRT-11710
公头断开头排 PRT-00116
2 针跳线 PRT-09044

以下组件是可选的,但有的话会更好:

组件 SparkFun SKU
热缩套件 PRT-09353
第三只手 TOL-09317
Heaterizer XL-3000 TOL-10326

指纹传感器概述

指纹传感器是来自 ADH 科技的 GT-511C3 设备。该设备包含一个光学传感器用于读取指纹,还配备了一个 ARM Cortex M3 处理器用于进行图像识别。与该设备的接口是通过串行 UART 连接,使用 3.3V 电平逻辑,波特率为 9600 bps。通过 JST 连接器有四根线需要连接:发送、接收、GND 和电源。

数据表中指出,误接受率小于 0.001%,误拒绝率小于 0.1%。简而言之,这是一个非常强大的指纹传感器。指纹数据被分析并存储在该设备上。我们将使用现有的库与此硬件进行通信。

理解指纹生物识别的局限性

请注意,这种指纹传感器认证机制的安全性仅与您的指纹强度相关。关于使用指纹传感器的常见批评集中在这样一个事实:指纹一旦被复制,您就无法像更改密码一样撤销或更改它。使用指纹作为两因素认证机制稍微降低了认证漏洞的风险,因为仍然需要输入 PIN 码或密码。您还可以通过安排一名武装警卫守卫传感器来降低假指纹攻击的风险,正如安全技术专家布鲁斯·施奈尔(Bruce Schneier)在 2013 年 9 月《WIRED》杂志的一篇评论文章中所指出的那样。这样的奢侈措施通常只限于资金雄厚的政府。

科学突破者,一档在探索频道播出的流行科学和工程节目,揭穿了指纹无法复制的神话,并展示了如何绕过指纹传感器:www.youtube.com/watch?v=3Hji3kp_i9k。此外,在苹果 iPhone 5s 发布几天后,混乱计算机俱乐部CCC)的生物识别黑客团队展示了如何绕过指纹传感器:www.ccc.de/en/updates/2013/ccc-breaks-apple-touchid

也许生物识别系统最大的危险是可能引发严重的隐私泄露。一旦指纹数据被暴露,它们将不再对任何其他生物识别系统有用,永远。2014 年 8 月,信息安全取证公司 Hold Security 向纽约时报报告称,一家俄罗斯犯罪组织窃取了超过 12 亿个用户名和密码。虽然这个泄露事件造成了极大的损害,但如果使用指纹生物识别,数据将无法恢复。希望公司不会直接存储指纹,而是存储类似哈希摘要的指纹表示。然而,如果实现不当,结果可能像存储原始指纹一样灾难性。

考虑到这些警告,我们将继续在本项目中使用指纹传感器。你将了解指纹传感器如何工作以及它如何融入身份验证系统中。然而,完成此项目后,你可能需要从传感器的数据库中删除你的指纹。

准备 CryptoCape

为了使 CryptoCape 更具可破解性,我们需要将 I/O 信号的焊盘焊接上公头插针。这将使我们能够连接各种外部组件。虽然你可以直接焊接到焊盘,但最好是焊接一个 0.1 英寸的公头引脚,这样你就可以轻松连接带母端的跳线,以便你的项目使用,之后还能重复使用。

完全焊接好的 CryptoCape 应如下图所示。31 个引脚或更多的断开式插针足以填充每个焊盘。从技术上讲,除非你打算写入 EEPROM,否则不需要填充 EEPROM 写保护焊盘。不过,如果你覆盖了 EEPROM 的外设信息,BBB 可能无法加载正确的驱动程序。

准备 CryptoCape

准备连接

在连接任何线缆之前,我们需要物理方法将 JST 电缆的端连接到 CryptoCape。CryptoCape 具有 0.1 英寸的焊盘,可以容纳 0.1 英寸的公头插针,并且母对母的跳线也能完美匹配该连接。JST 连接器的一端是四根裸线。如果你将每根线焊接到一个 4x1 0.1 英寸的公头插针上,你就能制作一个简单的连接器。使用第三只手,你可以将 JST 电缆焊接到插针上,最后在电线和公头引脚周围加热缩管。记住,在焊接前一定要先把热缩管套上!完成的连接器应该像这样:

准备连接

将扫描仪连接到 CryptoCape

我们将把指纹扫描仪连接到 CryptoCape。该传感器的 Arduino 兼容库由 Josh Hawley 开发。该库配置为使用数字引脚 4 作为 ATmega 的接收引脚,数字引脚 5 作为 ATmega 的发送引脚。这些引脚在 CryptoCape 上被标记为D4D5,位于 ATmega 下方。剩余的两个引脚分别是 3.3V 电源和地,它们也与 D4 和 D5 引脚在同一排。将跳线的母端连接到这些引脚。如果你使用 SparkFun 的 JST 连接器,指纹扫描仪的引脚顺序如下,从黑色线开始:D4、D5、GND、电源。

准备指纹传感器

必须通过一个叫做 注册 的过程来训练指纹传感器识别您的指纹。有几种方法可以注册您的指纹。SparkFun 网站提供了如何使用 ADH-Tech 提供的基于 Windows 的软件来编程传感器的说明。然而,您需要额外的组件,即 FTDI 基本分离板,将电脑的 USB 转换为扫描仪所需的串口。您也可以直接使用 Arduino,但如果使用 5V 的 Arduino,还必须使用逻辑电平转换器。由于 CryptoCape 配备了兼容 Arduino 的处理器,我们将展示如何在 BBB 和 CryptoCape 上执行此操作。包含 ATmega 固件的仓库可以通过以下命令克隆到您的 BBB 上:

git clone https://github.com/jbdatko/Fingerprint_Scanner-TTL.git

在这个仓库中,FPS_Enroll.ino 文件将会将指纹注册到传感器的数据库中。正如之前提到的,您需要单独编译此文件。或者,您也可以使用仓库中的预编译版本。

上传注册脚本:

sudo ./upload.sh FPS_Enroll.cpp.hex

您应该看到类似下面的文字滚动:

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f
avrdude: safemode: lfuse reads as 0
avrdude: safemode: hfuse reads as 0
avrdude: safemode: efuse reads as 0
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
 To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "FPS_Enroll.cpp.hex"
avrdude: input file FPS_Enroll.cpp.hex auto detected as Intel Hex
avrdude: writing flash (11458 bytes):

Writing | ################################################## | 100% 3.09s

avrdude: 11458 bytes of flash written
avrdude: verifying flash memory against FPS_Enroll.cpp.hex:
avrdude: load data flash data from input file FPS_Enroll.cpp.hex:
avrdude: input file FPS_Enroll.cpp.hex auto detected as Intel Hex
avrdude: input file FPS_Enroll.cpp.hex contains 11458 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 2.21s

avrdude: verifying ...
avrdude: 11458 bytes of flash verified

avrdude: safemode: lfuse reads as 0
avrdude: safemode: hfuse reads as 0
avrdude: safemode: efuse reads as 0
avrdude: safemode: Fuses OK

avrdude done.  Thank you.

如果出现问题,首先检查跳线是否连接好,然后再试一次。

该脚本将在 9600 波特率下输出到串口,因此我们需要将 /dev/ttyO4 更改为反映此波特率:

sudo stty -F /dev/ttyO4 9600

最后,让我们通过以下命令显示串口的输出:

cat /dev/ttyO4

脚本会耐心地等待您注册指纹。将您的指纹放在读卡器上,查看串口输出并按照提示操作。成功注册的输出看起来是这样的:

Remove finger
Press same finger again
Remove finger
Press same finger yet again
Remove finger
Enrolling Successful

如果出现问题,且注册过程有些挑剔,您需要重置 ATmega 并重新尝试注册。在同一个仓库中有一个脚本,reset.sh,它简单地切换 ATmega 的复位线。如果您遇到问题,请重置您的 ATmega 并重新尝试。

上传生物识别检测草图

现在传感器已经训练好识别您的指纹,我们将上传一个草图,该草图将在您出示指纹之前锁定 CryptoCape。具体来说,它将防止 BBB 访问 CryptoCape 上的芯片。我们将通过干扰 I2C 总线上的 SCL 线来实现这一点。

I2C 的一个弱点是,一个未对齐的设备就能干扰整个总线。在 CryptoCape 上,每个 IC 都连接到同一条 I2C 总线上。我们将在此项目中利用这一点。ATmega 将保持 SCL 低电平,直到成功接收到指纹。这实际上会干扰总线,因为主设备 BBB 无法生成启动条件。

在 BBB 上运行的软件会暂停,直到 ATmega 释放锁定。通常来说,这种效果是非常不希望出现的。然而,对于这个项目来说,它展示了两个微处理器如何相互作用甚至干扰对方。在下图中,您可以看到 Salee 逻辑分析软件中这种干扰的效果。一旦 SCL 被释放,BBB 就终于能够发送启动条件。

上传生物识别检测草图

FPS_CryptoCape.ino 文件中,这是通过将数字输出 2 设置为输出并拉低线路来实现的。当识别到指纹时,针脚被配置为输入,这防止了 ATmega 拉高或拉低线路,并允许正常的 I2C 操作。

从 ATmega 引脚板上的 D2 到 CryptoCape 上靠近 TPM 的 SCL 引脚添加一根跳线。这是唯一的一根额外线路,它将允许 ATmega 锁定 BBB 对 I2C 总线的访问。一旦添加了该线路,上传 FPS_CryptoCape.cpp.hex 文件,你可以自己编译或使用预编译版本。你 CryptoCape 上的线路应该如下图所示:

上传生物识别检测草图

像之前一样上传草图,然后使用相同的 cat /dev/ttyO4 命令监听串口。你将看到 ATmega 正在等待传感器的指纹。将你的指纹放到传感器上,完成后它会打印出验证结果:

Please press finger
Verified ID:0

你还会注意到,CryptoCape 上的绿色 LED 会熄灭。当 LED 点亮时,ATmega 正在阻止你的 BBB 访问 CryptoCape。

生物识别系统的安全分析

我们的生物识别系统有多安全?虽然它确实阻止 BBB 上的软件在接受有效指纹之前使用 CryptoCape,但通过拉断(或切断)D2 到 SCL 线路,系统可以很容易被攻破。没有电气连接,ATmega 无法干扰 I2C 总线。然而,根据你的安装情况,攻击者可能很难物理接触到硬件。评估漏洞及其缓解措施的过程被称为 威胁建模。在上一章中,Tor 的设计指出它无法防御全球被动对手。在你实施我们的生物识别系统时,可能访问干扰线路并不是威胁,因为你已经把 BBB 放进了一个金刚石盒子。没有完美的安全系统,所以威胁模型帮助我们理解系统的优缺点和假设。在最后两章中,我们将看到更多的威胁建模内容。

总结

本章提供了对 BeagleBone cape 和 CryptoCape 的深入了解。我们介绍了可信计算的概念,并建立了一个生物识别认证系统。我们展示了 I2C 设备的正常使用场景,并说明了一个恶意设备如何破坏整个总线。

在下一章,我们将使用 BBB 来保护 Pretty Good Privacy (PGP) 及其免费软件实现 GPG 的电子邮件加密和签名密钥。

第四章:使用受信平台模块保护 GPG 密钥

在我们对 BBB 硬件安全性进行调查后,我们将利用该技术来保护你在流行的 GPG 软件中的个人加密密钥。GPG 是 OpenPGP 标准的免费实现。这个标准是基于菲利普·齐默曼和他的非常好的隐私PGP)软件的工作而开发的。PGP 有一个复杂的社会政治背景,我们会在进入项目之前简要介绍。对于本项目,我们将把 BBB 视为一个独立的加密协处理器,并使用带有数字键盘输入设备的 CryptoCape 来保护我们在不使用时的 GPG 密钥。

具体来说,我们将执行以下操作:

  • 简要介绍 PGP 软件的历史和重要性

  • 执行基本的威胁建模来分析你的项目

  • 使用免费的 GPG 软件创建一个强大的 PGP 密钥

  • 教你如何使用 TPM 保护加密密钥

PGP 的历史

本章中使用的软件曾经被美国政府视为军火。如果没有政府许可就出口它,将违反国际武器贸易条例ITAR)。直到 1990 年代初,密码学仍受到严格控制和限制。虽然 90 年代初期充斥着密码活动家的诸多记载,这些都在史蒂文·莱维(Steven Levy)的《加密》(Crypto)一书中有详细记载,但有一个人尤其是本项目软件背后的推动力量:菲利普·齐默曼。

菲利普·齐默曼(Philip Zimmerman)在 1990 年左右有一个小型的个人项目,他称之为非常好的隐私(Pretty Good Privacy)。受到儿时对密码和密码学的强烈兴趣以及对能够进行强大电子监控的政府的政治反感的驱使,他着手为人民创建一个强加密程序(Levy 2001)。

有一个事件特别促使齐默曼完成 PGP 并发布了他的工作。那就是当时的美国参议员约瑟夫·拜登(Joseph Biden)在第 266 号参议院法案中添加的语言,该法案将要求:

“电子通信服务提供商和电子通信服务设备制造商应确保通信系统允许政府在法律授权的情况下,获得语音、数据和其他通信的明文内容。”

1991 年,为了在 PGP 1.0 被宣布非法之前赶紧发布,齐默曼将他的软件作为免费软件发布到互联网。随后,随着 PGP 的传播,美国政府对齐默曼进行了刑事调查,指控他违反了美国的出口法。齐默曼通过一种可以称之为法律破解的方式,将 PGP 的整个源代码,包括如何将其扫描回数字形式的说明,作为一本书发布。正如齐默曼所描述的:

“政府要禁止出口任何人都可以在公共图书馆或书店找到的书籍,在政治上是很困难的。”
--(Zimmerman, 1995)

一本公开领域出版的书籍将不再受到 ITAR 出口管制的限制。魔 genie 已经从瓶子里放了出来;政府在 1996 年放弃了对 Zimmerman 的指控。

反思加密战争

Zimmerman's 的斗争被认为是一次顽强的胜利。许多其他强烈支持强加密技术的人,也就是被称为 密码朋克 的人,也赢得了普及和传播加密技术的战斗。但是,如果加密战争在九十年代初就已胜利,为什么加密技术还没有变得无处不在呢?嗯,在某种程度上,它已经变得普及。当您在网上购物时,应该受到强加密技术的保护。几乎没有人会坚持要求他们的银行或在线商店 使用加密技术,大多数人可能会觉得它们使用加密技术更安全。但个人隐私保护软件呢?对于这些工具,必须改变习惯,因为普通的电子邮件、聊天和网页浏览工具默认情况下是不安全的。这种变化引起了紧张情绪和对采用的抵制。

此外,安全工具通常难以使用。在关于安全可用性的开创性论文中,研究人员得出结论,当时的 PGP 5.0 版本,尽管有 图形用户界面 (GUI),也未能防止那些对加密学没有经验但至少具有大学教育的用户犯下灾难性的安全错误(Whitten 1999)。Glenn Greenwald 因为认为 GPG 太复杂,所以推迟了大约两个月才与 Edward Snowden 取得初步联系(Greenwald,2014)。Snowden 坚决拒绝与 Greenwald 分享任何信息,直到他安装了 GPG。

GPG 和 PGP 使个人能够保护自己的通信。隐含地,您还必须信任接收方不会转发您的明文通信。GPG 期望您保护自己的私钥,并不依赖于第三方。虽然这增加了一些复杂性和维护过程,但信任第三方持有您的私钥可能是灾难性的。2013 年 8 月,Ladar Levison 决定关闭他自己的公司 Lavabit(一家电子邮件提供商),而不是将用户的数据交给当局。Levison 勇敢地关闭了公司,而不是交出数据。

Lavabit 服务生成并存储了您的私钥。尽管该密钥已加密为用户的密码,但它仍然使服务器能够访问原始密钥。尽管 Lavabit 服务减轻了用户自己管理私钥的负担,但却让 Levison 处于尴尬的境地。要正确使用 GPG,您绝不应交出您的私钥。要了解 Lavabit 的完整分析,请参阅 Moxie Marlinspike 在 www.thoughtcrime.org/blog/lavabit-critique/ 上的博客文章。

鉴于国家监控能力的广泛性和深度,保护个人隐私的兴趣重新升温。研究人员现在正在设计安全协议,考虑到这些威胁(Borisov, 2014)。Philip Zimmerman 在《为何需要 PGP?》章节的官方 PGP 用户指南中以以下语句作结,这句话今天依然如当初写下时一样真实:

“PGP 赋予人们掌控自己隐私的能力。社会对这种需求的关注日益增加。”

开发威胁模型

在上一章结束时,我们介绍了威胁模型的概念。威胁模型是对系统安全性的一种分析,旨在识别资产、威胁、漏洞和风险。像任何模型一样,分析的深度可以有所不同。在接下来的章节中,我们将提供一个简要分析,帮助你开始思考这个过程。此分析还将帮助我们理解项目的能力和局限性。

描述密钥保护系统

我们分析的第一步是清楚地描述我们要保护的系统。在这个项目中,我们将使用 BBB 和 CryptoCape 构建一个逻辑 GPG 协处理器。我们将在 BBB 上存储 GPG 密钥,然后通过安全外壳SSH)连接到 BBB 使用密钥并运行 GPG。CryptoCape 将用于在不使用时加密你的 GPG 密钥,称为静态加密(at rest)。我们将添加一个数字键盘,用于收集一个数字代码,该代码将传递给 TPM。这将允许 TPM 解包你的 GPG 密钥。

本项目的想法来源于 Peter Gutmann 对开源加密协处理器的研究工作(Gutmann, 2000)。当 BBB 作为主机的协处理器时,具有极高的灵活性,考虑到功耗,性能也相对较高。通过将敏感代码运行在一个能够访问明文加密密钥的独立硬件上,我们获得了额外的保护层(或者至少是一层间接性保护)。

识别我们需要保护的资产

在我们保护任何东西之前,我们必须知道需要保护的是什么。最重要的资产是 GPG 私钥。拥有这些密钥,攻击者可以解密过去加密的消息、恢复未来的消息,并利用密钥冒充你。通过保护你的私钥,我们也在保护你的声誉,这是另一个资产。我们解密后的消息也是一种资产。如果攻击者能够轻松访问你解密的消息,他/她可能不会在乎你的密钥。BBB 本身也是一个需要保护的资产。如果 BBB 变得无法使用,那么攻击者就成功阻止了你访问私钥,这种攻击被称为拒绝服务DOS)。

威胁识别

要识别针对我们系统的威胁,我们需要对敌人的能力进行分类。这是一个高度个人化的分析,但我们可以将敌人概括为三种原型:资金充足的国家行为者、技术高超的黑客和心怀嫉妒的前任。国家行为者拥有几乎无限的资源,无论是从财务还是人力资源角度来看。黑客是一个技术高超的操作者,但缺乏国家行为者的资金和资源。心怀嫉妒的前任不是一个复杂的计算机攻击者,但他非常有动机伤害你。

不幸的是,如果你成为国家行为者定向监视的目标,你可能面临比 GPG 密钥更严重的问题。这个行为者可以将你的一生都置于监控之下,为什么要费力去窃取你的 GPG 密钥呢?墙壁中的隐藏摄像头早已记录下你屏幕上的一切。

同时,合理的假设是,你与之沟通的每个人也都在被监视,只需要一个人的一个小错误,就可能暴露你征服世界的计划。

提示

本杰明·富兰克林的格言在这里非常适用:三个人能守住一个秘密,前提是其中两个已经死了

然而,正确使用 GPG 将保护你免受全球被动监控。当正确使用时,既不会你的互联网服务提供商,也不会你的电子邮件服务提供商或任何被动攻击者能够了解你消息的内容。被动攻击者不会直接攻击你的系统,但他们可能会监控大量的互联网流量,试图收集所有信息。因此,你消息的机密性应该得到保护。

我们假设试图伤害你的黑客是远程攻击,且没有物理访问你 BBB 的权限。我们还假设最坏的情况,即黑客已经攻破了你的主机。在这种情况下,不幸的是,黑客能够执行很多操作。他可以安装键盘记录器,捕捉到所有内容,包括你在电脑上输入的密码。虽然他无法获取我们将在 BBB 上输入的代码,但他可以在密钥可用时登录 BBB。

心怀嫉妒的前任并不太懂计算机,但他不需要懂,因为他知道如何使用高尔夫球棒。他知道,与你的计算机连接的这个 BBB 对你来说非常重要,因为你曾经滔滔不绝地向他讲述过一本书里那项非常酷的项目。他可以物理摧毁 BBB,连同它里面的你的私钥(也许这段关系也会一起破裂!)。

识别风险

前述风险的可能性有多大?幸运的是,在大多数国家,政府的主动监控风险较低。然而,这种攻击的后果非常严重。正如我们从爱德华·斯诺登事件中了解到的,被国家行为者卷入被动监控的风险是非常可能的。然而,通过使用 GPG,我们能为此类威胁增加一层保护。一个主动的黑客试图伤害你是比较不太可能的。但感染键盘记录恶意软件的风险,可能并非不合理。微软在 2013 年的一项研究中得出结论,每 1000 台计算机中就有 8 台感染了恶意软件。你或许会尝试冒这些风险,但让我们换个说法:在一组 125 台计算机中,就有一台感染了恶意软件。一个学校或大学的计算机数目远远超过这个数字。最后,只有你自己可以评估被嫉妒的前任伤害的风险。

注释

欲了解完整的微软报告,请参考blogs.technet.com/b/security/archive/2014/03/31/united-states-malware-infection-rate-more-than-doubles-in-the-first-half-of-2013.aspx

减轻已识别的风险

如果你发现自己成为国家的目标,这个项目单独并不能提供太大帮助。我们可以通过两种策略在一定程度上保护自己免受黑客攻击。第一种是,不将 BBB 连接到你的笔记本或计算机,而是将 BBB 作为独立机器使用,通过 microSD 卡传输文件。这被称为空气隔离。配备专用的显示器和键盘时,软件漏洞破坏隔离并感染 BBB 的可能性大大降低。然而,这会带来较高的个人不便,具体取决于你加密文件的频率。如果你认为将 BBB 连接到计算机的风险太高,可以创建一个空气隔离的 BBB 以获得最大保护。如果你认为风险较低,因为你已经加固了计算机并有其他保护机制,那么可以将 BBB 连接到计算机。

注释

空气隔离的计算机仍然可能受到攻击。2010 年,一种名为 Stuxnet 的高度专业化蠕虫能够通过 USB 闪存驱动器传播到网络隔离的计算机。

第二种策略是通过某种方式将 GPG 密码直接输入 BBB,而不使用主机的键盘。完成项目后,我们将建议一种机制来实现这一点,但它稍微复杂一些。这将消除键盘记录器的威胁,因为密码直接输入。

针对前任的防护措施是像保护自己的钱包一样保护你的 BBB,不要让它离开你的视线。它比你想象的稍大一些,但足够小,可以放进一个小背包或公文包里。

总结我们的威胁模型

我们的威胁模型虽然简略,但展示了在使用或开发安全技术之前应经过的思考过程。威胁模型这个术语是安全行业的专用词汇,但它其实就是合适的规划。这个分析的目的是发现逻辑漏洞,防止你花费数千美元为前门安装高科技锁,却忽视了后门的安全。现在我们明白了我们要保护什么以及为什么使用 GPG 很重要,接下来让我们构建项目。

生成 GPG 密钥

首先,我们需要在 BBB 上安装 GPG。它很可能已经安装好了,但你可以通过以下命令检查并安装它:

sudo apt-get install gnupg gnupg-curl

接下来,我们需要添加一个密钥。对于已经拥有密钥的人,你可以将密钥环secring.gpg导入到你的~/.gnupg文件夹中。对于想要创建新密钥的人,在 BBB 上请继续执行接下来的步骤。

注意

本项目假设你对 GPG 有所了解。如果 GPG 对你来说是新鲜事物,Free Software Foundation 维护了一份电子邮件自我防护指南,这是一个非常易于理解的 GPG 入门介绍,指南可以在emailselfdefense.fsf.org/en/index.html找到。

生成熵

如果你决定在 BBB 上创建新密钥,我们需要考虑一些技术细节。首先,GPG 需要大量的随机数据来生成密钥。内核中可用的随机数据量与可用的熵量成正比。你可以使用以下命令检查可用的熵量:

cat /proc/sys/kernel/random/entropy_avail

如果这个命令返回一个较低的数字,低于 200,那么 GPG 将没有足够的熵来生成密钥。在 PC 上,人们可以通过与计算机交互来增加熵,例如敲击键盘或移动鼠标。然而,这种熵来源对于嵌入式系统来说比较困难,在我们当前的设置中,我们没有奢侈的条件去移动鼠标。

幸运的是,有一些工具可以帮助我们。如果你的 BBB 运行的是 3.13 或更高版本的内核,我们可以利用 AM3358 上的硬件随机数生成器来帮助我们。你需要安装rng-tools包。安装完成后,你可以编辑/etc/default/rng-tools,并添加以下行来注册硬件随机数生成器以供rng-tools使用:

HRNGDEVICE=/dev/hwrng

完成此操作后,你应该启动rng-tools守护进程,命令如下:

/etc/init.d/rng-tools start

如果你没有/dev/hwrng——目前,CryptoCape 上的芯片还不支持字符设备,也无法访问/dev/hwrng——那么你可以安装haveged。这个守护进程实现了硬件易失性熵收集与扩展HAVEGE)算法,详细信息可以参考www.irisa.fr/caps/projects/hipsor/。这个守护进程将确保 BBB 保持熵池,这对于在 BBB 上生成 GPG 密钥是足够的。

创建一个好的 gpg.conf 文件

在你生成密钥之前,我们需要为 GPG 建立一些更安全的默认设置。正如我们之前讨论的,使用电子邮件加密仍然不像应该的那样简单。Riseup.net 是一家具有强烈社会责任感的电子邮件提供商,它在help.riseup.net/en/security/message-security/openpgp/best-practices上维护着一份 OpenPGP 最佳实践指南。该指南详细说明了如何加固你的 GPG 配置,并为每个选项提供了背后的动机。阅读这份指南非常值得,它可以帮助你理解 GPG 密钥管理的复杂性。

Jacob Applebaum 维护了这些最佳实践的实现,你可以从github.com/ioerror/duraconf/raw/master/configs/gnupg/gpg.conf下载并保存为你的~/.gnupg/gpg.conf文件。该配置文件有详细注释,你可以参考Riseup.net提供的最佳实践指南以获取更多信息。然而,有三个条目需要你进行修改。第一个是default-key,它是你主 GPG 密钥的指纹。在本章稍后,我们将向你展示如何检索该指纹。现在我们无法执行此操作,因为我们还没有密钥。第二个是keyserver-options ca-cert-file,它是密钥服务器池的证书授权。密钥服务器托管你的公钥,密钥服务器池是多个冗余的密钥服务器集合。Riseup.net上的说明提供了如何下载和安装该证书的详细信息。最后,你可以使用 Tor 来获取密钥更新。

你向密钥服务器请求公钥的行为表明你可能有兴趣与该密钥的所有者进行通信。对于一个被动的对手而言,这些元数据可能比你的消息内容更有价值,因为它揭示了你的社交网络。正如我们在第二章中学到的,使用 Tor 桥接绕过审查,Tor 在保护流量分析方面表现出色。你可能不希望将你的 GPG 密钥存储在与桥接相同的 BBB 上,因此第二个 BBB 会有所帮助。在你的 GPG BBB 上,你只需要将 Tor 作为客户端运行,这是其默认配置。然后,你可以更新keyserver-options http-proxy,指向你在localhost上运行的 Tor SOCKS 代理。

注意

电子前沿基金会 (EFF) 提供了一些关于元数据揭示性质的假设性例子,例如,他们(政府)知道你曾从金门大桥拨打自杀预防热线。但通话的内容依然是机密。更多细节请参阅 EFF 博客文章:www.eff.org/deeplinks/2013/06/why-metadata-matters

生成密钥

现在你可以生成你的 GPG 密钥了。按照屏幕上的指示进行操作,不要包含评论。根据你的熵源,这可能需要一段时间。这个例子使用 haveged 作为熵收集器花费了 10 分钟。关于设置过期日期存在不同意见。如果这是你第一次使用 GPG,先尝试设置一年。你随时可以创建一个新密钥或延长现有密钥的有效期。如果你将密钥设置为永不过期,而你又丢失了密钥(例如忘记了密码),别人仍然会认为它是有效的,除非你撤销它。此外,务必将用户 ID 设置为与某种身份认证匹配的名字,这样更容易验证持有私钥的人与认证文件上的姓名一致。创建新密钥的命令是 gpg --gen-key

Please select what kind of key you want:
 (1) RSA and RSA (default)
 (2) DSA and Elgamal
 (3) DSA (sign only)
 (4) RSA (sign only)
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
 0 = key does not expire
 <n>  = key expires in n days
 <n>w = key expires in n weeks
 <n>m = key expires in n months
 <n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at Sat 06 Jun 2015 10:07:07 PM UTC
Is this correct? (y/N) y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
 "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"

Real name: Tyrone Slothrop
Email address: tyrone.slothrop@yoyodyne.com
Comment:
You selected this USER-ID:
 "Tyrone Slothrop <tyrone.slothrop@yoyodyne.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
You need a Passphrase to protect your secret key.

We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy.
......+++++
..+++++

gpg: key 0xABD9088171345468 marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2015-06-06
pub   4096R/0xABD9088171345468 2014-06-06 [expires: 2015-06-06]
 Key fingerprint = CBF9 1404 7214 55C5 C477  B688 ABD9 0881 7134 5468
uid                 [ultimate] Tyrone Slothrop <tyrone.slothrop@yoyodyne.com>
sub   4096R/0x9DB8B6ACC7949DD1 2014-06-06 [expires: 2015-06-06]

gpg --gen-key  320.62s user 0.32s system 51% cpu 10:23.26 total

从这个例子中,我们知道我们的密钥是 0xABD9088171345468。如果你创建了多个密钥,但更常使用其中的一个,你可以编辑 gpg.conf 文件并添加以下行:

default-key 0xABD9088171345468

生成后维护

为了让他人可以向你发送加密信息,他们需要知道你的公钥。设置公钥服务器有助于分发你的公钥。你可以按照以下方式发布你的公钥,并将指纹替换为你的主密钥 ID:

gpg --send-keys 0xABD9088171345468

注意

GPG 不依赖第三方,期望你自行管理密钥。为了简化这一工作,OpenPGP 标准定义了“信任网络”机制,用于验证其他用户的密钥。关于如何参与信任网络的详细信息可以在 GPG 隐私手册中找到:www.gnupg.org/gph/en/manual/x334.html

你还需要创建一个撤销证书。撤销证书在你想撤销密钥时是必要的。比如说,如果密钥被盗,你需要撤销它。或者更可能的情况是,如果 BBB 发生故障,你无法再访问密钥。生成证书并按照提示操作,将 ID 替换为你的密钥 ID:

gpg --output revocation-certificate.asc --gen-revoke 0xABD9088171345468

sec  4096R/0xABD9088171345468 2014-06-06 Tyrone Slothrop <tyrone.slothrop@yoyodyne.com>

Create a revocation certificate for this key? (y/N) y
Please select the reason for the revocation:
 0 = No reason specified
 1 = Key has been compromised
 2 = Key is superseded
 3 = Key is no longer used
 Q = Cancel
(Probably you want to select 1 here)
Your decision? 0
Enter an optional description; end it with an empty line:
>
Reason for revocation: No reason specified
(No description given)
Is this okay? (y/N) y

You need a passphrase to unlock the secret key for
user: "Tyrone Slothrop <tyrone.slothrop@yoyodyne.com>"
4096-bit RSA key, ID 0xABD9088171345468, created 2014-06-06

ASCII armored output forced.
Revocation certificate created.

Please move it to a medium which you can hide away; if Mallory gets access to this certificate he can use it to make your key unusable.
It is smart to print this certificate and store it away, just in case your media become unreadable.  But have some caution:  The print system of your machine might store the data and make it available to others!

请听从建议,将此文件移出 BeagleBone。将其打印并存放在安全地方是一个不错的选择,或者将其刻录到 CD 上。

注意

CD 或 DVD 的使用寿命可能不像你想象的那么长。美国国家档案馆关于光学存储介质的常见问题页面指出:

“CD/DVD 的实际使用寿命为 2 到 5 年,尽管发布的预期寿命通常标称为 10 年、25 年或更长。”

参考他们的网站www.archives.gov/records-mgmt/initiatives/temp-opmedia-faq.html获取更多详细信息。

最后,创建你的加密备份密钥,并考虑将其存储在耐用介质上的安全位置。

使用 GPG

有了你创建或导入的 GPG 私钥,你现在可以在 BBB 上像在任何其他计算机上一样使用 GPG。在第一章中,创建你的 BeagleBone Black 开发环境,你在主机计算机上安装了 Emacs。如果你按照 GNU/Linux 的指示操作,你也可以在 BBB 上安装 Emacs。如果你这样做,你将享受自动的 GPG 文件加密和解密功能,用于以.gpg扩展名结尾的文件。例如,假设你想给你的好朋友 Pirate Prentice 发送一条消息,他的 GPG 密钥你已经有了。在 Emacs 中撰写你的消息,然后以.gpg扩展名保存。Emacs 将提示你选择用于加密的公钥,并自动加密缓冲区。如果一个 GPG 加密消息是加密给你有相应私钥的公钥,当以.gpg结尾时,Emacs 将自动解密消息。在从终端使用 Emacs 时,加密的提示应该看起来像以下截图:

使用 GPG

用 TPM 保护你的 GPG 密钥

如果你愿意,你可以现在停止项目并愉快地在你的 BBB 上使用 GPG。但是如果你这样做,你将错过使用 CryptoCape 提供的一些额外保护,特别是可信平台模块TPM)。在接下来的部分中,我们将使用 TPM 来保护我们的 GPG 私钥。

介绍可信计算

TPM 是一个密码协处理器。CryptoCape 上的 TPM 是 Atmel 的嵌入式 I2C 版本,符合由可信计算组TCG)发布的 TPM 规范 1.2 版。TCG 是一个行业联盟,负责维护和开发可信计算的开放规范。在 RFC 4949 中,可信的定义是:按设计和政策预期运行的系统

从密码学角度看,TPM 1.2 存在一些限制。它实现了 RSA 算法,SHA-1,具有内部随机数生成器和一些有限的存储空间。它不提供任何对称加密算法。这些限制是为了设计成本低廉、可嵌入模块的设计目标。对称加密算法被排除在外,因为使用 TPM,可以保护静态对称密钥,并允许更强大的主机计算机对其进行操作。

TPM 1.2 规范总共有 700 多页。我们将关注 TPM 的一个独特特性,这个特性使得它的许多安全功能成为可能:平台控制寄存器 (PCRs)。PCRs 是 TPM 寄存器,始终可以读取,但只能通过扩展操作写入。扩展操作获取当前的 20 字节 PCR 值,与一个 20 字节的输入值组合,并将新的 PCR 值设置为这个组合的 SHA-1 结果。关键点在于一旦 PCR 被设置,就无法逆转。它只能在未来的扩展操作中继续组合。

起初,这个功能可能不明显有何帮助。让我们考虑一个例子。在启动时,您的计算机的 BIOS 在加载引导加载程序之前,首先将引导加载程序的 SHA-1 哈希发送到 TPM 以扩展一个 PCR。然后加载引导加载程序。引导加载程序在您的内核上执行相同的操作。然后内核在各种启动系统上执行相同的操作,最后允许正常用户操作。在这个过程结束时,PCRs 将填充一系列哈希值。

这些寄存器的值代表您系统的可信度量。现在,假设恶意软件已经感染了您的计算机并修改了启动过程。在下次启动时,至少一个 PCR 的值与之前记录的值有显著不同。PCRs 使得可以对启动过程进行测量,从而提供关于启动过程的断言。

有几个与 TPM 保护启动过程相关的术语。如果 PCR 值与已知配置不匹配,安全启动将停止启动过程。经过认证的启动只是测量启动过程,并允许远程方对启动过程的来源进行断言。受信启动指的是同时使用经过认证和安全启动的系统。

加密数据到一个 PCR 状态

TPM 支持另一个建立在 PCR 状态之上的功能。如前所述,TPM 可以执行 RSA 加密。然而,TPM 还可以将 PCR 状态与加密结合在一起,这个过程称为封存。一旦数据被封存到 PCR 值,只有当 PCR 与加密时相同的值匹配时,才能解密数据。

这将如何帮助我们保护 GPG 密钥?我们将 GPG 密钥加密到已知的 PCR 状态。我们将使用从连接到 CryptoCape 的键盘输入的数字代码作为这个 PCR 状态的输入。当 TPM 解密 GPG 私钥时,它将像通常一样可供 GPG 使用。虽然 GPG 私钥已经受到密码短语的保护,但 TPM 在静止时提供额外的密钥保护。密码短语仍然可能被键盘记录器捕获,但在 BBB 启动并连接 CryptoCape 并直接输入代码之前,我们的密钥将不可用。

该系统还有助于防止对数字代码的离线攻击。一旦使用正确的代码扩展了 PCR 值,就可以解锁数据。但是,如果输入错误的代码,PCR 值将不正确,若该 PCR 是不可重置的 PCR 之一,唯一的重置方法是重启。

添加键盘

我们需要一种方法将此代码输入到 BBB 中。此代码用于填充 TPM 的 PCR 之一,该 PCR 将用于密封 GPG 密钥。这个键盘将连接到 CryptoCape 上的 ATmega328p。虽然 BBB 完全能够处理键盘的 I/O,但通过使用 ATmega328p,我们可以充分利用代码重用。对于 SparkFun 目录中的大多数硬件产品,至少有一个非官方的 Arduino 库。如果这些组件在 SparkFun 上没有,你应该能够从产品描述中找到类似的部件。就键盘而言,有一个官方库。该项目的硬件列在下表中:

设备 SparkFun 编号
CryptoCape DEV-12773
键盘 COM-08653
F/F 跳线 PRT-08430
公头断开连接器 PRT-00116

要构建这个 Arduino 库,你首先需要从 Arduino Playground 网站安装Keypad库:playground.arduino.cc/code/Keypad。然后从 GitHub 克隆以下仓库:

git clone https://github.com/jbdatko/beagle-bone-for-secret-agents.git

ch4代码文件夹中,你会找到keypad.ino源代码和已编译好的 hex 文件,准备加载到 328p 中。从第三章,通过 CryptoCape 添加硬件安全,记住可以通过以下命令将编译好的草图上传到 ATmega328p,只要确保安装了程序跳线:

sudo ./upload.sh keypad_cryptocape.cpp.hex

该程序将 328p 连接到 I2C 总线的十六进制地址 0x42。它会等待从 I2C 主设备——BBB 接收数据,然后从键盘收集五位数字代码。你有十秒钟的时间输入五位数字代码,计时器一旦 CryptoCape LED 亮起就开始。每按下一次键,LED 会瞬间闪烁。收集完五个字符后,LED 会熄灭。

要将键盘连接到 CryptoCape,你首先需要将 0.1"的公头引脚焊接到键盘上。同时,你还需要将 0.1"的公头引脚焊接到 CryptoCape ATmega328p 的焊盘上。安装好引脚后,你需要使用跳线将键盘连接到 CryptoCape。请注意,键盘有九个引脚,但只有七个会用到。将第一个引脚(最靠近*字符的引脚)视为引脚 0。按以下表格连接跳线:

键盘引脚 Arduino 数字引脚
3 D2
1 D3
5 D4
2 D5
7 D6
6 D7
4 D8

将键盘连接到 CryptoCape 后,应该看起来如下图所示:

添加键盘

注意

图像中显示的情况是逻辑供应的镀钢机箱。您可以在他们的网站上找到这些信息:www.logicsupply.com/components/beaglebone/boards-cases-kits/bb100-orange/

现在,我们需要一些软件,它将启动 ATmega328p 上的代码收集过程。请记住,软件需要收集代码,然后扩展 PCR。在前面列出的存储库中有一个文件,keypad.c,它正是这样做的。要构建此程序,您需要开源 TCG 软件堆栈的开发包:

sudo apt-get install libtspi-dev

然后,您应该能够使用以下命令编译程序:

gcc keypad.c -o getgpgpin -ltspi

拥有 TPM 的所有权

在使用 TPM 之前,我们必须首先拥有它。拥有 TPM 会为维护操作建立一个所有者密码和一个 TPM 内部的根密钥之一,即存储根密钥SRK)(发音为shark)。您可以将管理员密码设置为任何密码,但是为了与传统软件一起使用,您会想将 SRK 设置为二十个零的众所周知的密码。如果您想要设置一个唯一的 SRK 密码,但是用于控制 TPM 的 TrouSerS 软件包括一个命令行参数,用于将密码设置为其众所周知的值。首先安装tpm-tools

sudo apt-get install tpm-tools

然后,您应该重新启动带有 CryptoCape 连接的 BBB。这将确保 TPM 内核驱动程序和相关软件正确加载。要检查一切是否正常工作,请发出以下命令:

dmesg | grep TPM

应返回:

[    5.370109] tpm_i2c_atmel 1-0029: Issuing TPM_STARTUP

然后,通过发出以下命令检查守护程序:

ps aux | grep tcsd

此命令应返回类似于以下内容:

tss  799  0.0  0.1  11492   980 ?  Ss Jun08 0:00 /usr/sbin/tcsd

然后,您可以按以下方式拥有 TPM:

tpm_takeownership -z -l debug

您将被提示输入所有者密码。 -z 选项将 SRK 设置为众所周知的密码短语。回应应为:

Tspi_Context_Create success
Enter owner password:
Confirm password:
Tspi_Context_Connect success
Tspi_Context_GetTpmObject success
Tspi_GetPolicyObject success
Tspi_Policy_SetSecret success
Tspi_Context_CreateObject success
Tspi_GetPolicyObject success
Tspi_Policy_SetSecret success
Tspi_TPM_TakeOwnership success
tpm_takeownership succeeded
Tspi_Context_CloseObject success
Tspi_Context_FreeMemory success
Tspi_Context_Close success

现在您已经准备好使用 TPM。

注意

如果您有 CryptoCape v02,则需要执行一些额外步骤。版本号位于板的底层,在 P8 标头上方,靠近开源硬件标志的图标上方,看起来像一个齿轮。此修订版上的 TPM 以合规模式发货,这意味着加载在其上的密钥是测试密钥。这有助于在制造过程中测试 TPM,但需要最终用户更改密钥。有关详细信息,请参阅页面cryptotronix.com/cryptocape-tpm/

扩展 PCR

我们需要扩展一个 PCR 以便加密我们的 GPG 密钥。我们将随意选择 PCR 号码 9。首先让我们查看 PCR 状态,以确保它是空白的:

cat /sys/class/misc/tpm0/device/pcrs | grep PCR-09

这应返回 PCR 的当前状态,在不使用安全启动的情况下是:

PCR-09:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

现在,从以下部分运行getgpgpin程序。你应该会看到 CryptoCape 上的 LED 灯变为绿色,并且你有 10 秒钟的时间输入一个五位数字的 PIN 码。每次按下一个键时,LED 灯应该会闪烁,当输入完五个数字时,LED 灯会熄灭。10 秒钟后,getgpgpin程序将悄无声息地退出。如果你在编译程序时启用了#define DEBUG并设置为1,你应该会看到如下信息:

54321
(Line 53, extend_pcr)  Create a Context
 returned 0x00000000\. Success.
(Line 55, extend_pcr)  Connect to TPM
 returned 0x00000000\. Success.
(Line 59, extend_pcr)  GetTPM Handle
 returned 0x00000000\. Success.
(Line 62, extend_pcr)  Owner Policy
 returned 0x00000000\. Success.
36987(Line 73, extend_pcr)  extend
 returned 0x00000000\. Success.

现在,再次检查你的 PCR 状态:

cat /sys/class/misc/tpm0/device/pcrs | grep PCR-09

你现在应该有一个填充的 PCR9:

PCR-09:2B 1E 41 10 EB A0 91 9E B4 89 0E 04 83 0B 70 C5 C2 AA 23 44

你只能输入代码一次。如果你再次尝试,程序将使用现在错误的 PCR 状态作为输入,再次扩展 PCR9。现在,让我们封存我们的 GPG 秘密密钥环:

tpm_sealdata -p 9 -i secring.gpg -o secring.gpg.tpm -z -l debug

如果你愿意,可以删除-l debug,命令将悄无声息地完成。现在让我们测试解密:

tpm_unsealdata -i secring.gpg.tpm -o deleteme -z

如果成功,它应该悄无声息地完成。你现在可以删除临时文件deleteme和原始的secring.gpg。你做了加密备份对吧?你可能想要以更安全的方式删除这个文件。安全删除工具srm可以做到这一点,它会在删除之前多次覆盖文件。要安装它,可以使用以下命令:

sudo apt-get install secure-delete

然后像使用rm一样使用它。

注意

Bunnie Huang 和 Sean Cross(也被称为 xobs)在第 30 届混沌通信大会30C3)上展示了一场关于破解 SD 卡的讲座。你的 SD 卡或 eMMC 包含一个小型微控制器,用于管理附加的闪存。这款微控制器非常适合充当中间人攻击者,并操控你存储在设备上的数据。例如,这个微控制器可能会保存你数据的备份,因为它向你的计算机报告的存储容量是 8GB,但实际上它包含的是 16GB 的闪存芯片。更多信息可以在 Bunnie 的博客上找到,www.bunniestudios.com/blog/?p=3554

启动时解锁你的密钥

最后,我们需要自动化这个过程。当 BBB 启动时,我们希望它收集代码,扩展 PCR,并解锁 GPG 密钥,以便它们可以准备使用。我们将制作一个init.d脚本来处理这个过程,但我们仍然需要处理 GPG 密钥。我们不希望解锁的 GPG 密钥留在磁盘上,即使它已通过密码保护。相反,我们将把 GPG 密钥保存在一个ramfs中,它永远不会触及持久存储。

要创建ramfs,请将以下内容添加到/etc/fstab

ramfs    /mnt/ramdisk ramfs nodev,nosuid,noexec,nodiratime,size=1M,uid=1000,gid=1002   0 0

确保将你的 uid 和 gid 替换为适合你用户的值。你可以通过运行id命令来获取这些值。可以选择重启或运行mount -a来重新加载fstab。由于 GPG 期望secring.gpg文件位于~/.gnupg/secring.gpg,我们将创建一个从该位置到 ramdisk 的链接。创建以下符号链接:

ln -s /mnt/ramdisk/secring.gpg ~/.gnupg/secring.gpg

现在,我们需要一个在启动时运行的脚本。在beagle-bone-for-secret-agents/ch4仓库中,有一个名为tpm_gpg的脚本,您可以将其复制到/etc/init.d/。此脚本期望getgpgpin位于/usr/local/bin,并且您的secring.gpg文件应该放在正常的位置。根据需要进行编辑。要注册此脚本,请以 root 身份运行:

update-rc.d tpm_gpg defaults

在脚本已经就绪、虚拟磁盘设置为启动时挂载、ATmega 已编程以收集代码且硬件已连接的情况下,再次重启设备。注意观察 CryptoCape LED 灯是否亮起,输入您的 PIN 码,然后重新登录到 BBB。如果您的 GPG 密钥位于/mnt/ramdisk,恭喜您,您刚刚使用 TPM 来保护您的 GPG 密钥!由于符号链接的存在,所有与 GPG 相关的程序将像往常一样使用这些密钥。如果没有,请重新编译keypad.c,将调试模式设置为1,确保一切正常运行。

注意

虽然 ramfs 旨在确保仍然通过密码保护的 GPG 密钥在断电后被销毁,但过去有研究人员从 RAM 中恢复了密钥。请参考citp.princeton.edu/research/memory/上的冷启动攻击。

威胁模型的迭代

威胁建模和系统设计是一个迭代过程。本章中我们构建的系统是一个良好的起点,但它仍然可以改进。我们在本章开始时识别出一个问题,那就是我们仍然需要在可能已被攻破的计算机上输入 GPG 密码。键盘上的代码输入目前仅在 BBB 关闭电源时保护 GPG 密钥。如果一个不知情的攻击者启动 BBB,它也可以保护密钥,因为在 10 秒的时间窗口后,PCR 将不再具有正确的值。为了防止密钥记录攻击,我们希望能够直接在 BBB 上输入密码短语。

有一款名为gpg-agent的软件,它管理每个登录会话的密码短语。它可以支持不同类型的PIN 码输入程序。例如,一个 PIN 码输入程序是基于 X-Windows 的,另一个则支持命令行接口。您当然可以创建一个支持自定义硬件的 PIN 码输入程序。然而,当您创建这个自定义 PIN 码输入程序时,您需要考虑密码短语的强度问题,如果仅由数字组成,可能会导致 GPG 密钥的安全性降低。这展示了随着新特性的加入,我们需要重新评估威胁模型,以确保最初的假设仍然有效。

此外,您可能还想考虑为您的项目添加一个外壳。您所在的黑客空间可以帮助您制作一个专业外观的外壳。如果您想要便宜一点的选择,可以找到一个小型半透明容器,并按以下图示切割出键盘和连接器的空间:

威胁模型的迭代

总结

在本章中,你学习了如何通过 GPG 来保护电子邮件的机密性。我们为我们的系统创建了一个威胁模型,并展示了如何通过这个分析帮助我们理解设计的能力和局限性。最后,我们成功构建了一个 BBB GPG 协处理器,使用 TPM 来帮助保护静态的 GPG 密钥,并获得了更多将微控制器与嵌入式 Linux 平台结合的实践。

在下一章中,我们将研究另一种用于保护实时聊天的主要隐私增强技术。你将了解 Off-the-Record (OTR) 的独特加密特性,以及如何在你的 BBB 主机上托管的 Internet Relay Chat 网关上使用 OTR。

第五章:离线聊天

在本章中,我们将使用BeagleBone BlackBBB)来保护您在线生活的最后堡垒:实时聊天。通过 GPG 保护您的电子邮件,使用 Tor 保护您的浏览,我们将使用名为Off-the-RecordOTR)的软件来保护即时消息聊天。OTR 解决了 PGP 威胁模型中的一个弱点,我们将在构建项目之前概述 OTR 的设计目标。我们还将整合所有聊天网络,通过 Internet Relay Chat 接口进行管理,该接口将运行在您的 BBB 上。尽管这个项目不需要除 BBB 以外的任何额外硬件,但加密概念和网络交互比前几章稍微更具挑战性。在本章和本书结束时,您将接触并熟悉三种最有效的在线隐私保护工具。

在这一章中,您将执行以下操作:

  • 学习 PGP 和 OTR 之间加密设计的区别

  • 使用 BitlBee 运行 IRC 聊天网关

  • 将您的 IRC 网络与 IRC 中继器 ZNC 结合使用

  • 在 BitlBee 和 ZNC 上设置并使用 OTR 聊天

离线通信背景

在我们研究 OTR 之前,让我们考虑如何加密我们的聊天会话。我们可以使用 GPG 进行聊天。我们需要知道通信对象的公钥,每次输入信息时,它都会加密和/或签名该信息并发送出去。一些聊天网络没有类似电子邮件地址的东西,所以找到并验证公钥可能会比较麻烦。然而,您完全可以想象出一种这样的聊天系统;它是 GPG 与电子邮件的一个稍微同步的版本。

即使解决了那些技术问题,PGP 的设计中仍然存在一个更大的问题。让我们回到我们的朋友 Alice 和 Bob。Alice 和 Bob 已经使用 GPG 进行通信一段时间了。他们使用 GPG 毫无瑕疵,并且始终如一地践行最佳的安全卫生习惯。直到有一天,有人获取了 Bob 的私钥。现在,这种情况可能有多种方式发生。尽管 Bob 有强烈的意志力,也许他就是无法抗拒点击Watch cuTe kittys [sic]链接,导致恶意软件感染了他的计算机。也许有人偷走了他定制的 GPG 硬件令牌,并猜出了他的 GPG 密码。无论 Bob 的私钥是如何泄露的,重要的是现在别人已经拥有了它。

Bob,作为一名警觉的 GPG 用户,立即撤销了他的密钥,通知大家该密钥已经被泄露。这警告其他人不要再使用该密钥,并且在未来的通信中应使用新的密钥。但我们不能忘记 Alice 和她与 Bob 之间的许多通信。那 Alice 怎么办?这个攻击者,拥有 Bob 的私钥,可以解密 Alice 和 Bob 之间的所有过往通信。所有内容。突然间,他们的对话似乎不再那么私密,正如 OTR 设计者 Ian Goldberg 所提到的关于 GPG 通信隐私的问题。

引入 Off-the-Record 通信

虽然 GPG 有其作用,但如果你担心失去对私钥的控制,那么你可能需要考虑其他工具。一个专门考虑到这一威胁的工具叫做Off-the-RecordOTR),最初发布在论文《Off-the-Record Communication, or, Why Not To Use PGP》(Borisov 2004)中。OTR 包含一些与 PGP 不同的加密功能和设计目标。例如,OTR 被设计为包含完美前向保密性,确保会话密钥(即加密通信流量的密钥)在长期身份密钥泄露的情况下不会被重新推导出来。同时,OTR 只在初始认证步骤中使用数字签名;单个消息不会被签名。

会话密钥通过Diffie-Hellman 密钥交换协议由双方独立推导。Diffie-Hellman 协议有助于解决密钥分发问题。Alice 和 Bob 想要用对称加密算法保护他们的通信,但他们都需要相同的密钥。通过使用 Diffie-Hellman,他们可以在不安全的信道上独立推导出共享密钥,而无需将密钥暴露给第三方。OTR 使用 Diffie-Hellman 密钥交换中的非对称加密,使得双方能够在计数模式下推导出共享的 AES 密钥。AES 计数模式AES-CTR)使用 AES 作为流密码,本节稍后会讨论其重要性。

注意

Khan Academy 网站上提供了 Diffie-Hellman 密钥交换的简化版两分钟描述,链接:www.khanacademy.org/computing/computer-science/cryptography/modern-crypt/v/diffie-hellman-key-exchange--part-2

OTR 的另一个与 PGP 不同的特点是,OTR 被设计为具有信息否认性,即能够否认消息的作者身份或有效性。PGP 则是为了不可否认性而设计的,它通过你的数字签名提供一个证明,证明你确实创建了那条消息。然而,在 OTR 中,Alice 和 Bob 都无法证明对方或自己创建了某一特定的消息。这个功能的细节稍微有些技术性,但我们将提供一个高级总结,因为这是消息认证码MACs)的巧妙应用。

MAC 是一个附加在数据块上的小标签。标签由发送方计算,并发送给接收方,接收方重新计算该值以检查数据在传输过程中是否被篡改,这验证了数据的完整性。此外,MAC 涉及到双方的共享密钥。因此,Alice 和 Bob 拥有相同的 MAC 密钥。因此,当 Bob 验证消息上的 MAC 时,他可以确定发送者和他自己拥有相同的 MAC 密钥。在 OTR 中,由于 Alice 和 Bob 使用相同的 MAC 密钥应用于每条独立的消息,因此其中任何一方都可以创建消息来模仿对方。因此,他们都无法证明自己或通信伙伴确实创建了某条消息。这就提供了 OTR 中的否认功能。

OTR 设计者还加入了一个加密系统中额外的不常规特性:可伪造性。OTR 的设计使得在消息解密时,能够轻松地改变加密文本,从而产生一个有意义的输出。这之所以能实现,是因为设计者选择了一种易于变动的加密方案,使用的是流密码;在 OTR 中,它使用的是 128 位密钥长度的 AES-CTR。流密码的核心是生成密钥流,但实际的加密通常是通过对明文应用异或操作来进行的。解密则是通过对相同的密钥流应用相同的异或运算来进行的。一个能够猜测消息明文的攻击者,可以修改加密文本,从而生成一个不同的明文消息,且长度相同。因此,消息可以被伪造。

注意

异或(Exclusive-OR,或称 XOR)由于其逻辑定义,可以用于加密和解密:当且仅当 A 或 B 为真时,A 与 B 的 XOR 为真。数字消息被表示为二进制流。消息的明文与密钥流进行 XOR 操作以生成密文,当密文与相同的密钥流再次进行 XOR 操作时,明文会被恢复。例如,如果明文位为 1,且密钥流位为 1,那么密文将返回 0。当密文位 0 与密钥流 1 进行 XOR 操作时,明文位 1 会被恢复。可参考可汗学院关于 XOR 在加密中的交互式视觉系列:www.khanacademy.org/computing/computer-science/cryptography/ciphers/a/xor-bitwise-operation

艾丽丝和鲍勃仍然能够防止第三方篡改他们的即时对话,因为第三方并不知道 MAC 密钥。然而,OTR 加入了另一个复杂因素。当 OTR 重新生成新的 MAC 密钥时,它会发布先前对话的 MAC 密钥。发布 MAC 密钥意味着任何被动监听对话的人都可以更改密文,从而操控过去消息的明文内容。这为对话增加了另一层否认性,因为任何记录下来的对话都可以被轻松操控,并且看起来可能是合法的。艾丽丝和鲍勃只会发布旧的MAC 密钥,当前正在使用的密钥会被保密,直到协议要求他们重新密钥。

关于 OTR 的可用性

设计加密系统并不足以确保它们的采纳;它们还需要是稳健且易于使用的。OTR 不仅作为学术论文发布,而且还提供了一个库。OTR 被设计成可以在任何现有的即时消息IM)协议上工作,并与任何能够集成该库或插件的客户端兼容。你最喜欢的 IRC 客户端可能已经有一个插件或库,可以轻松集成 OTR。在本章中,我们将使用在我们将要检查的两个 IRC 应用程序中内置的 OTR 插件。

OTR 的设计,特别是完美的前向保密性和否认性功能,启发了对其他协议的衍生,除了实时聊天之外。例如,Open WhisperSystems 为移动设备开发的 TextSecure 应用程序在短信和其他异步即时消息通道上使用了类似 OTR 的协议。

此外,OTR(即时消息加密协议)与 Tor 和 GPG 一样,得到了美国非盈利组织“新闻自由基金会”的推荐,该基金会支持并捍卫公共利益新闻。该组织提供了关于如何使用这些工具的教育和教程。虽然这些工具最初是为保护记者的消息来源而设计的,正如格伦·格林沃尔德和劳拉·波伊特拉斯所使用的(格林沃尔德 2014 年),但该信息对任何使用隐私增强技术的用户都适用。

使用 BeagleBone 来保护你的在线聊天

在本章中,我们将使用 BBB 在各种 IRC 网关上运行 OTR。BBB 非常适合充当您的个人 IRC 网关。它可以轻松处理 IRC 连接,并充当一个始终在线的服务器,而不会显著增加您的电费。虽然 IRC 看起来可能有些过时,但它提供了一种客户端独立且模块化的界面。我们最终将构建一个完整的 IRC 解决方案,管理您的所有 IRC 网络。首先,我们将介绍软件 BitlBee,它将您的聊天网络,如 Google Talk 和 Jabber,合并到 IRC 中。

在 BeagleBone 上安装 BitlBee

BitlBee 是一个IRC 到其他聊天网络的网关。这意味着,如果您使用现有的聊天程序,如 Google Talk、Jabber、Twitter、AIM 或 Facebook,您可以通过 IRC 使用 BitlBee 进行这些协议的聊天。当非 IRC 用户听说 BitlBee 时,第一个问题是,为什么要这样做? 而 IRC 用户则会兴奋地响应。主要的好处是,通过使用 IRC,您可以通过相同的客户端软件与 Google Talk 上的朋友聊天,就像在 IRC 上聊天一样。这减少了您需要学习的程序数量。虽然乍一看这可能并不令人印象深刻,但请考虑到每个程序通常都有自己独特的快捷键和界面。此外,每个厂商经常更改应用程序的外观,迫使您重新学习如何使用该工具。另一方面,IRC 客户端的用户界面相对简单,而且 IRC 交互也相对标准化。

BitlBee 的另一个用途是作为您聊天网络的代理服务器。您的聊天网络身份是持久的,但您可以随时附加或分离您的客户端。重新连接时,您可以查看错过的即时消息。这可以防止您在一个客户端(例如手机)收到消息,但由于之后在计算机上登录聊天网络而错过消息。此外,BitlBee 支持 OTR,因此我们可以使用 BitlBee 管理我们的 OTR 保护的对话。

BitlBee 和 OTR 插件可以通过 Debian 软件库获取,因此安装过程非常简单:

sudo apt-get install bitlbee bitlbee-plugin-otr

安装过程会自动启动 BitlBee 守护进程,运行在端口 6667 上,这是默认的 IRC 端口。此时,您可以使用您喜欢的 IRC 客户端连接到 BitlBee 服务器。这是将 BitlBee 在本地网络上运行的一个优势,它始终在线,并可以从任何其他内部计算机或智能手机访问。由于 BitlBee 正在管理您的账户,它不会表现得像是您在不断上线和下线。

在这一章中,我们将使用的 IRC 客户端是 ERC,它是 Emacs 的 IRC 客户端。ERC 是一个运行在 Emacs 实例内的客户端,相比传统的 IRC 客户端有几个优点。首先,也是最重要的,如果你已经在使用 Emacs,那么你可以通过使用 Emacs 来完成其他任务,提高效率。不仅省去了在任务切换时的认知摩擦,而且 Emacs 的布局和键盘命令你已经非常熟悉。此外,ERC 和 Emacs 一样,非常模块化和灵活。当然,它是一个自由软件程序,而且有许多现有的模块可供使用,从昵称高亮到自动离线等功能。最后,它自然是跨平台的;任何能够运行 Emacs 的平台都能运行 ERC。

提示

对于 Emacs 用户来说,在 Emacs 中运行 IRC 客户端是合情合理的。毕竟,忠实的 Emacs 用户认为 Emacs 是最具可移植性的操作系统。如果你坚持不使用 Emacs,irssi 是一个备受尊敬的 IRC 客户端替代品:www.irssi.org/

要通过 ERC 连接到你的 BBB BitlBee 服务器,在 Emacs 中输入 M-x erc。系统会提示你输入 IP 地址。然后按回车键选择默认端口号,再次按回车键输入密码。你应该加入 &bitlbee 频道,在这个频道中你将会和一个其他用户(root)一起交流。下面的截图展示了 root 如何与你在 &bitlbee 频道中互动,同时也展示了 Emacs 内部的 IRC 客户端界面:

在 BeagleBone 上安装 BitlBee

创建 BitlBee 账户

第一个任务是创建一个账户在你的 BitlBee 服务器上。这是一个新的账户,用于管理你的 BitlBee 连接。以后我们可以用这个账户重新登录以加载我们的配置。否则,每次连接时都需要重复以下步骤。由于 BitlBee 是一个 IRC 网关,所有对 BitlBee 的命令都带有 IRC 的感觉。注册可以通过在 &bitlbee 频道中输入以下命令来完成:

register <password>

你的密码会被回显出来,root 用户应该回复:

Account successfully created

在使用 BitlBee 时,养成经常保存的习惯非常重要。否则,所做的更改不会持久保存。保存操作很简单,只需在 &bitlbee 频道中输入 save 即可。现在就保存吧。

将 Google Talk 账户添加到 BitlBee

仅仅拥有一个 BitlBee 账户并不太有用。我们需要将你的其他社交媒体账户添加到 BitlBee 才能使其发挥作用。我们将添加的第一个账户是 Google Talk 账户。BitlBee 支持其他聊天服务,如 Yahoo、AIM、XMPP、MSN、Facebook 和 Twitter,因此你不一定非要使用 Google 账户。完整列表请参考 wiki.bitlbee.org/FrontPage

不幸的是,2013 年 5 月,Google 宣布推出了新的通讯产品 Hangouts,它不支持 XMPP(这是 IETF 标准),而是使用了一个专有协议。具体来说,Google Hangout 不支持与 XMPP 的服务器到服务器联邦支持。如果你有一个独立的 XMPP 服务器,或者在 Jabber.org 或自由软件基金会的服务器上有账户,将不再能够与 Google Hangout 用户进行通信。你仍然可以使用完全支持 XMPP 的 Google Talk,但尚不清楚 Google 何时会停止支持 Google Talk。

注意

如果你没有 Google 账户,出于有效的隐私考虑,你应该阅读 Benjamin Mako Hill 的 Google has most of my e-mail because it has all of yours mako.cc/copyrighteous/google-has-most-of-my-email-because-it-has-all-of-yours。作者没有使用 Gmail,但超过 50% 的电子邮件通信都去了 Google 的服务器。除非你加密了邮件,否则 Google 服务器会保存你的通信内容。

要在 BitlBee 中添加你的 Gmail 账户,请在 &bitlbee 频道输入以下内容:

account add jabber you@gmail.com

BitlBee 根账户会回复如下内容:

<root> Account successfully added with tag gtalk
<root> You can now use the /OPER command to enter the password
<root> Alternatively, enable OAuth if the account supports it: account gtalk set oauth on

我们将继续启用 OAuth

acc gtalk set oauth on

注意

OAuth 是一个授权框架,它允许第三方访问其他 Web 服务,而不需要第三方应用知道你的凭证,例如密码。为第三方应用提供了有限的使用访问令牌,以限制对托管服务的访问。更多信息可以参考 OAuth 官网 oauth.net

由于大多数人现在都有 Google+ 账户,我们需要将昵称的格式设置为全名。否则,我们会看到随机字符串作为昵称:

account gtalk set nick_format %full_name

最后,使用以下命令启用账户:

acc gtalk on

BitlBee 会向一个 URL 发送私信,用于你的 OAuth 登录:

<jabber_oauth> Open this URL in your browser to authenticate:
https://...
<jabber_oauth> Respond to this message with the returned authorization token.

点击链接将提示你接受 BitlBee 的权限,应该会显示如下截图。点击 接受 后,你将收到一个代码,然后可以将其粘贴回私信窗口。

将 Google Talk 账户添加到 BitlBee

完成后,回到 &bitlbee 窗口,你应该会看到以下信息,表示你正在登录 GTalk:

<root> jabber - Logging in: Starting OAuth authentication
<root> jabber - Logging in: Requesting OAuth access token
<root> jabber - Logging in: Connecting
<root> jabber - Logging in: Connected to server, logging in
<root> jabber - Logging in: Converting stream to TLS
<root> jabber - Logging in: Connected to server, logging in
<root> jabber - Logging in: Authentication finished
<root> jabber - Logging in: Server changed session resource string to `BitlBee301D65C5'
<root> jabber - Logging in: Authenticated, requesting buddy list
<root> jabber - Logging in: Logged in

别忘了保存!

将 Jabber 账户添加到 BitlBee

如果你有一个 Jabber (XMPP) 账户,你可以继续将其添加到 BitlBee。语法与之前的示例类似:

account add jabber username@jabber.org password

根用户应返回类似如下内容:

Account successfully added with tag jabber

用以下命令启用账户:

acc jabber on

现在,当你输入 account list 时,应该能看到两个账户。最后,记得保存你的数据!

注意

你还可以添加 Twitter 账户,并通过 IRC 发推。不过,你需要 BitlBee 版本 3.2.1 或更高版本;否则,当你尝试连接 Twitter 时会遇到 SSL 错误。

加入自由软件基金会成为会员的众多好处之一是使用 FSF 的 XMPP 服务器。通过联合,用户可以在 member.fsf.org 服务器上通过您的 FSF 用户名与您联系。同样,自由软件基金会欧洲的成员也享有 XMPP 特权。欲了解更多信息,请访问各自的 FSF 网站:www.fsf.org/associate/benefitsfsfe.org/fellowship/index.en.html

向 BitlBee 服务器添加 OTR

我们已经为 BitlBee 安装了 OTR 插件,因此它已准备好支持 OTR。在加密对话之前,我们必须先生成一对密钥。对于您在 BitlBee 注册的每个账户,您都可以拥有唯一的密钥对。查看您的账户列表,然后使用以下命令生成 OTR 密钥:

otr keygen 0

几秒钟后,root 将通知您 OTR 密钥生成完成。在任何时候,您都可以使用以下命令查看您的 OTR 密钥信息:

otr info

这将为每个账户提供密钥指纹。您现在已准备好进行加密聊天。

在 BitlBee 中管理联系人

您的联系人或好友列表应在 BitlBee 验证您的账户时已经可用。您可以在 &bitlbee 窗口中使用 blist 命令查看您的好友列表。此表将显示昵称、特定账户的用户名以及每个联系人的状态。BitlBee 会将用户名转换为 IRC 友好的名称,这些名称在第一列是 "nicks"。当多人在不同账户上使用相同用户名时,这可能会导致混淆。BitlBee 允许您重命名昵称来帮助管理此问题。例如,BitlBee 会在重复昵称后附加下划线,但您可以使用以下命令对其进行重命名:

rename gabriel_ice_ gabriel_ice_jabber

添加联系人也可以使用熟悉的命令语法:

add 0 gabriel.ice@gmail.com

只需记得查看您的账户列表,以了解使用哪个账户号码。

与 BitlBee 聊天

聊天可以直接在&bitlbee频道进行。使用 IRC 语法指定昵称,BitlBee 会将其定向到适当的服务。一个基本的聊天会话,maxinegabriel_ice_japper 之间的聊天,看起来会是这样的:

<maxine> gabriel_ice_jabber: when can we meet to talk about DeepArcher?
<gabriel_ice_jabber> maxine: Tuesday at 10.

或者,您可以使用 /query 命令打开一个新窗口,直接与用户聊天。通过这种方式,您无需每次都指定用户的昵称,因为您和您的好友在一个私人聊天中。

提示

对于 IRC 新手,以下教程是一个很好的入门:www.irchelp.org/irchelp/irctutorial.html。对于寻找 ERC 特定帮助的用户,Emacs Wiki 提供了一些资源:www.emacswiki.org/emacs/ErcBasics

在 BitlBee 中使用 OTR 进行聊天

要启动 OTR 保护的聊天,请输入:

otr connect gabriel_ice_jabber

尽管我们此时已经连接并且聊天会话会被加密,但我们仍然面临一个问题,那就是如何真正知道我们在与谁聊天?这个问题看起来可能很抽象,但它是一个重要问题。通信协议常见的一种攻击是中间人攻击MITM)。MITM 攻击的经典设置涉及两个希望通信的双方——艾丽斯和鲍勃,以及恶意干扰者马洛里。艾丽斯与鲍勃发起连接,但被马洛里篡改,鲍勃与艾丽斯之间的连接也同样被篡改。艾丽斯认为自己在与鲍勃交谈,但实际上她在与马洛里交谈,马洛里把消息转发给鲍勃,反之亦然。此时,马洛里可以随意引导和操控对话。

为了防止这种情况,我们需要验证接收方的身份。在 OTR 中,你可以验证你伙伴的密钥指纹。这要求你们事先交换过 OTR 指纹,并且可能不太方便随时携带你的 OTR 指纹。另一种机制是使用社会主义百万富翁问题来验证你的朋友。社会主义百万富翁问题将在以下小节中详细讨论,现在可以把它当作一个问答游戏,答案只有与你通信的人才知道。

要在 BitlBee 中发起协议,请输入类似以下内容:

otr smpq gabriel_ice_jabber "What beer did I order last night, one word, lowercase?" ipa

假设昨晚你和加布里埃尔·艾斯一起吃晚餐,他应该知道你点了什么类型的啤酒。在提问时,最好给出如何输入问题的说明。否则,可能会导致不正确的回答,并可能让你的伙伴困惑,尽管喝了几杯酒,他仍然清楚地记得你喝的是 IPA。如果你的伙伴正确回答,你应该会看到:

<root> smp: initiating with gabriel_ice_jabber_...
<root> smp gabriel_ice_jabber_: secrets proved equal, fingerprint trusted

这个机制是单向的;加布里埃尔必须首先发起协议,才能完全信任你。这部分交换流程如下所示:

<root> smp: initiated by gabriel_ice_jabber with question: "What did I have for lunch yesterday, one word, lowercase?"
<root> smp: respond with otr smp gabriel_ice_jabber <answer>
<jbd> otr smp gabriel_ice_jabber pizza
<root> smp: responding to gabriel_ice_jabber...
<root> smp gabriel_ice_jabber: correct answer, you are trusted

恭喜!你已成功连接并完成身份验证,现在可以通过 OTR 和 BitlBee 进行聊天了!如果你使用的是 GTalk 并且也通过浏览器登录了 Google,你可能会注意到加密消息在不断传输。你可能会选择退出浏览器中的 GTalk,但为了好玩,如果你仍然登录,你将看到 OTR 消息,它们看起来像这样:

?OTR:AAIDAAAAAAQAAAAFAAAAwBPAdyxNJT7MYxOFBPfmPRCbW3yE6gADfimB7wikaf/r9/DVQ3hZfJXj+c7HSddySk77fJi3csbRIIxKCSXGLO/9cOw7SJ+u10d8D6Wp2scCAi7TzO/YGkZmeGlef3lYUbwaVkH5VoYfLSo+i90McmLrgEfM9kgZuXLtDA1H2f4jWdtBJh1XxdK/GyZBZvTcncMs/e3rRrKpSNZiJq0kijMhIK6N4NRdaNK1URipDJai1d2bnGJ2Pk0rihXc5yzCrgAAAAAAAAACAAAAEUw6xZ+tJrdEG/+yqaiwoDi0Fc9eloiWtIc1UWQ8JTIT3eaKvuMAAAAA.

理解社会主义百万富翁问题

即使是像 OTR 这样的设计精良的协议,也可能存在一些微妙的设计缺陷。对于那些希望在项目中加入加密技术的人,有一句著名的警告,不要自创加密技术,意思是不要自己发明加密技术,因为概率不利于你,且一旦犯错,可能会破坏你的安全性。而且,即便是经验丰富的加密专家也不可能一开始就做对所有事情。幸运的是,发布研究、设计和代码有助于同行评审过程。

针对一些关于 OTR 认证阶段的批评,作者改进了他们的协议(Alexander 2007)。在这篇论文之前,OTR 用户需要通过带外的方式验证 OTR 密钥的指纹。虽然这种方式可行,但由于其不便和扩展性差,存在一个人为因素的缺点,因为你可能需要向你想要进行安全通信的人分发 OTR 密钥。然而,双方可能共享更多关于彼此的亲密知识来验证他们的真实性。问题就变成了,爱丽丝和鲍勃如何在不互相透露的情况下共享某些秘密信息。研究人员发现,这个问题是社会主义百万富翁问题的再表述,其中两个百万富翁想知道他们是否同样富有,但又不能互相透露他们的财富数量。

这个问题背后的数学原理依赖于一种叫做零知识证明的技术。零知识证明允许某人证明一个陈述的正确性,而无需提供关于该陈述的任何额外信息。OTR 的零知识证明的详细信息和证明超出了本书的范围,并在(Alexander 2007)中进行了详细描述。

在 OTR 中使用社会主义百万富翁问题的含义是,爱丽丝可以问鲍勃一个只有鲍勃知道的特定问题。如果马洛里假装成鲍勃,并且爱丽丝选择了一个马洛里不知道答案的好问题,马洛里如果猜错了将无法获得任何额外的信息。例如,爱丽丝问马洛里(假装成鲍勃)她最喜欢的吉他手是谁。鲍勃知道爱丽丝是Who乐队的粉丝,答案自然是皮特·汤申德。马洛里并不知道这个细节,所以她给出了一个令人钦佩但错误的答案——吉米·佩奇。爱丽丝会看到协议失败,并知道鲍勃并非他所表现出来的那个人。但马洛里不会知道关于答案的其他信息,除了吉米·佩奇是不正确的。然而,马洛里已经晚了,因为爱丽丝不再信任她并终止了连接。

使用中继器管理你的 IRC 连接

现在 BitlBee 已经在 BeagleBone 上运行,你可以享受 OTR 保护的即时消息传递,但我们可以改进这个设置。目前,我们是直接通过你的 IRC 客户端连接到 BitlBee。如果你只有一个客户端,这样做没问题。但是,如果你正在用笔记本聊天,然后站起来走开,你可能希望在手机上继续对话。为此,我们需要一个更持久的代理连接。这个问题可以更一般地表述:我们如何保持与所有 IRC 网络(包括 BitlBee)的持久连接。为此,我们需要一个 IRC 中继器(Bouncer)。

IRC 代理服务器充当代理服务器并维持你与 IRC 服务器的连接。这在那些不支持昵称注册且你希望保持昵称的服务器上非常有用。如前面使用案例所述,代理服务器通常支持多个客户端,这将使你在切换设备时能几乎无缝地进行 IRC 对话。由于我们正在使用 BitlBee 作为我们的 IRC 网关,连接到 XMPP 和即时消息网络,我们也可以将 IRC 连接合并,并由代理服务器来管理这一切。

IRC 的现代用途

IRC 发明于 1988 年,它是全球首批实时聊天网络之一。尽管社交网络可能已取代了互联网上许多随意的对话,IRC 仍然占有一席之地。尽管这些对话依然在 IRC 上进行,但有一个群体定期聚集在 IRC 上,他们应该是本书读者感兴趣的:开源开发者。大多数维护良好的开源项目都有一个对应的 IRC 频道,你可以在任何时候寻求帮助。

对于开源项目,两个最大的 IRC 网络是freenodeoftc。实际上,本书中每一个主要的软件和硬件包都有一个对应的 IRC 频道,你可以在其中寻求帮助。使用 IRC 相较于其他媒介有一些优势。对于活跃的频道,在参与对话之前,通常建议并鼓励先潜水。潜水就是被动地观察对话。你可能会,也很可能会,仅仅通过阅读现有对话就学到一些东西。此外,如果你有问题或疑问,IRC 是一个实时聊天,因此你可能能够迅速解决你的问题。它也是一个比公共邮件列表更为非正式的媒介。如果你对在邮件列表上提问有所顾虑,IRC 是一个更合适的提问平台。

注意

在 freenode 上,相关频道包括:#sparkfun,用于一般电子学问题,以及与一些 SparkFun 员工和客户聊天,#beagle,这是 BeagleBone 爱好者的聚集地,#gnupg,用于 GPG 相关问题,和#cryptotronix,这是作者关于开源加密硬件的频道。在 oftc(irc.oftc.net)上,你可以查看#bitlbee频道以获取关于 BitlBee 的帮助,或者#tor讨论 Tor。

IRC,像任何共享的通信媒介一样,拥有一定的网络礼仪,用户期望每个人都遵守这些礼仪。令人惊讶的是,有一份 RFC 定义了网络礼仪的指南(RFC 1855)。这篇文档确实值得一读,但如果你遵循以下建议,应该就没有问题。首先,不要询问是否可以提问。这意味着,在 IRC 频道中不要问是否可以提问。你可以直接提出你的问题。虽然频道中有管理员,但 IRC 通常不遵循举手等待被叫到的方式。其次,不要刷屏。这意味着不要将大量文本粘贴到频道中,因为这会导致所有连接的客户端快速滚动文本,文本很快就会消失在屏幕之外。你可以使用像 Debian 提供的粘贴服务(paste.debian.net/),然后将链接粘贴到 IRC 频道中,同时解释链接中包含的内容。最后,要有耐心。正如前面所说,许多人在 IRC 上背景潜伏,可能不会立刻看到你的问题。根据你提问的时间,等待大约 30 分钟是合理的。在活跃的频道中,你可能会更快得到回应,但不要反复提问同样的问题。

下载并安装 IRC 跳板 ZNC

我们将使用名为 ZNC 的 IRC 跳板软件包。ZNC 是一个维护良好且与时俱进的软件包,像所有优秀的开源软件一样,它也有一个 IRC 频道:#znc,位于 freenode 上。Debian 仓库中的软件包略显陈旧,因此我们将从源代码安装 ZNC。通过执行以下命令下载源代码压缩包:

wget http://znc.in/releases/znc-1.4.tar.gz

我们想培养检查下载软件签名的良好习惯。1.4 版本的签名者是 Alexey Sokolov,他的 GPG 指纹是:D582 3CAC B477 191C AC00 7555 5AE4 20CC 0209 989E。你可以使用以下命令下载他的公钥:

gpg –recv-key  D5823CACB477191CAC0075555AE420CC0209989E

接下来,下载发布版本的签名文件:

wget http://znc.in/releases/znc-1.4.tar.gz.sig

最后,验证下载软件的签名:

gpg --verify znc-1.4.tar.gz.sig znc-1.4.tar.gz
You should see something like the following:
gpg: Signature made Thu 08 May 2014 08:21:40 PM UTC using RSA key ID 0209989E
gpg: Good signature from "Alexey Sokolov <alexey@alexeysokolov.co.cc>"
gpg:                 aka "Alexey Sokolov <ktonibud@gmail.com>"
gpg:                 aka "Alexey Sokolov <alexey@asokolov.org>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: D582 3CAC B477 191C AC00  7555 5AE4 20CC 0209 989E

虽然这个过程增加了一些步骤,但很快就会变成一种第二天性。如果你不执行这些步骤,当有签名文件可用时,你就假设下载的软件就是发布的软件。尽管 TCP 内置了校验和,你在使用wget时会使用它,但这并不能保证文件是正确的,因为存在 MITM 攻击的可能性。无论你的疑虑有多大,验证每次下载的软件都是个好习惯。事实上,一个简单的 bash 脚本可以帮助你,因为标准做法是将.sig附加到文件的末尾:

wgetsig(){
    wget $1
    wget $1.sig
    fn=$(basename $1)
    gpg --verify $fn.sig $fn
}

如果你将该功能添加到你的.bashrc或等效文件中,你只需输入wgetsig <url>来抓取文件、签名,并通过 GPG 进行验证。现在,你可以相信下载的软件就是发布的那个软件,可以开始解压软件包了:

tar -zxvf znc-1.4.tar.gz

要从源代码构建 ZNC,您需要安装以下依赖项:

sudo apt-get install libssl-dev libperl-dev

大多数软件 tar 包都支持configure-make-make install的操作流程,这个也不例外。您可以使用以下命令构建和安装:

cd znc-*
./configure
make
sudo make install

在 BBB 上构建 ZNC 会花费一些时间,因为它还会构建每个 ZNC 模块,所以去享受一些咖啡吧。

配置 ZNC 以管理您的 IRC 连接

在我们配置 ZNC 之前,让我们退后一步,检查我们的系统架构。我们至少有三个不同的硬件部件参与其中:运行您的 IRC 客户端的机器,BBB 以及运行 IRC 服务器的机器。其中一个机器是 BBB,因为它运行 BitlBee IRC 服务器。查看以下部署图:

配置 ZNC 以管理您的 IRC 连接

让我们从 BBB 开始,由中心方块表示。BBB 正在运行两个模块:ZNC 和 BitlBee。ZNC 是多个 IRC 客户端可以连接的模块。ZNC 连接到 BitlBee 模块,后者也是在同一硬件上运行的进程。ZNC 还连接到一个或多个不同的 IRC 服务器。BitlBee 维护与各种 XMPP 或聊天服务器的连接,但由于 BitlBee 本身是 IRC 服务器,您通过 ZNC 连接到它。一旦一切设置好,您只需担心连接到 ZNC。

ZNC 需要一个配置文件,生成配置文件的最简单方法是运行以下命令:

znc --makeconf

这将启动一个交互式命令行界面。您需要创建一个新的 ZNC 用户名,该用户名与任何 BitlBee 或 IRC 系统都没有关联。您还需要决定运行服务的端口号。如果选择私有范围内的端口号,即4915265535,则与其他服务发生冲突的可能性较小。在此示例中,选择了端口50000。ZNC 有许多模块,但您需要启用webadmin模块以便轻松配置 ZNC。最后,请确保启用 SSL。它将生成一个自签名证书,大多数浏览器连接时会抱怨。或者,您可以创建一个完整的公钥基础设施PKI),并向 ZNC 提供服务器证书。

注意

PKI 是一个值得写书的子主题。关于 PKI 复杂性的介绍由 Peter Gutmann 在Everything you Never Wanted to Know about PKI but were Forced to Find Out中有详细记录,链接为www.cs.auckland.ac.nz/~pgut001/pubs/pkitutorial.pdf

示例配置会话如下所示:

[ .. ] Checking for list of available modules...
[ >> ] ok
[ ** ] Building new config
[ ** ]
[ ** ] First let's start with some global settings...
[ ** ]
[ ?? ] What port would you like ZNC to listen on? (1025 to 65535): 50000
[ ?? ] Would you like ZNC to listen using SSL? (yes/no) [no]: yes
[ ?? ] Would you like ZNC to listen using both IPv4 and IPv6? (yes/no) [yes]: yes
[ .. ] Verifying the listener...
[ >> ] ok
[ ** ] Unable to locate pem file: [/home/debian/.znc/znc.pem], creating it
[ .. ] Writing Pem file [/home/debian/.znc/znc.pem]...
[ >> ] ok
[ ** ]
[ ** ] -- Global Modules --
[ ** ]
[ ** ] +-----------+----------------------------------------------------------+
[ ** ] | Name      | Description 
[ ** ] +-----------+---------------------------------------+ 
[ ** ] | partyline | Internal channels and queries for users 
 connected to znc |
[ ** ] | webadmin  | Web based administration module       |
[ ** ] +-----------+---------------------------------------+
[ ** ] And 10 other (uncommon) modules. You can enable those
 later.
[ ** ]
[ ?? ] Load global module <partyline>? (yes/no) [no]: yes
[ ?? ] Load global module <webadmin>? (yes/no) [no]: yes
[ ** ]
[ ** ] Now we need to set up a user...
[ ** ]
[ ?? ] Username (AlphaNumeric): zncbeagle
[ ?? ] Enter Password:
[ ?? ] Confirm Password:
[ ?? ] Would you like this user to be an admin? (yes/no) [yes]:
 yes
[ ?? ] Nick [zncbeagle]:
[ ?? ] Alt Nick [zncbeagle_]:
[ ?? ] Ident [zncbeagle]:
[ ?? ] Real Name [Got ZNC?]: ZNC Admin
[ ?? ] Bind Host (optional):
[ ?? ] Number of lines to buffer per channel [50]:
[ ?? ] Would you like to clear channel buffers after replay?
 (yes/no) [yes]:
[ ?? ] Default channel modes [+stn]:
[ ** ]
[ ** ] -- User Modules --
[ ** ]
[ ** ] +--------------+------------------------------------------+
[ ** ] | Name         | Description                              |
[ ** ] +--------------+------------------------------------------+
[ ** ] | chansaver    | Keep config up-to-date when user         |
 |              | joins/parts                              |
[ ** ] | controlpanel | Dynamic configuration through IRC. Allows editing only yourself if you're not ZNC admin. |
[ ** ] | perform      | Keeps a list of commands to be executed when ZNC connects to IRC.                        |
[ ** ] | webadmin     | Web based administration module                                                          |
[ ** ] +--------------+------------------------------------------------------------------------------------------+
[ ** ] And 21 other (uncommon) modules. You can enable those later.
[ ** ]
[ ?? ] Load module <chansaver>? (yes/no) [no]:
[ ?? ] Load module <controlpanel>? (yes/no) [no]:
[ ?? ] Load module <perform>? (yes/no) [no]:
[ ?? ] Load module <webadmin>? (yes/no) [no]: yes
[ ** ]
[ ?? ] Would you like to set up a network? (yes/no) [no]:
[ ** ]
[ ?? ] Would you like to set up another user? (yes/no) [no]:
[ .. ] Writing config [/home/debian/.znc/configs/znc.conf]...
[ >> ] ok
[ ** ]
[ ** ]To connect to this ZNC you need to connect to it as your IRC server
[ ** ]using the port that you supplied.  You have to supply your login info
[ ** ]as the IRC server password like this: user/network:pass.
[ ** ]
[ ** ]Try something like this in your IRC client...
[ ** ]/server <znc_server_ip> +50000 zncbeagle:<pass>
[ ** ]And this in your browser...
[ ** ]https://<znc_server_ip>:50000/
[ ** ]
[ ?? ] Launch ZNC now? (yes/no) [yes]: yes
[ .. ] Opening config [/home/debian/.znc/configs/znc.conf]...
[ >> ] ok
[ .. ] Loading global module [partyline]...
[ >> ] [/usr/local/lib/znc/partyline.so]
[ .. ] Loading global module [webadmin]...
[ >> ] [/usr/local/lib/znc/webadmin.so]
[ .. ] Binding to port [+50000]...
[ >> ] ok
[ ** ] Loading user [zncbeagle]
[ .. ] Loading user module [webadmin]...
[ >> ] [/usr/local/lib/znc/webadmin.so]
[ .. ] Forking into the background...
[ >> ] [pid: 7019]
[ ** ] ZNC 1.4 - http://znc.in

在您的 ZNC 服务器上添加 OTR

虽然 BitlBee 已为我们的 XMPP 和聊天网络提供了 OTR 支持,但我们的 IRC 网络目前没有 OTR 支持。如果你不打算使用 OTR,那么仍然可以将 BBB 作为 IRC 网关,并享受一个统一的 IRC 平台。由于 OTR 必须由通讯的一方启动,因此此聊天配置将与任何 IRC 系统兼容。但如果你希望在其他 IRC 频道上使用 OTR,那么有两种方法可以解决这个问题。首先,你可以在 IRC 客户端中使用 OTR。这将为你的客户端和通讯方之间提供端到端的 OTR 会话,前提是他们也在客户端使用 OTR。不过,大多数客户端(但不是所有客户端)都带有 OTR 插件。另一种方法,就是本文将介绍的方法,是在 ZNC 内部使用 OTR。

这种方法有其优缺点。好处是,对于所有的聊天网络,无论你使用哪个客户端,你都会拥有相同的 OTR 密钥。因此,一旦你的朋友验证并信任了你的密钥,即使你切换到不同的 IRC 网络,他们也能继续信任你。此外,你不再需要在客户端上运行 OTR 插件。然而,OTR 会话会在 ZNC 处终止。因此,从客户端到 ZNC 的连接必须非常安全。至少,你应该像之前提到的那样启用 SSL 选项。不过,使用自签名证书时,你仍然可能面临中间人攻击(MITM),因此可能值得花时间生成一个证书颁发机构(CA),并为你的 ZNC 服务器签发证书。你面临风险的原因是,生成自签名证书比较简单,而 ZNC 也是如此。至少,你应该记下自签名证书中生成的公钥,并且只有当 ZNC 服务器提供该已知密钥时,才信任 SSL 连接。这种技术被称为证书钉扎。正如之前提到的,生成 PKI 是一个细致的任务,因此我将把这个(适度困难的)练习留给读者。

另一个选择是,如果你不想处理 SSL,你可以通过ssh连接到你的 BBB,并在 localhost 上运行 IRC 客户端。这仍然可以为你和服务器(BBB)之间的消息提供机密性,但它将限制你使用的 IRC 客户端,因为 IRC 客户端会运行在 BBB 上。在本章的剩余部分,我们将继续使用 SSL 方法。

ZNC 的 OTR 模块相对较新,因此必须从源代码编译。它还依赖于一个在 Debian wheezy 中不可用的 OTR 版本,但可以通过回溯仓库获取。请编辑你的 apt-sources 文件,添加回溯仓库:

sudo nano /etc/apt/sources.list

在文件末尾添加以下行:

deb http://http.debian.net/debian wheezy-backports main

然后执行:

sudo apt-get update

要安装更新版本的 OTR,请输入以下命令:

sudo apt-get -t wheezy-backports install "libotr5" "libotr5-dev"

克隆znc-otr模块的代码库:

git clone https://github.com/mmilata/znc-otr.git

进入目录并键入make。你应该会看到:

LIBS="-lotr" znc-buildmod otr.cpp
Building "otr.so" for ZNC 1.4... [ ok ]

otr.so复制到~/.znc/modules目录,并注意,你可能需要创建该 modules 目录。znc-otr模块现在已经安装,但尚未加载。

将你的网络添加到 ZNC

在安装所有组件后,我们现在可以配置 ZNC。由于我们已经启用了 ZNC 的 webadmin 模块,因此可以使用浏览器来配置我们的代理并添加账户。你可以通过输入 BBB 的 URL 后跟 ZNC 的端口号来访问 webadmin 模块,格式如下:

https://192.168.1.42:50000

使用你的用户名和密码登录。在页面的右侧,会显示如下截图中的导航菜单:

将你的网络添加到 ZNC

点击你的设置。然后向下滚动到网络部分,点击添加。在这里,你可以添加之前创建的 BitlBee 设置。网络名称为 BitlBee,昵称为你创建的 BitlBee 用户名。在此 IRC 网络的服务器下,输入以下内容并将密码替换为你的 BitlBee 密码:

localhost 6667 password

滚动到页面底部,点击添加网络来保存。现在你可以返回你的设置页面,以类似的方式添加其他 IRC 网络。在本章中,我们将添加一个 freenode 账户,因为我们将用它来演示如何在 IRC 上使用 OTR。如果你没有,可以编造一个昵称,并在此 IRC 网络的服务器部分输入以下内容:

chat.freenode.net +6697

+6697 表示你希望通过 SSL 使用端口 6697 连接到 freenode,这也是半官方的 IRC TLS 端口。你可以通过点击频道下的“添加”来添加频道,ZNC 不仅会在客户端断开时将你保留在频道内,还会回放频道的对话内容。你可以通过在频道信息页面更改缓冲区计数设置来指定回放的行数。

从你的 IRC 客户端连接到 ZNC

现在你可以从你的 IRC 客户端连接到 ZNC。根据客户端的不同,你应该能够在 server password 字段中设置用户名和密码。如果你收到密码错误的警告,并且确认密码输入正确,请将密码设置为 username:password。如果使用 ERC,必须这样做。更具体地说,你应该使用 M-x erc-tls 连接,并提供 BBB 的 IP 地址、ZNC 的端口号、用户名和之前格式的密码。

如果你添加了多个网络,当你连接到 BBB 时,首先应该看到以下信息:

-*status- You have several networks configured, but no network was specified for the connection.
-*status- Selecting network [bitlbee]. To see list of all configured networks, use /znc ListNetworks
-*status- If you want to choose another network, use /znc JumpNetwork <network>, or connect to ZNC with username zncbeagle/<network> (instead of just zncbeagle)

这些消息来自虚拟用户。虚拟用户的前缀是 *,这个用户是 status。虽然 ZNC 已连接到多个网络,但你目前只看到 BitlBee 网络。在这里,你可以像之前的章节中一样与 BitlBee 进行互动。只要 ZNC 和 BitlBee 运行,ZNC 将保持与 BitlBee 的连接,你可以随时附加或分离。要在实际的 IRC 网络(如 freenode)上使用 OTR,我们需要将 ZNC 附加到其他网络。有两种方法可以做到这一点。正如 status 提醒我们的,假设你将 freenode 网络命名为 freenode,可以通过以下命令跳转到该网络:

/msg *status JumpNetwork freenode

这将把你现有的会话 跳转 到 freenode。虽然你可能仍在同一个客户端窗口中,但现在你正通过一个不同的 IRC 网络聊天,因为我们已经从 BitlBee 切换到了 freenode。如果你使用 GNU screen 或 tmux,我们刚刚执行了一个类似的操作,就像切换到一个新的屏幕一样。会话仍在运行,我们只是查看了不同的实例。这种方法的好处是只使用了一个从客户端到 ZNC 的连接,但可能会有些混淆。

或者,你可以打开另一个 ZNC 连接。为了让 ZNC 知道你希望新的会话连接到不同的网络,你必须使用不同的语法。你的用户名必须是 username/network 形式,如果你像在 ERC 中那样把用户名发送到密码字段中,则格式为 username/network:password。所以,在这个例子中,用户名是:

zncbeagle/freenode

使用任一方法,通过 IRC 连接到 freenode。

通过 ZNC 建立 OTR 连接

现在我们正在使用 ZNC 来管理 IRC 流量,接下来我们来建立一个 OTR 会话。这个过程与我们在 BitlBee 上所做的类似,完成后你应该能熟练地使用 OTR 来建立身份验证。在这个实验中,你需要一个懂加密的朋友、一个不情愿的另一半,或者一个单独的 IRC 账户。基本上,你需要一个可以通过 OTR 与其聊天的人。

现在你已经登录到 freenode 或你喜欢的 IRC 网络,可以与其他用户发起聊天。在大多数客户端中,当你输入以下命令时,这将会在新窗口中打开对话:

/query username

现在,你可以与朋友享受一场传统的、未加密的聊天。要进行 OTR 聊天,我们首先需要生成一个密钥,就像我们在 BitlBee 中所做的那样。在 ZNC 中,有一个虚拟用户 *otr,与 *status 用户类似,你可以向该用户发出 OTR 命令。首先,你应该输入以下命令来生成一个密钥对:

/msg *otr genkey

记住,ZNC 中所有虚拟用户都有 * 前缀。这可能会打开一个新窗口,显示 *otr 用户,你应该看到类似这样的内容:

<*otr> Starting key generation in a background thread.
<*otr> Key generation finished.

现在你可以发起一个 OTR 会话。如果你想发起 OTR 会话,输入以下命令:

?OTR?

否则,你的好友可以启动 OTR 对话,ZNC-OTR 会自动继续协议。与 BitlBee 不同,问题不是身份验证命令的一部分,因此你必须先自行输入问题。如果 Alice 和 Bob 正在交谈,身份验证步骤之前的对话可能是这样的:

<alice> When prompted, answer the question: What was printed on my t-shirt which I wore yesterday? One word, lowercase.
<bob> got it.

启动身份验证的命令格式为:/msg *otr auth username answer。继续我们之前的例子,命令如下,其中问题的答案是 tworkeffx

/msg *otr auth bob tworkeffx

这将提示你的好友参与 OTR 身份验证阶段,他在屏幕上看到的内容取决于他使用的 IRC 客户端。*otr 用户应该用类似以下的消息回应:

<*otr> [bob] Gone SECURE. Please make sure logging is turned off on your IRC
<*otr> [bob] Peer is not authenticated. There are two ways of verifying their identity:
<*otr> [bob] 1\. Agree on a common secret (do not type it into the chat), then type auth bob <secret>.
<*otr> [bob] 2\. Compare their fingerprint over a secure channel, then type trust bob.
<*otr> [bob] Your fingerprint:  E8949490 D0326A85 1049EE79 DF111C0A BCC68D42
<*otr> [bob] Their fingerprint: 00694775 3945FA05 B2E0DA61 5416DFFC 4F9C5936
<*otr> [bob] Initiated authentication.
<*otr> [bob] Peer replied to authentication request.
<*otr> [bob] Successfully authenticated.

正如*otr所提示的那样,身份验证有两种方法。我们使用的是第一种方法,即社会主义百万富翁协议。你的好友 Bob 给出了你的答案,你已经验证了他。Bob 也应该进行类似的交换,答案的格式是:

/msg *otr auth bob <answer>

现在,你可以享受加密的聊天会话了。

扩展项目

当前,你的 BeagleBone 仅服务于你的本地网络。你可以像设置 Tor 服务器时那样启用端口转发,将其开放到互联网,让你在外出时也能访问 ZNC。如果你这么做,务必确保使用 SSL,并考虑使用动态 DNS 服务,这样你就不必记住 IP 地址。

ZNC 和 BitlBee 软件包具有很强的扩展性。此外,由于它们是 IRC 服务器,你可以在 ZNC 服务器上运行一个 IRC 机器人。有几个流行的 IRC 机器人软件包,可能最著名的是 Eggdrop(www.eggheads.org/)。在你的 BBB IRC 服务器上定制一个机器人可以让它在 IRC 和硬件之间进行交互。例如,如果你在 BBB 上添加了一个温度传感器,你可以查询机器人以了解房间的温度。如果你在 BBB 上添加了 ZigBee 无线电,并将相同的温度传感器连接到一个由电池供电的 ZigBee 无线电上,机器人就能告诉你外面的温度。如果你成为一个热衷的 IRC 用户,你会喜欢将硬件电子项目与 BBB 机器人结合起来。

如果你想使用 CryptoCape 来增加一些硬件保护,你可以将 ZNC 的 SSL 证书存储在 TPM 中。TPM 可以存储 RSA 密钥,并且可以生成私钥保持在 TPM 中。虽然连接各个组件需要进行大量编程,但这无疑会是一个有趣且具有挑战性的项目!

总结

本章中,你学习了如何使用另一个隐私工具——OTR。我们将 OTR 用于两个不同的应用,并研究了 OTR 身份验证的工作原理。我们还设置了 BBB,将其作为 IRC 网关连接到我们的聊天网络,并管理所有的 IRC 通信。

在本书中,我们挑选了三款最受欢迎且备受尊重的隐私与安全应用,并在 BeagleBone Black 上使用它们。BBB 的小巧体积、低功耗以及扩展性使其成为理想的隐私助手。本书所用的软件和硬件大量依赖密码学,而密码学本身是一个社会化且常常具争议的技术。我们也在过程中了解到了一些现代密码学的社会政治斗争。最后,你无需成为一名特工就能进行私密且安全的通信;最好的工具是免费提供的。你可以通过使用这些工具并向开发者提供反馈来改进它们。

快乐黑客!

附录 A. 参考文献精选

第一章

第二章

第三章

第四章

第五章

posted @ 2025-07-05 19:51  绝不原创的飞龙  阅读(7)  评论(0)    收藏  举报