# 安全随笔——安全到底是什么

### 引言 <a href="#h2-1" id="h2-1"></a>

“这横贯数千年的西法史，说来说去就是讲这么一个问题。”，老师转过身，在黑板上写下了几个单词，“What is \_\_\_?”。一位女同学在台下脱口而出，“law”。老师把粉笔一丢，挥挥手，微笑示意着我们下课。毫无疑问这是一堂精彩绝伦的法律课，但身为信安专业的学子，自然而然萌生了另一个想法：黑板上的填空，如果替换成 security，该作何解答？

时光倒回数年前，记得在马云的访谈录上，见过这么一句话“做淘宝，最难的是建立诚信体系”。当时尚小不能理解，现在有所感悟。连萍水都未曾相逢的买家与卖家，凭什么信任“买家是真的买家，卖家又是真的卖家”，凭什么能够实现”一手交钱，一手交货“？淘宝的解决思路是：淘宝作为**可信第三方**介入交易，在买家下单后，先将货款转入到淘宝的指定账号，只有在买家确认收货后，卖家才能从淘宝收到相应的货款。问题进一步延伸，淘宝凭什么能够成为可信第三方？成为可信第三方后，又是如何分发和管理其数字证书，确保互联网上每一笔交易的顺利进行？

回答上述两个问题都离不开建立一套**安全体制**，但相比于安全体制如何建立，更为重要的一点是，究竟如何去理解“安全”，即回答“What is security?”。

密码学大牛 Bruce Schniner 在其著作 *Applied cryptography : protocols, algorithms, and source code in C*提到了安全的定义，笔者认为非常恰当，援引如下：

> 如果把一封信锁在保险柜中，把保险柜藏在纽约的某个地方，然后告诉你去看这封信，这并不是安全，而是隐藏。
>
> 相反，如果把一封信锁在保险柜中，然后把保险柜及其设计规范和许多同样的保险柜给你，以便你和世界上最好的开保险柜的专家能够研究锁的装置，而你还是无法打开保险柜去读这封信，这才是安全的概念。

为了更好地理解什么是安全，可行的方案是学习信息安全领域的道统学科——密码学。

### 密码学 <a href="#h2-2" id="h2-2"></a>

密码学是为了达到机密信息不被非授权地获知的目的,而采取的某种手段或方式，主要基于数学或物理的某种变换来实现**加密/ 解密**。密码学的研究对象可以抽象为一个四元组：（明文，密钥，密文，加解密算法），即研究 p = D\_k(E\_k(p)) 的实现 。

#### 历史 <a href="#h3-1" id="h3-1"></a>

密码学是一门古老的学科，在数千年前已经诞生，并且得到广泛应用：

* 与密码学 cryptography 意思相近的一个单词是 cryptology，在古希腊文中的意思是“如何秘密地书写单词”。440 B.C. 古希腊战争中，奴隶主赫斯坦为推翻波斯人统治，想与爱奥尼亚城统治者联合行动，采用了“隐写术”进行保密通信。他剃光一位忠实奴隶的头发，将情报刺在其头皮上，等待头发长出来之后，就让奴隶出发前往爱奥尼亚城。奴隶到达目的地后，让人剃光自己的头发，对方就看到了奴隶头皮上刺的情报。
* 现代的门限共享方案，早在我国周代就有其雏形。据史料记载，周代的著名军事家姜尚（字子牙）发明了“阴符”和“阴书”。其中，阴书采用“**一合而再离，三发而一知**”的方法，将一份军事情报分成三份，分别放在三枚竹简上，派三名信使各持一个竹简出发，到达目的地后，三枚竹简再合而为一，就可得知军事信息的原意。

除了上述两个例子，诸如藏头诗、卡丹网格式密码、二战期间周恩来总理发明的“豪密”、让日本摸不着头脑的“纳瓦霍密码”，也都是密码学的实际应用。然而这些历史应用可能离当下生活仍旧太遥远，因此不妨移目下方这个小故事：

> 在百度的密码吧里，这则已有 20118 个跟贴，名字为《求救，我已经快想爆了》的帖子里，发帖主人 HighnessC 说：“最近和一个心仪的女生告白，谁知道她给了一个摩斯密码给我，说解出来才答应和我约会。可是我用尽了所有方法都解不开这个密码。。好郁闷啊。只能求救你们了。”
>
> <省略解密过程>
>
> 吧友们最后直呼，“祝楼主幸福咯。因为她是爱你的！！”

