极客时间已完结课程限时免费阅读

16 | 安全管理:数字世界的守护

16 | 安全管理:数字世界的守护-极客时间

16 | 安全管理:数字世界的守护

讲述:丁伟

时长20:04大小18.45M

你好,我是七牛云许式伟。今天我们要聊的话题是操作系统的最后一个子系统:安全管理。
数字世界是高效的,但数字世界也是脆弱的。在越来越多的日常生活被数字化的今天,安全问题也越来越凸显出了它的重要性。
有经验的安全工程师都知道,做好安全的基本逻辑是:不要开太多的门和窗,最好所有人都在同一道门进出,安全检查工作就可以非常便利地进行。
要想构建一个安全可靠的环境,从最底层就开始设计显然是最好的。所以安全管理是一个基础架构问题。现代操作系统必然会越来越关注安全性相关的问题。因为一旦安全问题严重到触及人们的心里防线,整个数字世界都有可能随之崩塌。
让我们从头回顾一下操作系统安全能力的演进。

病毒与木马

首先是实模式的操作系统,以微软的 DOS 系统为代表。实模式的操作系统进程都运行在物理地址空间下。
这意味着,每个软件进程都可以访问到其它软件进程(包括操作系统)的内存数据,也可以随意地修改它。所以这个时期的计算机是非常脆弱的,它选择的是信任模式:我相信你不会搞破坏。
不过,好在这个时期网络还并不发达,所以一个单机版本的恶意软件,能够干的真正恶意的事情也很有限。这一时期恶意软件以计算机病毒为主,其特征主要是繁衍自己(复制自己),对计算机系统本身做某种程度的破坏。
现代操作系统基本上都是保护模式的操作系统。保护模式就是让软件运行的内存地址空间隔离,进程之间相互不能访问(除非基于共享内存技术,那也是进程自己主动选择,与被动无感知的情况下被人窥视不同)。
这从安全角度来说,是很重要的进步。不管怎么说,内存数据是最为敏感的,因为它无所不包。况且,从 Windows 开始,互联网逐步进入人们的视野。计算机的联网,一下子让安全问题变得严峻起来。
恶意软件目的开始变得不单纯。它不再只是黑客的技术炫耀,而是切切实实的黑色产业链的关键依赖。
这一时期恶意软件开始以木马为主。木马和病毒一样会去繁衍自己(复制自己),但是它较少以破坏计算机的运行为目的,相反它默默隐藏起来,窃取着你的隐私。然后,它再通过互联网把窃取的信息默默地传递出去(比如通过电子邮件)。
哪些信息是木马感兴趣的?有很多。比如以下这些信息:
键盘按键;
剪贴板的内容;
内存数据;
文件系统中关键文件的内容;
……
你可能奇怪,前面不是说保护模式已经把内存数据隔离了么,为什么木马还是能够取到内存数据?
其实这一点不难想明白,虽然跨进程已经无法取得数据了,但是木马本来就是靠复制自己,把自己伪装成正常软件的一部分。这样,木马程序和正常的软件代码同属于一个进程内,所有信息对其仍然一览无余。
为了彻底阻止木马程序篡改正常的应用程序,聪明的操作系统创造者们想到了好方法:数字签名。
这本质上是白名单技术。所有正常发布的软件都到操作系统厂商那里登记一下。这样,一旦木马去修改软件,把自己附加上去,这个软件的签名验证就通不过,也就直接暴露了。
其实 Windows 操作系统已经引入了数字签名的概念,可以用以鉴别软件的可信度。但是考虑到从开放转向封闭有极大的历史负担,所以无论是 Windows 还是 macOS,都没有完全杜绝无签名的软件,最多当你运行无数字签名的软件时,会给个不可信的警告。
第一个大规模把软件发布变成一个封闭环境的是苹果的 iOS 操作系统。苹果通过引入 App Store,要求所有应用发布都必须通过 App Store 进行。今天无论是 Android 还是 iOS 操作系统都基于应用市场这样的封闭软件发布的形态。
这样一来,软件无法被非法修改,木马基本上就无所遁形了。当然,这并不代表木马在这些平台上就消失了。虽然不容易,但是通过感染开发人员的软件开发环境,还是可以在软件编译或其它环节中把木马注入到要发布的软件中。
要发现这种异常,iOS 和 Android 系统的厂商对软件进行数字签名前,往往会对其进行安全扫描,以发现各种潜在的安全风险。一旦某个软件被鉴定为恶意软件,就无法通过数字签名,也无法发布到应用市场上。
通过这些机制,木马很难再有机会得到传播。

