*仅支持后缀为.xls,.xlsx的文档,最大支持5M
一键轻松为您的EXCEL文档添加打开密码,保护文档安全
文档加密之后效果如下图:




采用无损加密,效果与使用office软件加密的效果是一样的,支持六种加密方式XOR加密,40 Bit RC4加密,CSP加密,AES 20(次)*128位加密,100000(次)*128位加密,100000(次)*256位加密,加密强度逐渐加强
Excel 97-2003 文档使用了相对强度较高的RC4CryptoAPI加密
2007和2010版本的Excel文档,统一采用AES128加密方式
2013及以上版本采用加密强度最高的AES256进行加密
为了保持向旧版本的兼容,高于2003版本的office文件,也就是xlsx结尾的文件,如无选择,则默认使用ECMA376 Standard encryption加密,加密后的文件最低打开版本为:office2007
您无需对选项中的各种加密方式,感到不知所措
因为,无论您上传的由什么版本生成Excel文档,您可以随意选择加密方式,随意选择文档限制,程序会自动为您加密成合适的excel文档
下面的介绍,您无需了解
加密方式从1到6逐渐增强
加密方式1:XOR加密 仅支持后缀为xls的文档,这个是所有加密方式中,最弱的加密方式,早已被微软弃用,该功能可以提供给大家测试和研究使用,不再建议使用这种加密(所有office版本都可以打开)
加密方式2:40 Bit RC4加密 仅支持后缀为xls的文档,这种加密方式适用97-2003版本的excel加密,注意:该加密方式已不再安全,可通过查表,快速逆向出文档内容,不再建议使用.(所有office版本都可以打开)
加密方式3:CSP加密 仅支持xls后缀的文档,中规中矩的加密方式,使用97-2003版本的excel加密,这种加密方式是xls后缀文档的最佳加密方式,至少不会被查表逆向出文档内容.(所有office版本都可以打开)
加密方式4:AES 20(次)*128位加密 仅支持xlsx后缀的文档,office2007的默认加密方式,密码强度(较强)(加密后打开加密文档的最低office为2007或者更高版本)
加密方式5:100000(次)*128位加密 仅支持xlsx后缀的文档,office2010的默认加密方式,密码强度(很强)。(加密后打开加密文档的最低office版本为2010或者更高版本)
加密方式6:100000(次)*256位加密 仅支持xlsx后缀的文档,office2013的默认加密方式,密码强度(超强,变态强,史无前例的强,XX).(加密后打开加密文档的最低office版本为2013或者更高版本)
限制选项1:禁止编辑(只读) 需要输入密码才能编辑文档,否则只能阅读文档
限制选项2:保护当前工作表 控制对当前工作表所做的更改类型(默认会设置全部worksheets)
限制选项3:保护工作簿结构 防止对工作簿结构进行不需要的更改,例如添加工作表,删除工作表,移动工作表,全部不允许修改
限制选项4:标记为最终状态 告知读者您的工作簿是最终版本,并将其设为只读
选项1,2,3均可设置单独的密码,为了选项界面简单,只允许设置一个相同的密码
支持对已经进行限制的excel文档进行二次覆盖限制
小于等于office 2003的文件,都是使用ole,biff8格式存储的,加密方式和open xml截然不同
biff8(excel 2003文档)加密的关键是filepass Record 0x002F
通过rc4加密方式,使用随机生成salt和encryptedVerifier,再加上可控变量password,来生成一段filepass记录,长度为200字节,填充到0x002F
encryptedVerifier 和 verfiferHash 形成了对比关系,与数据解密没有一点关系,仅仅是为了验证输入密码是否正确
搞清rc4加密的最大关键在于,对称加密算法的加密和解密函数是同一个函数
下面是一段excel 2003加密的伪代码,也是本站提供的为office 2003版本的excel加密的部分代码,供大家参考
def main():
#临时的一个存储文件
file = io.BytesIO()
tem_excel = xlrd.open_workbook(u'decrypt.xls', formatting_info=True)
#从新拷贝一份,这里非常重要
new_excel = copy(tem_excel)
new_excel.save(file)
ole = olefile.OleFileIO(file)
workbook = ole.openstream('Workbook')
workbook = xls97._BIFFStream(workbook)
#存储加密的一些信息
plain_buf = []
encrypted_buf = io.BytesIO()
#前端生成salt和密码
salt = torandom() #随机生成一个16字节的salt
password = "1234567890"# 需要设置的密码,可以是中文哦
filepass = makepassword(password,salt)
for i, (num, size, record) in enumerate(workbook.iter_record()):
if num == recordNameNum['FilePass']:
#将计算好的filepass填充到旧文件,即可达到加密的目的
plain_buf += list(pack("<HH", num, size)) + list(filepass)
encrypted_buf.write(b"\x00"*(4+size))
elif num in [recordNameNum['BOF'], recordNameNum['FilePass'], recordNameNum['UsrExcl'],
recordNameNum['FileLock'], recordNameNum['InterfaceHdr'], recordNameNum['RRDInfo'],
recordNameNum['RRDHead']]:
#这些record 不进行加密
header = pack("<HH", num, size)
plain_buf += list(header) + list(record.read())
encrypted_buf.write(b"\x00"*(4+size))
elif num == recordNameNum['BoundSheet8']:
header = pack("<HH", num, size)
plain_buf += list(header) + list(record.read(4)) + [-1] * (size-4) # 保留 lbPlyPos
encrypted_buf.write(b"\x00"*4 + b"\x00"*4 + record.read())
elif num == 0 and size == 0 and not hasattr(record,"read"):
plain_buf += list(record)
encrypted_buf.write(record)
else:
#if num == 47:#recordNameNum['FilePass']:
header = pack("<HH", num, size)
plain_buf += list(header) + [-1] * size
encrypted_buf.write(b"\x00"*4 + record.read())
encrypted_buf.seek(0)
#对称加密,加密函数和解密函数是同一个函数
dec = DocumentRC4CryptoAPI.decrypt(password, salt, 128, encrypted_buf, blocksize=1024)
for c in plain_buf:
if c == -1:
dec.seek(1, 1)
else:
dec.write(bytearray([c]))
dec.seek(0)
workbook_dec = dec
with tempfile.TemporaryFile() as _ofile:
file.seek(0)
shutil.copyfileobj(file, _ofile)
outole = olefile.OleFileIO(_ofile, write_mode=True)
outole.write_stream('Workbook', workbook_dec.read())
# _ofile = open(_ofile_path, 'rb')
_ofile.seek(0)
shutil.copyfileobj(_ofile, open(u"encrypt.xls","wb"))