CSP课程笔记_01_Introduction

《计算机系统原理》课程笔记(1)——夏虞斌老师——IPADS Lab

一、Guessing Password

checkpw (user, passwd):
acct = accounts[user]
for i in range(0, len(acct.pw)):
if acct.pw[i] ≠ passwd[i]:
return False
return True

验证密码的代码逻辑是按顺序比照每一位,若相符则比照下一位,若不相符直接返回密码错误。

对于这种密码验证机制,可以采用Timing Attack(时序攻击)来破解密码。一开始的思路是:验证程序运行的时间越长,则说明猜中密码的位数越多。但是计算机的运算速度太快,程序对每一个字符的验证都用极短且不可确定的时间完成,而且因为计算机运行的不确定性,程序在不同次的实验过程中对同一个字符的验证时间也不一定相同,因此通过运行总时间来量化地推测猜对密码位数不可行。

正确思路是基于操作系统的寻址特性之一Page Fault(缺页)。每次只猜一个字符,将猜测的字符及之前的所有已通过验证的正确字符放在映射到主存的Page中,剩下的字符放在未映射到主存的Page中。如果该猜测字符通过了验证,则读下一个字符的时候会发生Page Fault,而Page Fault带来的时间损失是能够被明显观测到的,程序的运行总时间会大幅增加。因此,每次观测到Page Fault的出现,都说明猜测字符通过了验证,以此类推便能猜测出完整的密码。

二、C语言中volatile关键字

在本线程内读取内存中一个变量时,为提高存取速度,编译器的优化会将变量读取到一个寄存器中,下次再读取这个变量值时,就不会从内存中读,而是直接从寄存器中取值。

当变量值在本线程内被改变时,会同时更新寄存器中的值,使寄存器和内存保持一致。但当变量在别的线程中被改变时,寄存器内的值不会被更新,则下次本线程从寄存器读到的值就和其实际内存中的值不一样,即内存比寄存器/缓存的值要新

为了拿到内存中最新的值,使用volatile关键字,被这个关键字修饰的变量每次读都是从内存中读,不会因为编译器的优化而从寄存器或者缓存中读。

文章作者: Moon Lou
文章链接: https://loumoon.github.io/2019/09/25/CSP课程笔记-01-Introduction/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Moon's Blog