软件的信息安全

但是,这意味着我们没有安全风险了么?当然不是。在移动设备上,安全问题的大环境发生了巨大的变化。
首先,移动时代随着我们数字世界对现实生活影响的加深,我们越来越多的敏感信息更加容易被软件触及。有很多新增的敏感信息是 PC 时代所不具备的,例如:
通讯录和通话记录;
短信;
个人照片和视频;
个人地理位置(GPS)信息;
移动支付的支付密码、支付验证码;
录像和录音权限;
通话权限;
.……
正因为如此,尽管操作系统正变得越来越安全,但我们面临的安全威胁却也在日趋严重。
其实, iOS 操作系统在安全管理上的考虑不可谓不周全。
首先,在软件隔离机制上,除了基于 CPU 的保护模式,确保软件之间的内存隔离外,iOS 还引入了沙盒系统(Sandbox),确保软件之间文件系统隔离,相互之间不能访问对方保存在磁盘上的文件。
其次,通过上面我们已经提及的数字签名机制,防止了软件被恶意篡改,让病毒和木马无法传播繁衍。
最后,对涉及敏感信息的系统权限进行管控。各类敏感信息的授予均是在应用程序使用的过程中进行提示,提醒用户注意潜在的安全风险。
在这一点上,Android 操作系统往往则是在安装软件时索要权限。这两者看似只是时机不同,但是从安全管理角度来说, iOS 强很多。
还没有见到软件真身就让用户判断要不要给权限,用户往往只能无脑选择接受。而如果是在软件运行到特定场景时再索要权限,那么权限给不给就有合理的场景支持决策。
但是,在利益面前,软件厂商们是很难抵御住诱惑的。所以不仅仅是恶意软件会去过度索要系统权限,很多我们耳熟能详的常规软件也会索要运行该软件所不需要的权限。
移动时代,恶意软件的形态已经再一次发生变化。它既不是病毒也不是木马,而是“具备实用功能,但背地却通过获取用户的敏感信息来获利”的应用软件。
它通过诱导用户下载,然后在软件安装或者使用时索要敏感信息的获取权限。
一个软件到底是正常的还是恶意的?边界已经越来越模糊了。
以前病毒和木马都有复制和繁衍自己这样一个显著的特征,但如今它们的复制繁衍能力已经被操作系统的安全机制所阻止,所以恶意软件和普通软件一样,都是通过某种手段吸引用户下载安装。
怎么保护好用户的隐私信息?道高一尺,魔高一丈。攻防之间的斗争仍将继续下去。

网络环境的信息安全

