陈颂光
全栈工程师,能够独立开发从解释器到网站和桌面/移动端应用的各类软件。
关注我的 GitHub

理解信息安全

随着信息的价值不断被挖掘,以意想不到的方式获取和修改信息、取得别人的计算能力变得有利可图。要降低成为受害者的可能性,就有必要了解攻击者的经济学和技术手段,识别自身风险,从而在合适层面用合适的方式应对。不会攻击,就不会防护。

信息安全模型

信息安全传统上有三个目标(过往重要性按是按以下顺序排列,但现在已反转),它们分别面临一些威胁:

  • 数据机密性,即只有指定的人可以读取指定数据
    • 存储设备遗失或被盗
    • 嗅探或截取网络通信
    • 敌人在附近收集热、电磁辐射、光或声波
    • 离职或受到威迫利诱的员工
    • 恶意软件
  • 数据完整性,即只有指定的人可以修改指定数据
    • 设备或介质损坏
    • 老鼠在卡片上咬出一个孔
    • 人员误操作
    • 恶意软件
  • 系统可用性,即指定的人可以使用系统而其它人不能
    • 拒绝服务攻击通过大量浪费系统资源使其它合法用户几乎不能用系统
    • 僵尸网络控制别人的计算机用于发送垃圾邮件等用途

威胁的来源称为入侵者,它们包括:

  • 脚本小子,她们没有特定目的(只出于好奇心),通常也没有明确的攻击目标,缺乏发现漏洞和设计攻击的能力,只会套用现成的具体攻击方法,这类人是最常见的攻击者
  • 内部人员(包括承包商的)如学生、程序员、操作员和各类技术人员,她们有一定技术能力(能利用已知漏洞)且愿意付出一些努力
    • 出于挑战心态,如提前知道工资或职位变动
    • 出于报复心态,如被处分的员工可能故意为公司制造麻烦
    • 出于利己心态,如把舍入改为截断然后把尾数据为己有
  • 间谍,她们受竞争对手指使以便获取机密信息(如技术、设计、交易)或进行破坏(如引致防空系统失灵),有强烈动机和能力(能发现新漏洞),这类人比较罕见

安全模型指定对什么人(或者组或角色,下面抽象为域)对什么对象能做什么、不能做什么。为了保证安全性,应该按最低极限原则。安全模型的表示方式有:

  • 保护矩阵,每个域对应一行、每个对象对应一列、每个单元格记录容许的操作,由于矩阵稀疏此法往往占用过多空间
  • 访问控制列表,对每个对象关联一个列表以描述每个域中能对它干什么
  • 权能,对每个域关联一个列表以描述对每个对象中能干什么

对于采用自主访问控制(而非强制访问系统)的系统,一个用户可能可把她持有的权限委任给其它域。这时,一个完美的安全模型不仅要考虑用户现在是否有某个权限,还要考虑用户是否可利用现有权限获得该权限。

不同的保护目标对应不同的保护模型,设想把用户按职级分为若干类,数据也按机密性分为若干级,如:

  • 为了保证机密性,一个模型(Bell-LaPadula)是只许向下读(将军可以读中校的文件,但中校不可以读将军的文件)和向上写(将军不能泄露信息给中校,但中校可以告诉将军她知道的情况)
  • 为了保证完整性,一个模型(Biba)是只许向上读(将军不可以读中校的文件,但中校可以读将军的文件)和向下写(将军可以改变中校的命令,但中校不可以改变将军的命令)

可见,各个保护目标有时是相互矛盾的,必须按实际需要进行取舍。然而,安全性同样只是众多权衡因素中的一个,不能期望绝对的安全,抵抗恶作剧和国家级攻击不是一个难度,只能是够用就好:

  • 向后兼容性同时也意味着保留原有系统中的许多脆弱性
  • 保持安全性要求降低复杂性,需要砍掉一些特性
  • 大量安全性检查会降低性能

保护措施是为了使攻击者付出的代价大于她的得益,可分为:

  • 事前的预防(如访问控制、防火墙)
  • 事后的检测(如入侵检测系统)和响应(如恢复或取证)

