在线EXCEL(xls,xlsx)文档限制解除工具


*仅支持后缀为.xls,.xlsx的文档,最大支持5M

使用在线EXCEL(xls,xlsx)文档限制解除工具须知


你上传的excel文档,你必须拥有该文件的完全使用权,或者该文件归属与你,否则禁止使用本工具

在线EXCEL(xls,xlsx)文档限制解除工具使用说明


解除限制之前

1:可以对全版本office(97,2003,2007,2010,2013,2016,2019)的excel文档进行无损限制解除

2:另外还支持由金山wps生成的excel(xls,xlsx)文档的相关无损限制解除

本工具可解除限制范围有:

右侧的excel限制都可以使用本工具解除---》

可以取消标记为最终状态

可以取消保护当前工作表

可以取消保护工作簿结构

可以取消只读限制

以上限制无论是否设置了密码,都可以在不提供密码的情况下,进行限制解除

备注:金山wps保存时设置的私密文档,登录指定账号才能打开的限制,本工具无法为您解除,忘悉知

非workbook复制,所以可以100%保证文档的结构和数据的完整

偏执


如果你执意想要找回保护当前工作表的密码,好吧,我来告诉你有多难:

Excel使用一种在XML文件中以哈希形式存储用于工作表保护的密码的方法。

从Excel 2013版本开始,哈希值很大,很难通过Bruteforce找回密码,而Excel 2010的哈希值是2个字节,可以被大约65536次尝试找到密码。

Excel 2010工作表保护方法

为了保护工作表,密码的哈希值存储在相应工作表名称的xlm文件中,而哈希值存储在workbook.xml文件中,以保护整个工作簿。

以下是密码1表“ 123456789”受保护时存储的哈希值。(在文件xl / worksheets / sheet1.xml中)

<sheetProtection password="9690" sheet="1" objects="1" scenarios="1"/>

为什么变成了9690?这是用了某种哈希算法F来进行转换的

比如:F("123456789") = "9690"

如果F是一种成熟的哈希算法,几乎没有冲突,那就很难找到一个合适的碰撞点,但是

由于某种原因,表格的保护方法必须弱于主表加密,所以这种加密,可以非常容易碰撞到相同的"9690"这个值,但是密码肯定和你原来的不一样,但是可以正常使用

这种加密方式就不再介绍了,网上有很多vba脚本

Excel 2013工作表保护方法

作为哈希算法,使用了Sha2类型的Sha512,因此哈希值是512位(= 64字节),并且使用了salt,因此即使使用Rainbow表(预先计算了哈希值的表),也无济于事。

哈希值的计算如下。

hashValue = sha256(密码||盐)

由于salt值为24个字符,因此如果创建哈希表,则约为24 * 8 = 192位。

下面看具体操作

把你的xlsx文件,修改成后缀为zip,找到文件 xl\worksheets\sheet1.xml

提取加密信息hashValue和saltValue(一般在2013中才会用到这么强的加密)

<sheetProtection algorithmName="SHA-512" hashValue="nx9HCR+xJ8Mkgdon2xwZ4QRJxCdluc5mbfkDyy4PS05BaOP8vfUrvvaV/9A++i0kdPLdCk01tDT84jomvoh5sA==" saltValue="Hby4xyZo7dYNNHwQTF0vWA==" spinCount="100000" sheet="1" objects="1" scenarios="1"/>

下面是找回保护当前工作表密码的完整代码,请跑一下,感受一下速度

之所以慢,是因为那十万次迭代

#! /usr/bin/env python 2.7.11
#coding=utf-8
#本脚本改造成opencl,使用NVIDIA GeForce GTX 750 Ti来全速测试,每秒仅能达到500H /s
import hashlib
from base64 import b64encode, b64decode
import struct

workbookAlgorithmName="SHA-512"
workbookHashValue="nx9HCR+xJ8Mkgdon2xwZ4QRJxCdluc5mbfkDyy4PS05BaOP8vfUrvvaV/9A++i0kdPLdCk01tDT84jomvoh5sA=="
workbookSaltValue="Hby4xyZo7dYNNHwQTF0vWA=="
workbookSpinCount="100000"

def findpassword(password):
    alg = workbookAlgorithmName.replace('-', '').lower()
    if alg not in hashlib.algorithms:
        raise Exception("Algorithm %s not in %r" % (alg, hashlib.algorithms))
    alg = getattr(hashlib, alg)
    count = int(workbookSpinCount)
    digests = []
    salt = workbookSaltValue
    salt = b64decode(salt)
    
    m = alg()
    m.update(salt) # data is binary, length = 16
    m.update(password.encode('utf-16-le')) # window's "unicode" encoding
    h = m.digest()
    #这里的十万次迭代循环加密,能慢到吐血
    #平时加密和取消密码,时间很短暂,几乎很难感觉到,但对爆破却是致命的打击
    for i in xrange(count):
        m = alg()
        m.update(h)
        m.update(struct.pack("<I", i)) # little endian 4-byte unsigned integer iterator
        h = m.digest()
    digest = b64encode(h)
    print digest
    print "log:", digest, u"密码找到了" if digest == workbookHashValue else u"密码不正确"

if __name__ == '__main__':
    #这里可以使用字典
    findpassword("bugscaner")

那么,你准备好放弃了吗?

更新日志


2023年9月20号上线