如果我们不轻易尝试不可信的软件,就可以一切安全无虞?并不然,我们还要考虑我们的计算机所处的网络环境安全问题。
我们上网过程需要经过一系列的中间节点,有交换机,有路由器。我们的上网产生的所有数据包,都经由这些中间节点,这意味着我们有以下三个级别的安全风险。
被窃听的风险。可能会有人在这些节点上监听你访问和提交的内容。
被篡改的风险。可能会有人在这些节点上截获并修改你访问的内容。
被钓鱼的风险。可能会有人冒充你要访问的服务提供方和你通讯。
虽然大部分的中间节点由网络运营商提供,我们刨除这些节点被黑客所黑的情形,基本上认为可信。但这并不绝对,至少在中国,运营商修改中转的数据包这样的事情是干得出来的,常见的手法有:
在正常的 HTML 页面插入广告;
修改用户下载的 apk 文件,替换成自己想分发的 apk 文件;
修改 404 类型的 HTML 页面,替换成自己的搜索引擎的搜索页;
.……
其次是 WiFi 路由器。WiFi 路由器因为其提供方鱼龙混杂,天生是安全问题的大户。运营商能够干的事情它全都可以干,甚至可以更加肆无忌惮,以李鬼替换李逵,钓鱼的风险并不低。
比如你以为登录的是交通银行官网,它可能给你一个一模一样外观的网站,但是一旦你输入用户名和密码就会被它偷偷记录下来。
怎么解决中间人问题?
首先是怎么防篡改。应用场景是电子合同 / 公章、网络请求授权(例如你要用七牛的云服务,需要确认这个请求的确是你,而不是别人发出的)等。这类场景的特征是不在乎内容是否有人看到,在乎的是内容是不是真的是某个人写的。
解决方法是数字签名技术。一般来说,一个受数字签名保护的文档可示意如下:
其中,“要防篡改的内容” 是信息原文。“密钥提示” 是在数字签名的 “密钥” 有多个的情况下,通过 “密钥提示” 找到对应的 “密钥”。如果用于保护信息的 “密钥” 只有一个,那么可以没有 “密钥提示”。“指纹” 则是对信息使用特定 “密钥” 和信息摘要算法生成的信息摘要。
大部分情况下,数字签名的信息摘要算法会选择 HMAC MD5 或者 HMAC SHA1。在 Go 语言中,使用上示意如下:
import "crypto/hmac"
import "crypto/sha1"
import "encoding/base64"
textToProtected := "要防篡改的内容"
keyHint := "123"
key := findKey(keyHint) // 根据 keyHint 查找到 key []byte
h := hmac.New(sha1.New, key) // 这里用sha1,也可以改成别的
h.Write([]byte(textToProtected))
textDigest := base64.URLEncoding.EncodeToString(h.Sum(nil))
textResult := textToProtected + ":" + keyHint + ":" + textDigest
得到的 textResult 就是我们期望的不可篡改信息。验证信息是否被篡改和以上这个过程相反。
首先根据 textResult 分解得到 textToProtected、keyHint、textDigest,然后根据 keyHint 查找到 key;再根据 textToProtected 和 key 算一次我们期望的信息摘要 textDigestExp。
如果 textDigestExp 和 textDigest 相同,表示没被篡改,否则则表示信息不可信,应丢弃。
如果我们希望更彻底的隐私保护,避免被窃听、被篡改、被钓鱼,那么数字签名就不顶用了,而需要对内容进行加密。
加密算法上,一般分为对称加密和非对称加密。对称加密是指用什么样的密钥(key)加密,就用什么样的密钥解密,这比较符合大家惯常的思维。
非对称加密非常有趣。它有一对钥匙,分私钥(private key)和公钥(public key)。私钥自己拿着,永远不要给别人知道。公钥顾名思义是可以公开的,任何人都允许拿。
那么公私钥怎么配合?首先,通过公钥加密的文本,只有私钥才能解得开。这就解决了定向发送的问题。网络中间人看到加密后的信息是没有用的,因为没有私钥解不开。
另外,私钥拥有人可以用私钥对信息进行数字签名(防止篡改),所有有公钥的人都可以验证签名,以确认信息的确来自私钥的拥有者,这就解决了请求来源验证的问题。
那么 A、B 两个人怎么才能进行安全通讯呢?首先 A、B 两人都要有自己的公私钥,并把公钥发给对方。这样 A 就有 A-private-key、B-public-key,B 就有 B-private-key、A-public-key。通讯过程如下所示。
A 向 B 发信息 R。具体来说,A 首先用 A-private-key 对 R 进行签名,得到(R,R-digest);然后用 B-public-key 对(R,R-digest)加密,得到 encoded(R,R-digest);然后把最终的加密信息发出去。
B 收到 encoded(R,R-digest),用 B-private-key 解密得到(R,R-digest),然后再用 A-public-key 验证信息的确来自 A。
B 理解了 R 后,回复信息给 A。这时两人的角色互换,其他同上。
非对称加密机制非常有效地解决了在不可信的网络环境下的安全通讯问题。但是它也有一个缺点,那就是慢。相比之下,它的速度比对称加密慢很多。
所以,一个改善思路是结合两者。非对称加密仅用于传输关键信息,比如对称加密所需的密码。完整的通讯过程如下所示。
A 生成一个临时用的随机密码 random-key。
A 向 B 发送 random-key,机制用的就是上面的非对称加密,基于 B-public-key。
B 收到 A 发送的 random-key,把它记录下来,并回复 A 成功。回复的信息可以基于 random-key 做对称加密。
此后,A 向 B 发、B 向 A 发信息,都用 random-key 作对称加密,直到本次会话结束。
你可能发现,整个过程中 A 自己已经不再需要非对称的公私钥对了。只要 A 事先有 B 的公钥(B-public-key)就可以。
当然,上面我们的讨论,没有涉及 B 如何把自己的 B-public-key 交给对方的。在假设网络不可信的前提下,这似乎是个难题。
我觉得有两个可能性。一个是 A 和 B 很熟悉,平常都经常一起玩。那么他们交换 public-key 完全可以不依赖任何现代通讯设备,包括电话和互联网,而是写在一张纸上,某天聚会的时候交换给对方。
另一个是更为常见的互联网世界场景:我要访问一个网站。我怎么才能避免被窃听、被篡改、被钓鱼?
通常我们用 HTTPS 协议。
在 HTTPS 协议中,第一步是 A 作为客户端(Client)去获取 B 作为网站的公钥(B-public-key)。
怎么获取?如果我们认为网络不可信,那么我们就需要找一个可信的中间人,第三方权威机构 G,由它来证明,我们网站 B 返回客户端 A 的公钥(B-public-key),的确来自于 B,中间没有被其他人篡改。
这意味着网站 B 不能直接返回自己的公钥(B-public-key)给客户端 A,而是需要返回由权威机构 G 做了数字签名的公证书(简称数字证书),里面记录了网站 B 的域名(domain),和对应的公钥(B-public-key),还有证书的颁发人 G 的代号。
这张数字证书的作用是什么?最重要的并不是它怎么在网络上传递的。而是它记录了这样一个事实:域名 domain 对应的公钥是 B-public-key,它是由权威机构 G 做出的公证,因为上面有 G 的数字签名。
所以这张数字证书并不需要临时生成,而是提前在网站部署时就已经生成好了,而且也可以随意传递给任何人,因为它是完全公开的信息。
当然这里还有一个前提,我们客户端 A 已经提前拥有第三方权威机构 G 的公钥(G-public-key)了。整个过程如下:
客户端 A 向网站 B 请求网站的数字证书。
网站 B 返回它的数字证书。
客户端 A 收到数字证书,用 G-public-key 验证该数字证书的确由权威机构 G 认证,于是选择相信证书里面的 (domain, public-key) 信息。
客户端 A 检查证书中的 domain,和我们要访问的网站 B 域名是否一致。如果不一致,那么说明数字证书虽然是真的,但是是别人找权威机构 G 认证的其他域名的证书,于是结束会话;如果一致,于是相信证书中的 public-key 就是网站 B 的公钥(B-public-key)。
有了 B-public-key,客户端 A 就可以愉快地上网,不必担心网络通讯的安全了。
但是,HTTPS 并不能完全解决钓鱼问题。它假设用户对要访问的网站域名(domain)可靠性有自己的判断力。
这当然并不全是事实。所以,高级一点的浏览器(例如 Google Chrome),它会建立不靠谱网站域名的数据库,在用户访问这些网站时进行风险提示。