结合多种不同粒度和原理保护措施可明显加大攻击的难度,良好的分层甚至可通过避免多余检查而减低开销。保护措施应该尽可能是自动化的,因为依赖人手操作的流程经常得不到落实。而如果存在一个缺口,则其它方面再稳固也是没有用的。为了检验系统的安全性,可以由自己用已知的攻击工具尝试攻击,由专业的第三方进行渗透测试也是方法。

一般攻击与防御

内部攻击

内部攻击由内部人员实施,她们拥有别人没有的知识和权限,因此特别难以防范且可进行针对性强的任务,内部攻击比外部攻击更危险。他们可能是故意的(为自己利益或受他人利益),也可能是被骗的(如冒充同事或高管的助手,一个实验发现冒充医生通过电话下令向病人注射不合理的药物能让许多护士上当)。

  • 逻辑炸弹,即在软件代码中注入通常不会执行的逻辑,例如只有输入开发者知道的口令系统后才继续工作,或者在发现自己的工号从发薪册消失便进行破坏,它们通常作威胁以防止自己失业(重新聘她为顾问才给解决问题)
  • 后门,即故意在代码插入脆弱性,如使某个密码可登录任何用户,以便开发者以后可绕过正常的认证过程取得系统的控制权。这后门也可能被外部攻击者发现并利用。
  • 登录欺骗,即设立一个仿冒的登陆屏幕,用于从合法用户骗取密码,然后才跳转到真正的登陆屏幕。这可通过不可捕获的按键组合击败。

防范这些攻击通常用代码审查,保证测试覆盖也可能有帮助。

安全意识不是可以轻易培训出来的,人永远是最薄弱的环节。

外部攻击

恶意软件

通过网络是最常见的,标准流程为:

  1. 踩点,即寻找攻击的目标。这可能是随意的,但聪明的攻击者会想方设法把范围缩窄到容易攻击的潜在目标以提高成功机会,比如:
    • 如果某公司招聘网管频率过高,则可能说明公司系统有严重问题以致没人愿意接手
    • 如果某公司最近大幅裁员或有收购合并等重大变动,计算机系统也可能处于一片混乱中
    • 通过whois找刚上线的服务器,它们的管理员更可能经验不足,并且可能仍然使用默认配置(一些常见web系统有众所周知的默认密码)和还没有打补丁
    • 通过搜索引擎寻找使用有疑似脆弱代码(如<input name="total" type="hidden"/>)、使用有已知漏洞CMS或使用默认配置的站点。
  2. 扫描,即通过端口扫描寻找有已知漏洞的程序版本。
  3. 查点,即连接到目标机器并触发已知漏洞。为了增加追查的难度,可能使用tor之类迂回的路线。
  4. 权限提升
  5. 想干的事情
  6. 消除痕迹或为下次入侵提供方便