故事的来龙去脉，可上知乎获悉：<https://www.zhihu.com/question/20011317/answer/728551774。>

#### 对称加密与非对称加密 <a href="#h3-2" id="h3-2"></a>

言归正传，回到密码学理论本身。无论是古典密码学，还是现代密码学，基本的加密模式都是**分组加密**（流密码可以视为分组长度为 1 的分组加密）。分组加密最本质的要求是 Claude Shannon 提出的**扩散（Diffusion）和混乱（Confusion）**，它们分别基于换位和替换操作实现。换位和替换即常说的的 S-box(Substitution) 和 P-box(Permutation)。S-box 将输入的数据块映射为另一个数据块，例如将字母"A"替换为"X"。P-box 则是将输入的数据块按照预定的规则重新排列，例如将字符串"ABCD"重排为"CDAB"。运用 S-box 和 P-box 的示例比比皆是，例如耳熟能详的 Caesar cipher 和 Vigenere cipher。

<figure><img src="/files/YZJaRGpch9VV4CHt0k6e" alt=""><figcaption><p>Caesar cipher</p></figcaption></figure>

<figure><img src="https://image.3001.net/images/20240516/1715841292_6645a90c4b05c00aa6405.png!small" alt="" width="375"><figcaption><p>Vigenere cipher</p></figcaption></figure>

然而基于线性变换的 S-box 与 P-box 难以抵御词频统计等攻击。现代密码学中，加解密算法的安全性不再依赖于线性变换，而主要依赖于某种非线性变换，加解密算法的原型也往往基于某类数学难题，像基于大数因子分解难题的 RSA、基于离散对数难题的 DH 和 DSA、基于椭圆曲线离散对数难题的 ECC。

以上讨论的密码学大多属于对称加密的范畴，对称加密的特点是加密与解密过程中使用的密钥是相同的，既然要用到相同的密钥，首当其冲的问题就是通信双方如何协商这一密钥？即如何解决通信双方的**密钥分发**问题。为讨论密钥分发问题，不妨先建立一个通信模型：