更多的信息安全话题

上面我们更多从服务终端用户角度,操作系统和浏览器以及我们的应用程序需要考虑的是信息安全问题。有以下这些信息安全问题没有涉及:
服务器的安全问题(DDOS 攻击、漏洞与入侵);
企业信息安全;
社会工程学的安全问题;
……

结语

总结一下,我们今天聊了软件安全态势的演变过程,从最早的病毒和木马,演化到今天敏感信息如通讯录等内容的窃取,正常软件与恶意软件的判断边界越来越模糊。
我们也聊了网络环境带来的安全问题。今天主流的假设是网络链路是不可信的,在不可信的网络之上如何去做安全的通讯,可以做到防窃听、防篡改、防钓鱼。这也是苹果前几年强制要求 iOS App 必须走 HTTPS 协议的原因。
如果你对今天的内容有什么思考与解读,欢迎给我留言,我们一起讨论。本章关于操作系统的话题到此就结束了。下一讲我们结合前面的内容,讨论并实战架构第一步,怎么做需求分析。
如果你觉得有所收获,也欢迎把文章分享给你的朋友。感谢你的收听,我们下期再见。
分享给需要的人,Ta购买本课程,你将得20
生成海报并分享

赞 19

提建议

上一篇
15 | 可编程的互联网世界
下一篇
17 | 架构:需求分析 (上)
unpreview
 写留言