典型的漏洞类型有:

  • 缓冲区溢出攻击是漏洞的最主要来源,由于C语言不作边界检查,有可能用数据覆盖返回地址,从而在过程结束时返回到攻击者指定的位置(攻击代码通常也在栈上,但即使禁止执行栈上代码,还可能返回到strcpy让它把代码复制到数据段),并保持进程原有的权限。防范缓冲区溢出攻击要求仔细地编码(特别是有高权限的程序),如不要用固定大小的数组缓冲用户的全部输入,代码静态分析工具可以帮助找出一些潜在的脆弱性,如调用了gets,但大量已经存在的C代码中的脆弱性难以修复。为了说明缓冲区溢出攻击防不胜防,考虑一个程序接收宽度和高度来创建图像,则宽度和高度填入大数后它们的乘积会溢出于是程序申请的空间不足,造成缓冲区溢出。
  • 格式化字符串攻击,C语言的printf格式化字符串中用%i可修改内存,如果格式化字符串部分来自用户,可能导致问题
  • 代码注入攻击,当运行了部分来自不可信外部的代码就可能意外运行了不应该运行的代码(这是文本脆弱性的又一体现),对抗方法是验证输入、转义或预编译
    • SQL注入,比如若服务器端脚本返回来自SELECT * FROM scores WHERE class='$cls' AND user='$user_id'的结果以便告知一个学生她某门课的成绩,但别有用心的学生在查询课程名高等数学'--,则服务器把它代入$cls后便查询并返回了所有学生的高数成绩(她不应知道的)。SQL注入不但可能导致泄漏数据,也可能导致数据修改(在上例中在注释号前加分号和修改语句即可)。
    • javascript注入,如果一个在线论坛不对回复适当处理,则一个用户在回复中包含的javascript代码将被其它阅读回复的人的浏览器执行,可能导致重定向到仿冒网站或者盗用身份进行一些操作(假如银行用coookies标识用户,则重写向到http://www.bank.com/transfer.php?to=007&amount=10000可能导致在用户不知情下向007帐号转帐10000块钱)
    • shell注入,如一个程序用perl之类写就可能导致用户可运行shell命令

恶意软件的用途包括:

  • 收集信用卡号和密码等敏感信息
  • 收集用户的消费习惯用于营销
  • 用用户的身份进行转帐等操作
  • 加密用户文件进行勒索
  • 发送垃圾邮件
  • 发起拒绝服务攻击
  • 更改浏览器主页、搜索引擎或增加工具条
  • 更改默认应用程序
  • 显示大量广告或把其它广告替换掉

恶意软件的传播方式分为:

  • 蠕虫利用已知漏洞通过网络主动传播自己,用户不用任何特殊操作都可被感染,最著名的是Morris在1988年的恶作剧
  • 病毒是被植入到其它程序中的,可能藏匿在不同地方:
    • 覆盖病毒,即修改系统中的可执行文件,通常会在大多数情况让它们正常工作以降低被发现的可能性,选择附在各段的填充位而非后端的病毒不改变文件大小也可降低被发现的可能性。
    • 设备驱动病毒,即修改驱动程序,因为驱动程序往往在内核态运行,可以做很多事情
    • 引导扇区病毒,即修改引导扇区(可能借助坏块重映射)或主引导记录,从而可修改中断向量再启动操作系统,只要操作系统没有及时设置时钟中断,病毒就能反复通过时钟中断取得控制并把保持指定的中断向量恶意,于是以后一旦发生指定中断病毒就可取得控制,这样可捕获所有系统调用
    • 宏病毒,即在容许宏的文档中插入恶意代码,重灾区是微软office文档中的宏和IE中的ActiveX控件,HTML或PDF文档中的javascript因能力有限危害性低一些。
    • 源代码病毒,即修改程序源代码,从而重新编译时能加入恶意行为,这方法是可移植的,感染到软件开发者的话能产生大范围危害。一种更隐蔽的方法是感染编译器控制它产生的代码。
    • 管理程序rootkit,它在虚拟机中运行整个操作系统,于是在操作系统中几乎看不出异常,但性能下降或计时与外部时钟不一致仍然可能导致被发现
    • 内核rootkit,它修改内核模块,Sony曾在CD中的自启动程序autorun.inf中秘密向用户的机器安装一个rootkit,用于阻止复制和收集用户收听习惯
    • 库rootkit,它修改libc之类的常用库
  • 木马是用户主动运行的,但暗中进行用户不知道的任务,它引诱用户运行的方法包括:
    • 包装成带有对用户有用的软件,如游戏或解压软件
    • 被其它恶意程序放在搜索路径中,使用户无意地运行错误程序(Unix中把仿冒程序放在比真的更前的搜索路径、或在DOS中放置对应于.exe文件的.com文件、或修改符号链接的目标)或因拼写错误而运行(如放置一个la期望用户把ls拼错)

恶意软件通常会潜伏一段时间,在已经大面积感染后才发作以免过早被发现从而清除。恶意软件还可能通过压缩、变异(在传播时生成效果相同的不同代码,如交换指令顺序、改变寄存器、等价指令替换和插入无用指令)来增加被识别的难度。

然而,最成功有攻击大多是还是基于社会工程学的,计算机只是它的其中一个现代媒介。

  • 木马的功能吸引人下载
  • 病毒常隐藏在标题吸引的邮件或页面中的附件,可能用已感染机器的用户名义向通信录中的人发出以增加可信性,在外地的网吧散布病毒可能可增加追踪源头的难度
  • 钓鱼网站注册一个与银行(或其它网站)域名差不多的域名,并部署一个与银行网站看起来差不多的网站,由此欺骗用户输入敏感信息

恶意软件的防御方法有:

  • 更新系统,绝大多数恶意软件利用已知的软件漏洞而非零日漏洞,它们大多已经被软件开发者修正,只要确保所有软件都已经打上最新的补丁即可避免受到入侵
  • 最少化功能,只启用必需的功能和帐号,从而减低暴露脆弱性的机会,每个服务只给予所需的最低权限,能不连网就不连网,能不带CD-ROM、USB接口就不带,同时避免泄露系统的信息(别人可能从垃圾中扔掉的说明书推测到)
  • 防火墙,用于阻止恶意软件进入系统,主要是防范来自网络的(但原则上对I/O也可这样干),它可以用硬件或软件实现。对于同时提供外部服务和内部服务的网络可能需要两层防火墙。配置防火墙的规则(如白名单和黑名单)时应尽可能允许正常的连接而拒绝其它
    • 无状态防火墙把包看作相互独立的,通常只检查包头,按IP地址和端口决定通过还是丢弃
    • 有状态防火墙维护连接状况,从而可制定更精细的规则,如不允许主动连接进来
  • 反病毒软件,用于检测并消除已经进入系统的恶意软件
    • 静态检测,由反病毒软件厂商维护一个经常更新的病毒特征数据库,反病毒软件也经常与之同步,然后在文件系统、MBR、引导扇区、坏扇区列表、ROM、CMOS中是否有已知病毒的特征,有则向用户报告(可能误报或漏报)并建议处理方法。扫描整个文件系统是耗时的,一个优化是增量扫描(只重新扫描上次扫描后长度或散列值发生变化的文件)。对于会干扰检测软件的rootkit,可能要用外部介质引导才能检测出。
    • 动态检测,即捕获所有系统调用并禁止可疑的行为,但容易误报且会明显降低程序运行速度
  • 完整性检查,即只容许指定的程序运行,如
    • 检查系统所有运行程序的散列值与一个被认为干净的时刻相同,这需要密码学技术来避免散列值文件被修改(最好有硬件支持)
    • 要求程序由可信的担保机构进行数字签名
    • Java运行期系统验证字节码文件以保证合法性
  • 入侵检测系统(IDS),可以对入侵进行更精细的建模,通过持续监视,在主机或网络边界出现指定的情况(如登录失败、端口扫描等等)时,发出报警并进行记录,主动的IDS也可能作其它响应(如开关进程、复位连接(TCP reset)、修改防火墙规则)。加密通信可能妨碍IDS工作。
    • 基于特征的入侵检测系统在发现系统行为匹配一些已知的受攻击特征吻合时报警,缺点是不能发现新的攻击方式
    • 基于统计的入侵检测系统在发现系统行为发生突变时报警,缺点是容易误报
  • 沙箱,即在与重要设施隔离的环境如虚拟机中运行程序以限制危害
    • 在功能受限的解释器上运行程序,Java就可制订相当仔细的安全策略,如只能访问若干目录
    • 用蜜罐吸引攻击是了解攻击特征的一个方法,当然病毒也会设法检查它是否运行在沙箱中。

在攻击与防御间的斗争会一直持续下去,如病毒会设法欺骗反病毒软件,反病毒软件又会设法反抗。

其它威胁

拒绝服务攻击企图损害可用性。拒绝服务攻击最常见的手段是耗尽目标系统的资源(带宽、内存、CPU、磁盘时间等等),导致它不能正常提供服务。

  • 垃圾邮件攻击中,大量的邮件被发送到目标系统,导致目标系统用光磁盘。为了增加追查难度,FROM往往填写虚假的源。
  • SYN洪水攻击中,短时间内大量的TCP的SYN包被发送到目标系统但不发送ACK包,导致目标系统为这些连接预留大量内存而用光内存。为了增加追查难度,数据包往往填写虚假的源IP。防范方法是使用SYN cookies,把连接信息(如IP、端口)用加密哈希函数生成序号,而不是记在内存。
  • ping洪水攻击中,短时间内大量的ICMP包被发送到目标系统,导致目标系统的带宽用尽。因此,不少防火墙屏蔽ICMP。

为了发送尽可能多的包来瘫痪目标系统,攻击可能同时从大量系统(通常是被恶意软件控制的机器)同时发出,这叫拒绝服务攻击。另一种借刀杀人方法是冒充目标系统向其它服务器发出精心设计的请求,从而让这服务器把更大的包响应给目标系统,这叫放大攻击。

中间人攻击企图损害机密性和完整性,方法是分别向通信双方冒充是对方,经典的方法包括猜测序列号而劫持TCP会话。防范方法是正确地实现通信双方身份的鉴别,虽然已经知道如何做,但仍然有许多会话没有合适的防护。为了增加中间人攻击的说服力,往往会与ARP欺骗或IP欺骗或DNS欺骗(向对方ISP发DNS请求然后在ISP对外询问时马上向ISP发送伪造的应答以污染其缓存)联合使用。

重放攻击通过重复利用合法信息来达到不合法用途,如收集敌机的识别信号后在己方的机播放企图让敌方误认为友机,又或卖方复制买方的电子支票要求银行多次付款。防范方法是正确地实现各种协议,特别是时间概念。

一些威胁称不上攻击,但也会意外泄漏重要信息,并被难以预测的方式使用,包括:

  • 公共的邮箱服务提供者能阅读所有经手邮件,可能用于投放精准广告
  • 你的位置可能被获取,可能用于跟踪
  • 一些机密信息可能可从公开的信息中导出,如公开了平均值但实际上只有一个样本

然而,保障隐私与监控罪犯是矛盾的,如何取舍不是纯技术的问题。

辅助技术

物理安全

物理安全是一道基础防线,其它安全措施多建基于它,因为如果敌人能接近你的机器(包括路由器等网络设备,无线网覆盖也不要超出公司范围),那可以干的事可多了,而且很多其它防范形同虚设。

你在不知不觉间可能泄露很多消息:

  • 有人在你后面而不知
  • 你上洗手间或吃饭时有别人使用了你没有退出的机器
  • 把网线连接到内网的接口
  • 别人用Live CD启动你的机器
  • 由于敲不同键发出声音有细微区别,录下声音就可确定你在输入什么
  • 晚上通过窗外看到你的脸反射来自屏幕的光可确定屏幕上的内容
  • 通过测量附近供电线路电流可算出的的机器的功率从而负载情况
  • 通过测量热量分布可算出的的机器的功率从而负载情况
  • 通过监控附近网络线路或无线电嗅探通信内容
  • 有伪基站进行中间人攻击窃取手机通话内容

更有甚者别人可以故意造成破坏,如:

  • 切断供电(所以可能要UPS系统来保证正常关机不丢失数据,甚至加上后备发电机)
  • 纵火(所以可能要在外围设立防火带和火情探测与灭火系统)
  • 制造水浸(可能通过触发灭火系统造成,真的被淹应先排水再尝试用冷风风干)
  • 切断通风使系统过热

防范上述攻击的基本方法就是设法保证没有外人能接近重要的机器,如聘请警卫,同时用监控摄像头作事后检测手段。多层屏障可提高安全性,内层安全措施可做得更隐蔽,必要时在层间设立开阔区域防爆。但要明白门禁系统(如随在合法人员后面)、物理锁(如撬锁、撞锁、配钥匙或换锁)、门、地板、天花板、墙、空调系统、摄像头、传感器、甚至监控管道气压以检测搭线的装置等等也是可被攻击的,只能做到适度安全。为了应付一旦发生灾难的情况,应当建立物理隔绝的备份。

身份认证

在实现安全模型时,首先需要判断用户是谁,这就是认证的问题。认证可以依据:

  • 用户知道的东西,如:
    • 口令,但口令在多方面可能被猜到(许多人用一些常用词作为口令、用自己的名字或出生日期作口令、使用默认口令、在多个系统中使用相同的口令)。存在一些的策略如限制尝试次数以抵抗猜测但会降低可用性(假如邮箱系统限制错误尝试次数,则可轻易通过乱输密码把别人的邮箱冻结),而且要确保策略严格执行不易,可能只营造的虚假的安全感,如只要能访问Unix的passwd文件(其中有用户名、盐和口令加盐后的散列值)便可任意次猜、对BIOS加密后别人还可把硬盘检走再读。强制强密码或定期更换则可能导致用户因记不住而明文保存或写下,从而在另一方面降低安全性。
    • 一次性口令,第n次或第n个时间段用的口令由初始口令经单向函数作用n次的结果,从而防止重放,见于网上银行的动态口令牌
    • 挑战-响应,向用户提问并要求用户正确回答才允许登录,如以一个函数为密钥,要求用户回答一个随机数对应的函数值
  • 用户有的东西,如:
    • 磁带卡,其中用磁带记录信息,读写磁带的设备容易获得使磁带卡便宜但容易伪造,用在信用卡和借记卡等
    • 芯片卡,其中有小型集成电路
      • 储值卡,其中有与ROM类似的非易失存储单元,也已经比较便宜
      • 智能卡,其中有ROM、RAM和CPU,从而可以较安全地脱机操作(其中涉及随机数挑战,这样重放并不管用,但功率分析攻击是可能的),常用于交通卡等等
    • 生物特征,由于即使同一个人的样本间也不会完全相同,生物特征一般只能模糊识别,要在接受非法用户与拒绝合法用户间权衡,可用的特征有:
      • 指纹,容易采集,但是指纹已经很容易伪造(复印足以欺骗光学识别、指纹套可以欺骗其它)
    • 虹膜,仍可能拍下别人虹膜后用隐形眼镜假冒
    • 笔迹,识别笔划顺序、速度、书写压力或其它细节,但即使同一人也有较大差别
    • 声音,但即使同一人也有较大差别(如感冒)
    • 脸型,但可能用面具冒充

自己实现认证机制容易出错,利用久经考验的第三方认证机制可能更为稳妥,如利用手机号识别用户。在要求高机密性和完整性时,可能用多重认证(常见卡类加口令如银行卡、卡类加指纹如证件),但可能降低可用性。

同时,要求用户过于频繁地认证并不友好,过多的密码甚至会使用户倾向用更弱或相同的密码,系统也会更难正确地被维护,因此单点登录是比较理想的。

数据机密性

保护数据机密性的标准手段是加密,其工作方式为:

  1. 发送方和接收方(可能是同一人)通过可靠信道协商,分别得到加密算法$E$与加密密钥$e$、解密算法$D$和解密密钥$d$
  2. 发送方把原始数据(明文)$m$转换为密文$m'=E(m,e)$,这过程叫加密
  3. 发送方通过不可靠信道把密文$m'$发给接收方
  4. 发送方把密文$m'$转换回明文$m=D(m',d)$,这过程叫解密,对所有明文$m$成立$m=D(E(m,e),d)$是第一步中选取的结果

