计算机科学入门
过去我们讲了计算机如何互连,让我们能瞬时跨全球沟通,但不是每个使用网络的人都会规规矩矩,不损害他人利益。
就像现实世界中我们用锁和栅栏保证物理安全,有警察减少犯罪,我们需要网络安全减少虚拟世界中的犯罪。
计算机没有道德观念,只要给计算机写清具体问题,它们很乐意地闪电般算出答案,破坏医院计算机系统的代码和保持病人心跳的代码,对计算机来说没有区别。
就像 原力
一样,计算机可以被拉到 光明面
或 黑暗面
,网络安全就像 绝地武士团 ,给网络世界带来和平与正义。
出自《星球大战》。
保密性,完整性,可行性
计算机安全的范围,和计算能力的发展速度一样快,我们可以把计算机安全,看成是保护系统和数据的: 保密性
(secrecy), 完整性
(integrity)和 可用性
(availability)。
保密性
是只有有权限的人,才能 读取 计算机系统和数据,黑客泄露别人的信用卡信息,就是攻击保密性。
完整性
是只有有权限的人,才能 使用 和 修改 系统和数据,黑客知道你的邮箱密码,假冒你发邮件,就是攻击完整性。
可用性
是有权限的人,应该 随时 可以访问系统和数据, 拒绝服务攻击
(Distributed denial of service attack),简称 **DDOS ** ,就是黑客发大量的假请求到服务器,让网站很慢或者挂掉,这就是攻击可用性。
威胁模型分析
为了实现这三个目标,安全专家会从,抽象层面 想象 "敌人" 可能是谁,这叫 威胁模型分析
(threat model),模型会对攻击者有个大致描述:能力如何?目标可能是什么?可能用什么手段?
攻击手段又叫 攻击矢量
(attack vector), 威胁模型分析
让你能为特定情境做准备,不被可能的攻击手段数量所淹没,因为手段实在有太多种了。
假设你想确保笔记本计算机的 物理安全 ,你的威胁模型是 "好管闲事的室友" ,为了保证保密性,完整性和可用性,你可以藏在脏兮兮的洗衣篮里。
但如果威胁模型是调皮的兄弟姐妹,知道你喜欢藏哪里,那么你需要更多保护:比如锁在保险箱里。
换句话说,要怎么保护,具体看对抗谁。
当然,威胁模型通常比 "好管闲事的室友" 更正式一些,通常威胁模型分析里会以 能力水平 区分。
比如 "某人可以物理接触到笔记本计算机,而且时间无限" ,在给定的威胁模型下,安全架构师要提供解决方案,保持系统安全。
只要某些假设不被推翻,比如没人会告诉攻击者密码。
保护计算机系统,网络和数据的方法有很多,很多安全问题可以总结成 2 个问题:你是谁?你能访问什么?
权限应该给合适的人,拒绝错误的人,比如银行员工可以打开取款机来补充现金,但我不应该有权限打开,因为我会把钱全拿走!
身份认证
所以,为了区分谁是谁,我们用 身份认证
(authentication),让计算机得知使用者是谁。
身份认证有三种,各有利弊:你知道什么?你有什么?你是什么?
你知道什么?
你知道什么
是基于某个秘密,只有用户和计算机知道,比如 用户名和密码 。
这是如今使用最广泛的,因为最容易实现,但如果黑客通过猜测或其他方式,知道你的密码,就惨了,有些密码很容易猜中,比如 12356
或 qwerty
。
但有些密码对计算机很容易,比如 PIN 码:2580, 看起来很难猜中,起码对人类来说是这样,但 4 位数字,只有一万种可能,一台计算机可以尝试 0000,然后 0001,然后 0002,然后到 9999,不到一秒内试完,这叫 暴力攻击
(brute force attack),因为只是试遍一切可能。
这种算法没什么聪明的地方,如果你错误尝试 3 次,有些系统会阻止你继续尝试,或让你等一会儿。
这个策略普遍而且合理,对于一般的攻击者确实很难,但假设黑客控制了 数以万计 的计算机,形成一个 僵尸网络
,用这么多计算机尝试密码 2580 ,同时尝试很多银行账户,即使每个账户只试一次,也很可能碰到某个账户刚好用这个 PIN 。
增加密码长度有帮助,但即使 8 位数字的 PIN 码也很容易破解,这就是为什么现在很多网站要求 大写 + 小写字母
,还有 特殊符号
等,大大增加可能的密码。
8 位数字的 PIN 只有一亿种组合,对计算机轻而易举,但包含各种字符的 8 位长度密码,有超过 600 万亿种组合。
当然,这些密码会难以记住,所以更好的方法是选一些更好记的东西,比如三个单词连在一起: 格林兄弟好厉害
或 披萨尝起来好好吃
。
英文大约有 10 万个单词,所以三个单词连一起大概有,1 亿亿种可能,想猜中的话,祝你好运!
另外使用不在字典内的单词被猜中的可能性更低,但我们没时间细说这个。
你有什么?
你有什么
这种验证方式是基于用户有 特定物体 ,比如钥匙和锁,如果你有钥匙,就能开门,这避免了被人 "猜中" 的问题,而且通常需要人在现场,所以远程攻击就更难了,但如果攻击者离你比较近,那么也不安全,钥匙可以被复制,手机可能被偷,锁可以撬开。
你是什么?
最后, 你是什么
这种验证,是基于你把 特征 展示给计算机进行验证,生物识别验证器,比如 指纹识别器 和 虹膜扫描仪 就是典型例子。
这些非常安全,但最好的识别技术仍然很贵,而且,来自传感器的数据每次会不同。
你知道什么
和 你有什么
。这两种验证是 确定性 的,要么正确,要么错误。
如果你知道密码,或有钥匙,那么 100% 能获得访问权限,如果没有,就绝对进不去,但 生物识别
是概率性的,系统有可能认不出你,可能你戴了帽子,或者光线不好,更糟的是,系统可能把别人错认成你,比如你的邪恶双胞胎。
当然,在现实世界中几率很低,但不是零,生物认证的另一个问题是 无法重设 ,你只有这么多手指,如果攻击者拿到你的指纹数据怎么办?你一辈子都麻烦了。
最近还有研究人员表示,拍个照都有可能伪造虹膜,所以也不靠谱。
所有认证方法都有优缺点,它们都可以被攻破,所以,对于重要账户,安全专家建议用 两种 或 两种以上 的认证方式,这叫 双因素
或 多因素
认证。
攻击者可能猜出你密码,或偷走你的手机,但两个都做到,会比较难。
访问控制
身份验证
后,就来到了 访问控制
,一旦系统知道你是谁,它需要知道你能访问什么,因此应该有个规范,说明谁能访问什么,修改什么,使用什么。
这可以通过 权限
(Permissions)或 访问控制列表
(Access Control Lists),简称 ACL 来实现,其中描述了用户对每个文件,文件夹和程序的访问权限。
读
权限允许用户 查看 文件内容, 写
权限允许用户 修改 内容, 执行
权限允许用户 运行 文件,比如程序。
有些组织需要不同层级的权限,比如间谍机构, 访问控制列表
的正确配置非常重要,以确保保密性,完整性和可用性。
Bell-LaPadula 模型
假设 我们有三个访问级别:公开,机密,绝密。
第一个普遍的好做法是,用户不能 读上
,不能读等级更高的信息,如果用户能读 机密
文件,那么不应该有权限读 绝密
文件,但能访问 机密
和 公开
文件。
第二个法则是用户不能 写下
,如果用户等级是 绝密
,那么能写入或修改 绝密
文件,但不能修改 机密
或 公共
文件。
听起来好像很奇怪,有最高等级也不能改等级更低的文件,但这样确保了 绝密
,不会意外 泄露 到 机密
文件或 公共
文件里。
这个 不能向上读,不能向下写 的方法,叫 Bell-LaPadula 模型
,它是为美国国防部 "多层安全政策" 制定的,还有许多其他的访问控制模型比如 中国墙模型
和 比伯模型
,哪个模型最好,取决于具体情况。
身份验证
和 访问控制
帮助计算机知道 你是谁 ,以及 你可以访问什么 ,但做这些事情的软硬件必须是可信的。
这个依赖很重要,如果攻击者给计算机装了 恶意软件 ,控制了计算机的操作系统,我们怎么确定安全程序没有给攻击者留后门?
我们仍然无法保证程序或计算机系统的安全,因为安全软件在理论上可能是 "安全的" ,实现时可能会不小心留下漏洞。
但我们有办法减少漏洞出现的可能性,比如一找到就马上修复,以及当程序被攻破时尽可能减少损害。
大部分漏洞都是具体实现的时候出错了,为了减少执行错误,减少执行,系统级安全的圣杯之一是 安全内核
(security kernel),或 可信计算基础
(trusted computing base),一组尽可能少的操作系统软件,安全性都是接近可验证的,构建安全内核的挑战在于决定内核应该有什么,记住,代码越少越好!
在 最小化 代码数量之后,要是能 "保证" 代码是安全的,会非常棒。
独立安全检查和质量验证
正式验证代码的安全性是一个活跃的研究领域,我们现在最好的手段,叫 独立安全检查和质量验证
(Independent Verification and Validation),让一群安全行业内的软件开发者来审计代码,这就是为什么安全型代码几乎都是 开源 的。
写原始代码的人通常很难找到错误,但外部开发人员有新鲜的眼光,和不同领域的专业知识,可以发现问题,另外还有一些安全大会,安全专家可以相互认识,分享想法。
一年一次在拉斯维加斯举办的 DEFCON
,是全球最大的安全大会。
隔离
最后,即便尽可能减少代码并进行了安全审计,聪明的攻击者还是会找到方法入侵,因为如此,优秀的开发人员应该计划当程序被攻破后,如何限制损害,控制损害的最大程度,并且不让它危害到计算机上其他东西,这叫 隔离
(isolation)。
要实现隔离,我们可以 沙盒
(sandbox)程序,这好比把生气的小孩放在沙箱里,他们只能摧毁自己的沙堡,不会影响到其他孩子。
操作系统会把程序放到沙盒里,方法是给每个程序 独有 的内存块,其他程序不能动。
一台计算机可以运行多个虚拟机,虚拟机模拟计算机,每个虚拟机都在自己的沙箱里,如果一个程序出错,最糟糕的情况是它自己崩溃,或者搞坏它处于的虚拟机,计算机上其他虚拟机是隔离的,不受影响。