家里的电脑终于又可以用了

此事说来话长。

这台电脑是03年买的,然后一直多病多灾。搬了几次家之后,因为内存显卡松动,经常启动不起来。而后,突然发现,每次进入windows的时候,在选择启动项之后,屏幕要黑很久,大约在30s左右,然后下面出现一条白色的进度条横线,然后才能出现windows启动画面(一个滚动条滚啊滚)。好吧,只是多等等。但是久了之后,启动完经常发现某某图标无法显示,或是干脆报告说某某“应用程序初始化失败”,一片乱七八糟,只能充启。但是,启动10次,至少大概有2-3次是处于可使用状态的,并且每次从休眠中恢复时,不存在此问题。所以我从来都是休眠,不安装任何系统补丁,以避免重启。

我错误的以为是我的主板大限已到。直到某一天,windows彻底启动不起来了。gf眼睁睁的看着我重启N次无效。进入安全模式也不行。在读\windows\system32\config的时候会停数10秒,然后在读windows/config/system.log的时候彻底卡死。更可恨的是,即便是重装系统或是进入故障恢复台进行修复,它也经常读不出来某个分区。或者,本来正常,但是突然就找不到当前目录,以及该盘下的其它文件。以至于重装系统的时候从来没有办法成功的copy所有文件并重启。

话说,我惊奇的发现,Freebsd仍然能正常运行。只是packages有些老了,放弃了从6.2升级到7.0的想法,更放弃了从xorg 6.x 升级到xorg 7.3的想法。这个……太痛苦了。于是我便pkg_delete -a,然后从ftp中用pkg_add -r重新安装需要的包。

windows怎么办?所有分区都是ntfs的,进入故障恢复台,对所有分区反复的进行chkdsk,但是还是不行。周五我把我的硬盘挂在朋友的机器上,再次进行chkdsk,依然无法启动win。于是准备周六去买本子,扔掉面前这个老家伙。但是嘛,gf不愿去中关村(她比我懂行)。于是就只好另谋策略。

周六我在网上搜索时无意中发现我之前出现的图标显示不正常可能是因为注册表损坏,再加上的确是在读取注册表的时候卡死,于是我便需要想办法修复注册表。但是因为硬件问题我没有办法去安装一个新的win。于是我便进入win的故障恢复台,备份注册表,然后把windows\repair目录下的5个注册表文件复制到\windows\system32\config下。然后启动,哇!成功了。一切恢复到刚装好系统的状态。需要重装所有驱动程序和应用程序,并重新建立用户帐户。
话说,我要成功启动win,而是完全的扔弃它,一个主要的原因就是我的ntfs分区上有很多文档是我从04年积攒到现在的,而且是用EFS加密的。这,已经不是我第一次为EFS悲痛了。唉…… how to decrypt them? xp刚出那一两年,微软工程师曾给出的答案是说,如果没有备份证书或者设置恢复代理,那么基本没救了。但是……几年过去了,一点办法就没有吗?

于是周六晚上我便去研究EFS。发现其实03年的时候EFS的结构就被研究透了,于是现在是有很多恢复工具的,包括微软自己开发的一个收费的工具。但是嘛,我穷,于是就只好去手动做。

我幸运的发现我以前早就把我的用户目录移动在了E盘,然后我的所有的密钥都在E盘。而我只是把系统恢复到了初始状态,系统的id没有变,然后第一个新建的用户的uid必定是1003。所以非常的简单,我只需要新建一个用户,然后把密码设置成和以前一样,然后把用户目录也设置到和以前一样(其实只需要3个key文件),那么就可以顺利打开以前的加密文件了。哈哈,果不其然。

顺便,对EFS的研究结果如下:
密钥文件在3个目录中
Session Key(private key): 被Master Key Encryption Key 加密。
%User Profile%\Application Data\Microsoft\Crypto\RSA\(User SID)

master key: 也是加密的,key是用户密码。
%User Profile%\Application Data\Microsoft\Protect\(User SID)
可能会有多个文件。
其中会放一个24字节的名叫"Preferred"的文件记录优先选用哪个。

公钥:
%User Profile%\application data\microsoft\systemcertificates\

在HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\EFS\CurrentKeys下面找到
一个名为CertificateHash的二进制字段,它记录着NTFS用于加密文件的用户证书的公钥的hash值。
这个证书的具体信息可以通过 证书查看器 查看。我是在IE的tools->internet options->content->Certificates打开证书查看器的。这里面会列出%User Profile%\application data\microsoft\systemcertificates\下的所有证书,同时,如果这些证书对应的私钥在%User Profile%\Application Data\Microsoft\Crypto\RSA\(User SID)下,那么查看的时候会显示一个图标并注明用户拥有与之对应的私钥。

EFS的原理很简单。加密的时候,
首先由Lsasrv进程的CryptoAPI系统生成一个对称密钥,这个被称做FEK (File Encryption Key)。
FEK + 原文 => 密文
FEK + 用户公钥 => DDF (data decryption field)
如果设置的有数据恢复代理的话,那么还有
FEK + 恢复代理的公钥 =>DRF(data recovery field)

解密过程也就很简单了。
DDF + 用户私钥 => FEK
FEK + 密文 => 原文

DDF和FEK存储在文件的$EFS属性中。关于这个属性的具体数据结构的描述在这里:
http://www.ntfs.com/attribute-encrypted-files.htm
传说微软给美国安全局预置一个DRF放在每个加密文件里面,但是……只是据说吧。

如果重装了系统,那么只要%User Profile%\application data\microsoft下的那两个核心文件还在:加密过的私钥、master key,那么根据用户的密码就可以挨个解密得到原文。所以,在hacker们摸清NTFS的这些套路后,问题就变的没有微软技术工程师口中的那么严重。然后发现EFS其实真的很脆弱。理论来说,如果没有这个用户私钥,那么加密过的数据就只有靠超强的计算能力去暴力破解了。但是就算被格式化,这个私钥也是有一定概率能从以前的文件系统中用传统的恢复文件的方式恢复出来的。然后只需要去猜用户的密码,就可以了。另外,efs的一个愚蠢就在于,它在加密前会把原文复制一份到一个临时的目录下,在加密完毕后删除原文,但是删除的方式并非是安全删除。并且,你看,它绕了这么一大圈,并没有有效的提高文件系统的安全性,只是把普通用户绕晕了,让他们在系统崩溃后不知所措。但是其实,加密的强度依然是相当的低,只要算出了用户密码,就可以顺利的打开其它一切。

目前还没有哪个开源的操作系统打算在它的NTFS文件系统模块中支持加密特性。我觉得不妨尝试下,那么,这个OS的livecd,将会很受欢迎。因为总是有N多人在系统崩溃后为EFS痛哭。
推荐一篇文章:
http://www.beginningtoseethelight.org/efsrecovery/
如果重装后格式化硬盘丢失了以前的用户文件,它采用了一种很巧妙的“狸猫换太子”的手段修改公钥证书的thumbprint字段然后伪装过去,这样就不需要原始的public key了。

此博客中的热门博文

少写代码,多读别人写的代码

在windows下使用llvm+clang

tensorflow distributed runtime初窥