其中加密算法与对应的解密算法有一些标准选择,过往经验表明不知道解密密钥的话从密文还原明文极为困难,但究竟多困难只能由时间回答。

  • 一些方案中总使用相同的加密密钥和解密密钥,这称为对称加密,比如DES、3DES、AES、IDEA、RC4、xor等等。虽然xor一次一密理论上无法攻破,但密钥与明文一样长使它没有应用价值(随非用量子通信信道)。
  • 一些方案中加密密钥和解密密钥之间看似没什么关系,这称为非对称加密,比如RSA、EIGamel、ECC等等。在端对端通信中,非对称的好处在于需要管理的密钥较少:使用对称加密时$n$个人间通信需要$\frac{n(n-1)}{2}$个密钥,但使用非对称加密时只用$n$对密钥(可公开加密密钥,故叫公钥,而解密密钥叫私钥)

已知的攻击方法有:

  • 功耗分析,由于处理0和1时指定消耗的能量不同,平凡地实现的算法很容易通过功耗泄露了密钥,这方法相当有效
  • 时间分析,由于对不同密钥需要执行的分支不同,加密需要的时间不同,可能可从加密需要的时间反推密钥,与功耗分析结合更强大
  • 线性密码分析,考虑明文位与密文位的差异
  • 差分字码分析,考虑明文位差异对密文位差异的影响

