如有不详,请联系:Owen.Liu@GrapeCity.com / J2.NETe@gmail.com
前提:
1. 加密文档:指Wookbook级的加密,就是在Save Excel文档时在General Settings中设置open password之后的文档;
2. 打开:需要用户传入密码。并非破解。但请勿将本文方法添加暴力模块使用 :-) ;
3. 本文涉及较多为,密钥计算,关于解密细节请参考微软相关文档;
使用的加密算法: RC4, SHA1, MD5, AES-128(其中RC4并不包含在所有版本的.NET Framework中,AES算法可以在.NET Framework 3.5中找到)
本文示例依赖 .NET Framework 3.5
A. Biff8 的加密文档读取
1. 通过文档中FILEPASS的record取得,文档的加密信息(关于Biff文档的格式问题,请参阅Biff的微软文档)
其中Biff8可以使用两种方法加密:Biff8标准加密算法和Biff8扩充加密算法。本文主要讨论最常用的Biff标准加密算法
2. 通过FILEPASS的结构,获得如下信息:
salt(加密随机数,16 bytes)
password verifier (密码效验器,16 bytes)
password verifier hash(密码效验器Hash,16 bytes)
3. 通过以上信息,生成解密key。并通过密码效验器,验证密码:
i. 将密码转化成unicode数组,并进行MD5 Hash;
ii. 将hash结果与salt串联,然后将byte数组,反复串联16次(336 bytes) ,然后再进行MD5 Hash;
iii. 将上步hash结果的前五位,串联上4 bytes的block值(在密码验证阶段为0,在以后解密阶段为block的index) ,然后进行MD5 Hash;
iv. 将上步hash结果的前16位,作为key
v. 使用RC4对称加密算法,将password verifier和password verifier hash分别解密,然后对password verifier的解密结果进行MD5 hash,其值应和password verifier hash的解密结果一致,即为密码正确。
vi. 之后进行逐个record的解密。excel biff8加密原则基本为,record的标示不加密,长度不加密,个别record不加密(见文档);另外,在record解密时,还需要通过block的值重新计算解密key,block的大小为1024.
4. 详细请参照示例代码;
B. OpenXML(ECMA-376) 加密文档的读取
1. 通常来说,xlsx文件相当于一个zip文件,可以用zip程序,直接打开。而在加密后,为了安全性考虑,微软使用了 structured storage(一种OLE文档存储方式)存储(可以用7-zip或者OLE document viewer打开,windows也有相应API来 *** 作此类结构)。在上述文档中,有一个叫做“EncryptedPackage”加密的package,就是一个zip包通过AES算法进行加密之后的结果。我们将使用和A一样的方式来检查密码,但生成key的方法不同;OpenXML的加密类型也有多种,我们这里就讨论常用的用AES-128进行加密的流程;
2. 通过文档的“EncryptedInfo”部分,需要过的一下信息(关于此部分的结构,请参考[MS-OFFCRYPTO].pdf)
salt(加密随机数,16 bytes)
password verifier (密码效验器,16 bytes)
password verifier hash(密码效验器Hash,32 bytes)
3. 通过以上信息,生成解密key。并通过密码效验器,验证密码:
i. 首先,定义一个H函数,其有两个输入,内部使用SHA1算法将两个输入串联之后的结果hash返回;
ii. 先将salt与password(password的unicode数组)进行H计算,h = H(salt, password) ;
iii.然后设iterator为0x00000000,将其转为4byte的数组,然后进行H计算,h1 = H(iterator, h)
iv.将上面的iterator递增一,然后再与h1进行H计算,h2 = H(iterator,h1),然后将这个递增和计算过程重复50000次,最后计算过的iterator为49999即可;
v. 现在有计算结果h50000,将h50000再与0x00000000(4 byte数组)进行H计算,Hfinal = H(h50000, 0x00000000);
vi. 生成一个64byte的数组,将每位都初始化成0x36,然后将这个数组与Hfinal异或;(关于这个地方,微软文档中写的有错误,按照原文的方法生成的key不正确,要不是文档的作者回信告诉我要使用这个法子,就算我想破头也想不出来啊 T__T)
vii.将异或结果,进行SHA1 hash,结果的前16byte就是解密的key;
viii.初始化AES算法,key长度为128,模式为ECB模式,Padding为none; 然后将password verifier 和password verifier hash分别解密;
ix. password verifier 解密后的SHA1 hash结果应该与password verifier hash解密后的前20byte相同;
4. 关于"EncryptedPackage" 的解密则更为简单,只许将“EncryptedPackage”读入,去除前8byte的size信息后,进行AES解密,即为未加密的标准openxml文档。
参考:
[MS-OFFCRYPTO].pdf
[MS-XLS].pdf
ECMA-376 standards
Reply by "winnow", 2008-09-10, 1:17
-----------------------------------------------------
总结一下, 关于这两种基于密码的加密方法, 基本上都是基于RFC2898 建议, 思想是这样:
输入是用户的密码:password, 输出是提供给加密函数的密钥:key.
考虑安全, 需要使同样的password生成的key不一样, 这样用相同的password加密后的结果就无法比较. 需要一个随机数salt.
另外, 为了使暴力破解的代价增大, 考虑使用一个循环多次的过程, 需要循环次数:iteration_count.
概念上, 生成方法为: 将password和salt进行某种运算, 配合一个Hash函数, 以某种方式循环iteration_count次, 在最后的结果里取一部分作为key输出.
具体参照RFC2898中的建议方法PBKDF1和PBKDF2.
这样, 用户输入的密码与一个随机数组合, 经过一定代价的运算, 就生成了可以供加密函数使用的密钥. 使用这个密钥和一个加密函数, 就可以进行加密了.
在应用中, 为了快速判断密码是否错误. 生成一个随机数verifier, 用一个Hash函数计算verifier的hash值:verifier_hash, 分别加密verifier和verifier_hash并保存.
解密的时候, 先分别解密出verifier和verifier_hash, 计算verifier的hash值, 与verifier_hash比较, 如果一致, 即说明密码正确.
salt的安装:master端:
#yum install salt-master -y salt主控端安装
# vim /etc/salt/mastersalt主配置文件修改
interface: 服务监听IP
auto_accept: True(可选,key通过‘salt-key -a keyname’命令手动进行认证)
注意:keyname 就是客户端中设置的id标识(可以查看salt-minion端的配置)
#salt-master -l debug debug模式,查看salt都进行哪些 *** 作
#/etc/init.d/salt-master restart 重启salt服务
#/etc/init.d/salt-master status 查看状态
#netstat -antlp | grep 4505确保消息发布端口正常
#netstat -antlp | grep 4506确保客户端与服务端通信端口正常
#/etc/init.d/salt-master restart
# /etc/init.d/salt-master status
# salt-key 查看认证相关信息
# salt-key -a wy-pe2 手动添加认证key(给wy-pe2主机添加认证)
#iptables -F 关闭防火墙以免影响认证
#salt-key -a wy-pe2
#salt-key -L 查看认证信息(会有显示已经认证和未认证的相关信息)
[root@wy-pe1 ~]# salt-key -L
Accepted Keys:
wy-pe2已经允许的key(表示wy-pe2已经允许认证了)
Unaccepted Keys:
Rejected Keys:
#cd /etc/salt/pki/master/minions在master中的minions目录中生成认证的key
#setenforce 0暂时关闭selinux
#/etc/init.d/salt-master restart
执行远程命令(使用salt内建的模块):
#salt ‘wy-pe2′ test.ping测试master和minion进行通信(在master端进行ping响应测试)
[root@wy-pe1 ~]# salt ‘wy-pe2′ test.ping如果能ping通,则为True
wy-pe2:
True
#lsof -i:4505 查看到minion端都和4505保持建立
[root@wy-pe1 ~]# lsof -i:4505
COMMANDPID USER FD TYPE DEVICE SIZE/OFF NODE NAME
salt-mast 8568 root 12u IPv4 63217 0t0 TCP *:4505 (LISTEN)
salt-mast 8568 root 14u IPv4 65101 0t0 TCP wy-pe1:4505->wy-pe2:51237 (ESTABLISHED)(表示建立连接了)
注意:如果认证那块没做好,就会影响相关的链接
客户端安装:
minion端安装配置:
#yum install salt-minion -y
#vim /etc/salt/minion修改minion客户端主配置
master: 服务端主机名
id: 客户端主机名(其实也就是认证key的名字)用来和master进行认证
#/etc/init.d/salt-minion restart 重启服务
#cd /etc/salt/pki/minion/在这个目录底下会生成两个认证文件(minion.pub minion.pem)
salt-minion端不能正常启动的解决步骤:(一般就是iptables和selinux的影响)
#/etc/init.d/salt-minion restart
# tail -f /var/log/messages
#/etc/init.d/salt-minion restart
#iptables -F
#tail -f /var/log/salt/minion
#salt-minion -l debug
#setenforce 0
#/etc/init.d/salt-minion restart
安装完毕,在master和minion认证完毕之后会在minion主机上的/etc/salt/pki/minion/目录底下生成新的minion_master.pub
问题1:档master和minion进行认证的时候,master没有接收到public key(minion)
(这个在后来的链接过程中会造成master和minion不能链接)
问题2:辅机salt-minion总是在查看服务状态的时候显示失败(but pid exits!)
# salt-minion -l debug 查看salt客户端详细信息
salt的简单使用:
salt可以直接让minion执行模块命令,也可以直接执行shell命令
1.salt -C ‘wy-pe1 and wy-pe2 or wy-peN’ test.ping-C表示多参数(表示在测试多台主机的存活状态)
# salt ‘*’ disk.usage查看磁盘使用情况(使用内建模块查看所有minion端的磁盘使用情况)
#salt ‘*’ cmd.run ‘df -h’ 使用cmd.run直接调用远程shell命令(功能同上)
# salt ‘*’ cmd.run “cat /root/lall”查看客户端主机的/root/lall文件
2.nodegroup对minion进行分组:
nodegroups:
group1: ‘L@foo.domain.com,bar.domain.com,baz.domain.com or bl*.domain.com’
group2: ‘G@os :Debian and foo.domain.com’
group3:’wy-pe2′
进行分组测试:
# salt -N group3 test.ping
wy-pe2:
True
3.grains对minion基本信息的管理:
salt ‘wy-pe2′ grins.ls查看grains分类
salt ‘wy-pe2′ grins.items 查看minnon基本信息(硬件参数)
4.pillar对敏感信息的管理,只有匹配到的节点才能获取和使用
默认pillar数据定义文件存储路径:/srv/pillar
状态管理:
1.salt基于minion进行状态的管理(state)
类似于pupet的pp文件功能,salt的state文件扩展文件名为.sls,采用的是和puppet一样的设计思路。即以master
端的文件状态来确定minion端的一些状态信息设置。(安装的软件包,服务的运行状态以及需要同步的文件配置)
注意:salt默认的根目录在/srv/salt中,如果没有需要进行建立。
top.sls:这个文件类似于puppet的site.pp文件,作为“最高同步” *** 作的入口文件,执行“最高同步” *** 作时,将从此sls文件中获取状态对minion进行同步
示例:(注意,salt文件完全采用ymal格式,对代码的缩进有着严格的要求)
#vim /srv/salt/servers_package.sls
httpd:项目名
pkg: 类型
– installed动作(表示安装httpd包)
service:
– running
– enable:True
vim-enhanced:
pkg:
– installed
tomcat环境
openjdk-7-jdk:
pkg:
– installed
tomcat7:
pkg:
– installed
– require:
– pkg: openjdk-7-jdk
# salt ‘wy-pe2′ state.sls servers_package 按照sls文件中的配置对wy-pe2进行服务配置
管理配置文件
httpd:
pkg:
– installed
file.managed:文件管理(文件同步 *** 作)
– name: /etc/httpd/conf/httpd.conf
– source: salt://httpd/httpd.conf
# salt ‘wy-pe2′ state.highstate应用修改(给minion永久添加状态)
3.使用salt schedule对minion进行实时更新,让minion自觉的保持某个状态
4.实时管理
有时候我们需要临时的查看某个机器上的某个文件,或者执行某个命令
cmd.run方式:(salt ‘$targeting’ cmd.run ‘$cmd’)用来远程执行shell命令
# salt ‘wy-pe2′ cmd.run ‘ifconfig eth0′ 查看某台主机的网络接口
cmd.script方式:可以向远程主机执行脚本
#salt ‘*’ cmd.script salt://useradd.sh 向minion主机上执行useradd.sh脚本(salt://是salt的默认发布目录,即/srv/salt)
pkg.install方式:制定主机安装软件
#salt ‘wy-pe2′ pkg.install vsftpd 指定主机安装软件
# salt ‘*’ network.interfaces查看远程主机接口
# salt-cp ‘wy-pe2′ salt-cmd /home/xxb2复制文件到指定的系统上(当前目录的salt-cmd)
salt是主命令,一般用来执行命令模块。
salt-cp用来复制文件到制定的系统上去
salt-key用来和minion之间进行身份验证
salt-master为服务端的主守护进程用于控制minion
salt-run为前端命令执行
module方式:(模块查看方式#salt ‘*’ sys.doc)
#salt ‘*’ disk.usage查看磁盘使用情况
# salt ‘*’ grains.item os/osrelease/oscodename
# salt ‘*’ user(group).info xxb2
# salt ‘*’ ip.get_interface eth0
#salt ‘*’ lvm.vgdisplay
salt相关管理命令:
salt-run manage.up 查看存活的minion
salt-run manage.down查看死掉的minion
salt-run manage.down removekeys=True查看down掉的minion,并将其删除
salt-run manage.status查看minion的相关状态
salt-run manage.versions查看slat的所有master和minion的版本信息
将文件夹package打成tar包 package.tar.gz 并加密 密码是 password tar czf – package | openssl des3 -salt -kpassword -out package.tar.gz 加密的tar包只能在Linux上解密,无法在Windows上使用。 解密tar包并且解压缩 openssl des3 -d -k pas...欢迎分享,转载请注明来源:内存溢出
评论列表(0条)