编辑(2020年):从Excel 2013开始,保护方案显然已经改变。因此,原始答案只有历史意义了。
新的保护机制使得使用最先进的SHA-512哈希算法几乎不可能检索密码。但是,如果您可以在几秒钟内轻松地取出它,为什么要破解呢?
- 解压缩
.xlsx
或.xlsm
文件
- 编辑
xl/worksheets/sheet<num>.xml
- 搜索并删除
<sheetProtection... />
标记
- 保存、重新压缩,享受吧
原始答案(适用于Excel 2010及以下版本)
很有趣 - 我之前知道代码片段,但不知道brettdj发布的解释。正如其他人所解释的那样,这是一种哈希碰撞的暴力搜索。实际上,由于它做了比必要的工作还要多(生成了194560个组合,但只有32768个哈希值),因此似乎是通过试错方法制作的。
简而言之,Excel的哈希算法(如http://chicago.sourceforge.net/devel/docs/excel/encrypt.html中所解释的):
- 获取密码每个字符的ASCII代码。
- 将其视为16位有符号数字。根据字符的位置向左移动其位(第一个字符1位,第二个字符2位,依此类推)。
- 将所有字符进行异或运算,得到一个16位有符号整数 >=0。
- 将该结果与密码的长度和一个魔术数字进行异或运算。
了解这一点后,可以设计以下暴力搜索:
- 最高位始终为零,因此有15位要测试。
- 将它们分成三个计数器,每个计数器覆盖5位。这样每个计数器都可以表示可打印的ASCII字符。
- 将这些计数器的ASCII表示包装在一个密码字符串中,以使它们彼此不影响。
最简单的方法是使用一个11字符密码,并将计数器放置在位置1、6和11。步骤2中的位移使计数器位正确:第一个计数器(“x”)向左移动1位,第二个计数器(“y”)向左移动6位,第三个计数器(“z”)向左移动11位。在哈希的按位表示中,计数器影响以下位:
bit: 76543210 76543210
cnt: -zzzzyyy yyxxxxxz
XOR操作可以忽略,因为XOR参数始终是常量。出于相同的原因,可以添加一个恒定的偏移量(例如64)。此外,其他密码字节(2-5、7-10)使用什么字符并不重要。
通过迭代所有可能的x、y、z组合,最终可以找到与原始密码产生相同哈希值的密码。
Public Sub demo()
' https://dev59.com/LWcs5IYBdhLWcg3wcDiZ
Dim x As Integer, y as Integer, z as Integer
Dim part1 As String, part12 As String
Dim sh As Worksheet
Set sh = ThisWorkbook.Worksheets(1)
sh.Protect "$ome_Insanely_Long_and_c0mplex_password! [(which i$ imp*ssible t0 re-member)]"
For x = 64 To 95
' pad with dots, so that x, y and z affect nonoverlapping bits of the hash.
part1 = Chr(x) + "...."
For y = 64 To 95
part12 = part1 + Chr(y) + "...."
For z = 64 To 95
On Error Resume Next
sh.Unprotect part12 + Chr(z)
If Err.Number = 0 Then
Debug.Print "Password: '" & part12 + Chr(z) & "'"
Exit Sub
End If
On Error GoTo 0
Next
Next
Next
End Sub