在选择加解密算法时,通常密钥位数越大强度越高,流加密比分组加密快,但不总是这样。除了加解密算法的强度,密钥生成算法也同样重要,还要保证密钥分发过程中没有泄漏或者收到仿冒的密钥。Diffie-Hellman给出一个简单的密钥交换协议,它利用$(G^a)^b\mod P=(G^b)^a\mod P$作为密钥,其中$P, G, G^a, G^b$可公开,但$a,b$各由一方保密。

由于已知的对称加密方案比非对称方案快得多,所以常见的使用模式是用非对称加密方案保护协商对称密钥的过程,后继传输用对称加密方案

不过,即使经过加密,内容的许多信息仍然会泄露:

  • 由于大多数加密方案的明文与密文长度成比例,可以从密文长度推断内容长度,如八卦杂志发现两个名人之间的通信突然增加,即使不知道内容也已经是重要线索
  • 由于大多数加密方案把相同的明文加密成相同的密文,可以通过比较密文判断明文是否相同,如假如某个大使馆几乎每天向所属国发出相同的电报但一天突然发出不同的电报,则可能有状况出现。在另一个粒度,对于分组密码,相同的分组加密成相同的分组也会带来同样问题,甚至更严重(可能被局部修改),所以存在电子密码本(ECB)以外的使用模式,如把断码链块(CBC)模式中加密块再与前一块异或(问题在于对传输错误敏感)、流密码模式中反复加密密钥用来生成xor用的位(问题在于不要重用初始密钥)、计数器模式中加密初始密钥加上分组号用来生成xor用的位(好处是可随机访问,问题在于不要重用初始密钥)。