![image.png](https://image.3001.net/images/20240516/1715841324_6645a92c5a4ed0a694e21.png!small)

具体考虑"首次通信"和"不安全信道通信"这两种场景，对于从未通信过的发送方和接收方，双发无法确认对方的身份，无法事先共享密钥，难以进行首次通信；在不安全信道中交换密钥存在风险，密钥可能被窃听或截获。一旦密钥泄露，攻击方就可以解密通信内容，进而窃取、篡改、伪造通信内容。综上，不难发觉对称加密难以解决**密钥分发**问题，而且对称加密还存在以下缺陷：

1. 无法实现不可否认性（抗抵赖性）。设想某机密信息被泄露，通信的发送方和接收方都有可能是泄密者，若第三方介入尝试取证，就会遇到无法唯一确认泄密者身份的问题。
2. 密钥管理负担重，每对通信双方都需要一个唯一密钥，随着通信参与方数量的增加，密钥数量以 N^2 规模增长。

在对称加密面临以上问题的情况下，非对称加密的出现填补了这些缺陷。1976年，Whitfield Diffie 和 Martin E. Hellman 发表了一篇极其重要的论文—— **New Directions in Cryptography**，开创了**非对称加密体系**（公钥加密体系），二人因此荣获 2015年 图灵奖。这一体系的关键在于使用一对公私钥，其中公钥用于加密，私钥用于解密。这种机制允许通信实体在不事先共享密钥的情况下进行安全通信，从而解决了对称加密在首次通信和不安全信道通信中的局限性。关于非对称加密的模式，可以举一个简单的例子加以说明（以下 c 代表密文，p 代表明文）：

![image.png](https://image.3001.net/images/20240516/1715841362_6645a952013ab2d352071.png!small)

值得一提的是，DH 二位虽然提出了非对称加密体系，但并没有给出一个实例，因为找到一个单项陷门函数并非易事。读者可能会好奇什么是单项陷门函数？单项陷门函数是非对称加密体系的基础，单项函数好理解，即从一方向计算容易，从另一方向反推很困难的函数，如 Hash 函数。陷门函数是一种在一个方向上很容易计算，但在**没有特殊信息**的情况下很难在相反方向上计算（寻找它的逆）的函数，称为“陷门”。陷门函数是单向函数的一种特殊情况。单向陷门函数的特点概况如下：

![image.png](https://image.3001.net/images/20240516/1715841376_6645a960334b9c0a1f9be.png!small)

在1979年，Ron Rivest, Adi Shamir 和 Leonard Adleman 发明了 RSA算法，**将非对称加密正式带入人世间**，三位作者也因此共同分享 2002年图灵奖。非对称加密有很多应用场景，PGP（Pretty Good Privacy）是其中一种。PGP 用于保护电子邮件通信的隐私和安全性，其应用过程的一种数学表达式如下：

![image.png](https://image.3001.net/images/20240516/1715841391_6645a96f4f85496f01e17.png!small)

具体流程：首先用单向函数生成明文 P 的摘要（用于后续消息完整性验证），再用私钥 sk 签名摘要（用于后续消息来源验证），而后将签名与摘要压缩（提高传输效率）。为了防止攻击者窃取，用对称密钥 km 加密压缩后的消息，并用接收方的公钥加密 km，最后采用某种编码方式，将消息编码后发送给接收方。接收方收到消息后，按照上述过程的逆过程进行解密。以下是一个 PGP 脚本 demo。

![image.png](https://image.3001.net/images/20240516/1715841429_6645a995a13ed97e66a14.png!small)

关于 PGP 的具体实现，可参考：<https://github.com/955xiaoSu/Trusted-transmission-based-on-PGP。>

以上从密码学的角度讨论了“What is security?”，以下笔者将从计算的角度进一步分享对这个问题的理解。

### 计算上不可行 <a href="#h2-3" id="h2-3"></a>

从广义上，笔者认为“安全等价于计算上不可行”。为了探讨“计算上不可行”这个概念，不妨先聊聊计算这件事。

计算是什么？对于 CS 行业的我们，第一反应可能是，计算机在做的事情是计算！而后开始联想冯诺依曼计算机体系的计算流程，即有一个输入设备读取输入，其次有存算设备来处理中间结果，最后输出设备展示计算结果。

![image.png](https://image.3001.net/images/20240516/1715841458_6645a9b2559904e75634d.png!small)

但除此之外，还有没有别的计算场景呢？

* 玩剪刀石头布是不是计算？
* 用笔在纸上做做算术、几何是不是计算？
* 拿起眼前的水杯喝水是不是计算？

在以上这些场景，人类大脑都需要进行时空方面的计算，确定肌肉的紧张程度，实现在特定的时空完成特定的动作。笔者认为在本质上，**”计算”是一种”映射“**，是对输入的响应，响应体现为输出，所以计算可以用如下范式表达。

![image.png](https://image.3001.net/images/20240516/1715841468_6645a9bccde2e3193a00a.png!small)

运用上述范式解释“睡眠”这一行为，首先将人体的感官与皮肤抽象为一个传感器，用于接收现实世界的输入（如光线、声音）。当夜幕降临，人体在生物钟的控制下，开始释放褪黑素、腺苷等化学物质，提升睡眠压力，让人体感到困倦，此外，人体接收到的各路信息（如昏暗的光线）也会提示到点了该上床睡觉了。与此同时，下丘脑作为大脑皮层的门卫，会控制相应的信号进入皮层促进睡眠，同时屏蔽一些不利于睡眠的信号。当心率、体温等指标都被调整到合适的范围时，人体逐渐进入睡眠状态。在睡眠场景下，“Blackbox”是人体神经信号的处理与传导，输出是人体呈现出睡着的状态（很明显的特征是肌无力）。

聊完计算之后，可以接着探讨“计算上不可行”。笔者认为，“计算上不可行”有两层基本的含义：

1. 不可计算。通俗点儿说就是做不到，包括但不限于以下两种情形：计算消耗的资源超过人类所能获取的极限、问题目前无法计算。\
   前者好理解，计算需要消耗能量，根据能量守恒定律，能量是不可能凭空产生的，因此计算所消耗的能量客观上不能超过人类所能使用的能量极限；对于后者，目前通用计算机的模型是图灵机，图灵机被希尔伯特形式系统所定义，而哥德尔证明了希尔伯特形式系统是不完备的！这意味着计算机的能力存在着上界，也说明人类认知能力存在上界，上界之上的世界是目前无法理解也无法计算的。
2. 可计算但不值得，换句话说即计算代价过高。道哥在《计算》中提到这么一个观点：

> 计算与安全是一枚硬币的两面，安全是由计算强度保证的。

深以为然。因为世界上不存在绝对安全的系统，安全追求的并不应该是所谓万无一失的系统，而应该着眼于提高攻击者的计算强度。例如让攻击者为追求 ￥1 价值的目标，付出至少 ￥2 的代价；又或者设计一个方案，让攻击者破解保密期限只有 1day 的机密消息，至少需要花费 2day 的时间。“提高攻击者计算强度”这样一种安全方案的可行性，已经被世界所存在的单向函数所证明。世界存在单向函数的一个例子是：根据[刘仁文：论死刑的成本](https://www.aisixiang.com/data/11994.html)，死囚从被判处死刑到执行花费的金额高达数百甚至上千万美元，而构成死刑的犯罪成本才多少呢？

上述两个章节分别从密码学和计算的角度讨论了“What is security？”，在最后，笔者尝试从系统的角度对此问题进行总结。

### 系统安全 <a href="#h2-4" id="h2-4"></a>

在某讲坛上，笔者有幸获得了提问道哥的机会。

> ”您觉得在学习安全的过程中，最重要的思维是什么？“
>
> ”系统安全。“

**系统安全成为了笔者看待安全的全局出发点**，从前听闻过的一系列攻击，蠕虫、震网、幽灵、熔断、西工大 TAO 攻击、CVE-2024-3094 xz 软件包后门……都被“系统安全”这根绳紧密串联在了一起，这些攻击不再是零散的，而是以树形结构被有序组织在脑海中。

在系统的视角下，考虑安全问题，可以围绕信息的生命周期进行思考：

1. 产生信息的过程中，本地硬件、固件、SBI、操作系统、编译器、ABI、应用程序、键鼠、屏幕等一系列软硬件设备是否可信？
2. 在信息存储的过程中，如何做到选择性可见（仅对目标对象开放）？文件的权限管理是否遵守 KISS 原则？若采用加密的方式进行存储，加密的熵值是否足够大？
3. 在信息传输的过程中，如何做到可靠传输，防止信息被窃取、篡改、伪造？
4. 如何防范社会工程？世界头号黑客 Kevin Mitnick 曾说过：“人是最薄弱的环节。你可能拥有最好的技术、防火墙、入侵检测系统、生物鉴别设备，可只要有人给毫无戒心的员工打个电话……”。Kevin 的著作 *The Art of Deception*淋漓尽致地展现了社会工程的效果。

围绕信息的生命周期是系统安全的一个实例，也可以围绕安全实现的四大手段“完整性、访问控制、随机化、隔离”来琢磨安全问题，这里暂不展开。当然，系统安全的思想不可能解决一切安全问题，在运用时必须反思其存在的前提是什么。毕竟盲目地运用任何一种理论，而不加考虑其前提，毫无疑问是一种愚蠢。那么系统安全的前提是什么？

笔者认为运用系统安全思维分析问题的前提是：**不信任**计算的参与方。这里的参与方不仅指人，也泛指计算用到的一切设备（如交换机、路由器、DNS 服务器、IP 协议）。假如你信任计算的参与方，那么就不需要考虑安全。比如 1973年 Vint Cerf 和 Bob Kahn 发表 *A protocol for Packet Network Interconnection*建立 Internet 后，在 1974年 ARPANET 的实践中，参与计算的节点总共只有 UCLA, SRI, UCSB, UTAH 四个，即便你骗骗我或者我骗骗你，也捞不到好处，那自然就没有必要考虑安全问题。

以上是笔者近一段时间学习安全的感悟，仅供读者参考，欢迎交流、批评与指正。最后有一句话希望与各位共勉：

> 在安全面前，我永远是个孩子。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://blog.kaisuping.cn/technology/an-quan-sui-bi-an-quan-dao-di-shi-shi-mo.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