精选留言(40)

  • KEN.Z
    2019-06-14
    问一下许老师, "这样,木!马程序和正常的软件代码同属于一个进程内,所有信息对其仍然一览无余。" 这个是通过何种方式实现的呢?

    作者回复: 把自己加到一个正常程序的尾部,然后修改程序入口,让它跳转到自己,执行完自己后再跳转回正常的程序代码。这样在用户看来这个程序功能没有发生变化,但是实际上每次开始的时候都会先运行病毒/木马程序再运行正常功能代码。

    共 3 条评论
    50
  • pawhrmyki
    2019-06-07
    看过一个讲rsa原理的文章,非常清楚,推荐给大家~~http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html
    20
  • Chen
    2019-06-12
    Android从6.0开始在运行时向用户索要权限,版本越高越重视用户的隐私。运行时索要权限毕竟麻烦,很多开发者有意将版本降至6.0以下。现在谷歌和一些应用厂商开始采取一些措施避免这种行为。谷歌开始强制App适配更高版本,华为应用市场8月1日后禁止基于8.0以下的应用更新和上架。

    作者回复: 感谢补充

    15
  • Smallfly
    2019-06-08
    许老师,病毒为什么要复制自己,每个功能都一样,不是多余么?即使有必要,它在运行中又是怎么实现自我复制的呢?

    作者回复: 病毒复制自己到所有的可执行程序,让自己成为其他程序的一部分,这是为了生存。被感染的程序越多,它被消灭的概率就越低。

    15
  • hxy
    2019-06-07
    Android 现在也是运行时索要权限吧?很久以前确实是安装的时候

    作者回复: 平常没怎么用android。我只知道第一个把索要权限改到运行阶段的是魅族,好多年前的事情了,当时小米手机可能还没有出来,让我大大惊讶了一番。

    9
  • Luke
    2019-06-10
    老师此篇写的很精辟,各个场景都覆盖到了。 关于安全,只能说是相对安全,我们实际架构时,也只能根据实际情况制定合适的方案,在速度,安全等方面权衡。
    5
  • sam
    2019-06-07
    凌晨4点多醒来,看到许老师更新,一口气读完,大脑出奇的清醒,再读前面几篇。
    5
  • 不温暖啊不纯良
    2021-04-02
    非对称加密就是我需要你给我传送信息的时候,我造一把钥匙一把锁,我把锁子打开给你,你把内容装进箱子,用我给你的锁锁上箱子,然后把箱子传给我,我在打开箱子之前,先看看锁有没有被撬过,如果有就说明箱子里面的内容已经不可靠。 所对应着公钥,钥匙是代表私钥。

    作者回复: 很形象的比喻

    4
  • Cc°°
    2019-06-17
    我在6月14号的留言,得到了老师的回复:使用对称加密!表示感谢!但是并没有解答我的疑问,对称加密的密钥也是需要在A和B之间进行传输的,如我问题中所说,如何保证对称加密的密钥的安全呢?因为使用B-private-key加密的对称加密密钥给A,中间人使用B-public-key是可以解开的!烦请老师解惑,多谢!

    作者回复: 1、首先random-key是A给B发的,不是反过来。 2、A给B发用的是B-public-key,所以只能B解得开。而B给A回复只需要用random-key对称加密回复,这个东西现在只有A和B知道。

    4
  • 魏颖琪
    2019-06-09
    HTTPS的证书获取流程,我的理解是B的证书是在A向B访问中获取,而不是向G获取。然后通过G的公钥(通常在操作系统或者浏览器)来验证这个证书的可信度,并通过这个证书获取B的公钥。在我们的应用中,通常将证书放在nginx中。

    作者回复: 对的

    4
  • 悠游
    2020-05-18
    https的本质就是在一个不可靠的信道上,基于数字证书和非对称加密协议生成一个对称的加密协议,进行可靠的通信

    作者回复: 是这样

    3
  • 丁丁历险记
    2019-10-27
    太客气了,运营商篡改可以直接点名的,包括移动电信联通。
    3
  • hua168
    2019-06-07
    老师现在很多网站用的是linux(centos,ubuntu),怎么样保证安全,我这样对吗? 1. 禁止远程公认的大权限账号如root,sa,administrator等 2. 禁止不用的端口,不能禁止就修改如22端口,修改其它 3.开启防火墙如iptable 如果入侵怎么跟踪分析别人入侵路径的?
    展开

    作者回复: 服务器安全很专业的一个话题,我不是这方面的专家。从入侵跟踪来说,我觉得要做好两件事情,一个是日志记录,而且要把日志做成服务性质而不要只是本地日志,因为高明的黑客会擦脚印。二是异常告警,发现可疑行为就通知人工介入。

    共 2 条评论
    3
  • 2019-06-12
    一门深入 长时薰修 我当奉持 如法修行
    共 1 条评论
    2
  • 幻灰龙
    2020-02-23
    PKI/CA机制是中心认证机制,但是中心出如果不可信,信任体系就完蛋。非中心化的方式例如基于朋友圈认证的OpenPGP或者GNUPG加密邮件的方式,或者像BlockChain这种通过智能合约的方式,把信任转嫁到不可撤销的货币合约上。更进一步,直接假设中心的不可信,使用复杂的零知识证明原理实现提供数据服务但是不暴露数据给任何中心或者第三方,可惜zero-zkSNI
    共 1 条评论
    1
  • wanhex
    2019-07-31
    强烈建议老师出一门网络安全的专栏,惭愧啊,做了好几年的网络安全,对于网络安全的理解还没有老师的一篇文章透彻,惭愧惭愧啊
    1
  • humor
    2019-07-20
    许老师好,我有一个关于操作系统的安全问题想请教一下。怎么保证操作系统(比如linux)本身的安全性呢,比如HTTPS协议生效的前提是Linux事先植入了权威机构的公钥,那如果这个公钥是有问题的呢?换句话说如果Linux的发布者“监守自盗”怎么办呢?更广义一点,怎么保证Linux本身不会窃取服务器中的信息呢,包括文件、内存还有数据库等。红帽等Linux厂商的发布镜像会有权威机构检测吗

    作者回复: 这个问题的确存在,不过一般不是发行商的问题,而是发行渠道。红帽不敢瞎搞,但是一些发行渠道会修改发行的系统,甚至带上恶意软件。在信得过的网站下载操作系统和软件,这是一个非常重要的常识。

    共 2 条评论
    1
  • Aaron Cheung
    2019-06-11
    打卡16 深入了解了 ssl 不再是表面那一点
    1
  • yxhuang
    2019-06-10
    许老师,Android 在 6.0 版本及其以上,也开始需要运行权限了。

    作者回复: 多谢补充

    1
  • VicX
    2019-06-08
    文章开头对于实模式和保护模式的讲解是否不够精确?CPU保护模式能访问比实模式更大的地址域,内存的合理隔离完完全全是靠的虚拟内存

    作者回复: 关于实模式和保护模式请看第 07 篇

    1