为了抵抗这类攻击,思路是把机密信息淹没在大量正常信息之间,这就是隐写术例如把信息藏在图片文件中对显示效果影响很小的位,这也可用于宣示著作权(自然也有反水印技术)。通过调制CPU使用率或缺页率、获取与释放文件、设备或其它锁都可以用于在进程间传输数据。

数据完整性

保护数据机密性的标准手段是冗余:如果接收到的数据不符合应有格式,就有理由认为经过窜改,但对有冗余的数据加密较易被破解。产生冗余的一个一般方法是消息摘要,给定单向函数$f$,其工作方式为:

  1. 发送方为原始数据$m$计算摘要$d=f(m)$
  2. 发送方通过可靠信道把摘要$d$发给接收方
  3. 发送方通过不可靠信道把数据$m$发给接收方
  4. 发送方检查是否成立$d=f(m)$,若是则相信数据没有被修改过,否则数据必然被修改过

其中单向函数有一些标准选择,如MD家族和SHA家族,过往经验表明要找出另一个有相同摘要的消息足够困难,如果还是有意义的就更困难。通常,消息摘要密钥位数越大强度越高,但拙劣的单向函数可能受到附加之类的攻击。

必须强调消息摘要要可靠地传送和保存,否则攻击者能改掉摘要的话整个方案就形同虚设。为了模拟传输摘要的可靠信道,一个可能的方法是对摘要进行加密,方法是反用非对称加密,公开解密密钥而保密加密密钥,这称为数字签名,它也可用于实现不可否认性(如后悔提交订单后也不能否认自己提交过)。接着的问题是如何保证接收者知道正确的解密密钥,现行的做法是由权威的各级认证机构(CA)签发证书并假设所有人知道根认证机构的解密密钥,但依赖于权威是一个单点故障,事实上只要给钱欺骗它们发放证书不难,认证机构也难以保证下级认证机构的可信性。公钥基础设施还涉及统一时间、证书撤回(只有拥有者能但其它人不能,不能基于私钥)和非层次式信任模型等等的问题。

其实消息摘要也用于非安全目的的应用,如检测传输过程中的随机错误和索引数据(如git用SHA-1),还有保存密码。

其它

信息安全有很多其它方面。如果想以它为专业,应当考取Security+、CASP、CISSP、CISA之类的认证。然而,实际攻防经验永远是无可取代的。

关键词 信息安全