下面的密码重cmeabc 多重药外排泵dE密码是多少

qwe=abc ,我们用密码表白,百度贴吧年度十大神贴之一
前几天看到网上一篇文章,讲一个男生向心仪的女生告白,女生给出了一段摩斯密码,在无数好心人的帮助下,最后解出了密码。出于好奇,我去了贴吧,找到了原来的贴子:
求救,我已经快想爆了。最近和一个心仪的女生告白,谁知道她给了一个摩斯密码给我,说解出来了才答应和我约会。可是我用尽了所有方法都解不开这个密码。。好郁闷阿。只能求教你们了。****-/*----/----*/****-/****-/*----/---**/*----/****-/*----/-****/***--/****-/*----/----*/**---/-****/**---/**---/***--/--***/****-/她唯一给我的提示就是这个是5层加密的密码..也就是说要破解5层密码才是答案..好郁闷阿..救救我吧..我本人不懂摩斯密码,当然,也不懂怎么解码,不过还是看了网上的密码解析,原来这段密文的意思是&I LOVE YOU TOO&,恭喜下他们~看了很多网上很多相关的文章,发现大家对解密过程中的有些步骤还不慎了解,或者说是解密的文章中没有说清楚,所以这里整理一下整个 解密过程(只是整理 ,不是我想出来的):1、参考摩斯密码对照表,得到对应数字组合2、数字分组41 94 41 81 41 63 41 92 62 23 74,发现个位数总是1~4 ,有人提示手机键盘,41对应数字键4的第一个字母,类推后得到G Z G T G O G X N C S3、 根据女生的提示&&她说途中有一个步骤是"替代密码"而密码表则是我们人类每天都可能用到的东西,这里强人想到了键盘,标准键盘为世界所公认,&码表 QWE=ABC依次类推&(这句话让很多人搞不清楚,导致推不出答案)。其实就是从键盘字母左上角开始,从左向右,从上到下进行对照,下面给出具体的对应 关系qwe=abcrty=defuiop=ghijasd=klmfgh=nopjkl=qrszxc=tuvvbnm=wxyz根据这个对应关系,得到O T O E O I O U Y V L4、至此,差不多可以猜到答案了,将字母分成两排OTOEOIOUYVL得到OOT UOY EVOL I5、倒序一下得到I LOVE YOU TOO&至此,答案就出来了!发现破解密码还是挺有意思的,当然,前提是破出来了,破不出来那感觉就不怎么样了,就像HighnessC刚开始那样。作为开发者,除了写程序偶尔也该换点花样搞搞脑子,呵呵~
分享这篇日志的人也喜欢
月底过任务
干活了干活了
谁人曾介意过我的感受
新主播,求守护!??
热门日志推荐
人人最热标签
北京千橡网景科技发展有限公司:
文网文[号··京公网安备号·甲测资字
文化部监督电子邮箱:wlwh@··
文明办网文明上网举报电话: 举报邮箱:&&&&&&&&&&&&
请输入手机号,完成注册
请输入验证码
密码必须由6-20个字符组成
下载人人客户端
品评校花校草,体验校园广场展开全部下一篇:现在很多人使用电脑都设置一个开机的密码,开机密码存在的意义主要是为了保护电脑的安全性,是一种保护隐私的存在。随着社会的发展,电脑的使用越来越普及,导致有些用户在公共场所使用电脑时,常会设置开机密码,限定登录用户,以避免个人隐私外泄,保障电脑中重要文有的网友为了保护自己电脑隐私或者重要资料不被他人窃取,往往喜欢为自己电脑设置开机密码。随着电脑的普及,家家户户都有它的身影,在我们的使用过程中,绝大多数人都会设置开机密码,那电脑如何设置开机密码呢?电脑在我们的生活里,成了缺一不可的产品,给我们带来了极大的娱乐享受,同时也给我们带来了很多的便利,今天我们就来一起了解下电脑怎样设置开机密码Win10系统大家应该不陌生吧!随着信息时代的来临,现在人们许多事情都可以在电脑上进行了,电脑可以帮助人们处理工作、学习和生活方面的几乎所有事情,也能节约纸张和笔墨,用于记随着科技的进步,家家户户都有了电脑,为了我们的安全使用,通常都会设置一个开机密码,要是电脑忘记开机密码怎么办呢?由于保护隐私的需要,很多人的电脑都会设置密码,但有时候因长时间未使用时会忘记开机密码。那么忘记开机密码怎么办呢?随着社会的不断发展,电脑已经得到了很大程度的普及,由于电脑中涉及自己的一些隐私,所以大多数人会给自己的电脑上设置开机密码,这样可以保护好自己密码学 – 默默的点滴
2017年十月
16171819202122
23242526272829
4-way handshake sequence
2. Key Heirarchy
The EAPOL encryption key is the middle 128 bits of the PTK value.
And the first 128 bits of the PTK (KCK), is used in the computation(and validation) of the EAPOL frame MIC field value (4way handshake Message 1/2).
3. EAPOL Frame format
4 Key Data Format
Key data may be zero or more InformationElement(s) (such as the RSN information element), and zero or more key dataencapsulation(s) (KDEs) (such as GTK(s)).
4.1 RSN Information
If theEncrypted Key Data subfield (of the Key Information field) is set, the entireKey Data field shall be encrypted. If the Key Data field uses the NIST AES keywrap, then the Key Data field shall be padded before encrypting if the key datalength is less than 16 octets or if it is not a multiple of 8. The paddingconsists of appending a single octet 0xdd followed by zero or more 0x00 octets.When processing a received EAPOL-Key message, the receiver shall ignore thistrailing padding.
Key Data fields that are encrypted but do not containthe GroupKey or STAKey KDE, shall be accepted.
If the GroupKey or STAKey KDE is included in the Key Data field but theKey data field is not encrypted the EAPOL-Key frames shall be ignored.
5. Sample 4-way Handshake
5.1 Message 1
The Authenticator sends an EAPOL-Key frame containing an ANonce.
Key data is zero.
5.2 Message 2
The Supplicant derives a PTK from ANonce and SNonce.
The Supplicant sends an EAPOL-Key frame containing SNonce, the RSN information element
from the Association Request frame and a MIC.
MIC is the KCK (The first 128 bits in the PTK).
Key data is RSN Information.
802.1X authentication, CCMP pairwise dna group cipher suites.
30, // information element id
14, // length
01 00, // Version 1
00 0F AC 04, // CCMP as group cipher suite
01 00, // pairwise cipher suite count
00 0F AC 04, // CCMP as pairwise cipher suite
01 00, // authentication count
00 0F AC 02, // authentication type is PSK
08 00, // PSK replay counter
<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad
30, // information element id&14, // length&01 00, // Version 1&00 0F AC 04, // CCMP as group cipher suite&01 00, // pairwise cipher suite count&00 0F AC 04, // CCMP as pairwise cipher suite&01 00, // authentication count&00 0F AC 02, // authentication type is PSK&08 00, // PSK replay counter
5.3 Message 3
The Authenticator derives PTK from ANonce and SNonce and validates the MIC in the EAPOL Key frame
The Authenticator sends an EAPOL-Key frame containing ANonce, the RSN from its Beacon or Probe
Response messages, MIC whether to install the temporal keys, and the encapsulated GTK
Should the MIC data
be same with the one in Message 2
Key data is RSN Information + GTK,
and the data is encapsulated by using of the AES algrithm with the KEK(The middle 128 bits in PTK).
To be added.
在编译OpenSSL前,需要正确安装Perl,因为在编译OpenSSL时需要使用到该程序。
下载最新版本的Perl:。然后安装之。
Windows 一定要使用 ActivePerl 主要是由于换行跟Linux ,Unix 的不同,如果使用其他的Perl生成的MakeFile 文件,会导致NMake无法正常的编译。
另外,一定要确保ActivePerl在系统的PATH 环境变量中在最前面,并且在命令行中执行 PATH命令的输出是跟环境变量中是一致的,Windows中有时候会发生刚刚添加的环境变量不能及时更新到命令行界面的问题,即使是你已经重新打开新的命令行窗口了。
下载最新版本的OpenSSL:
一定要使用最新的OpenSSL,早期的版本有Heartbleed的BUG,另外一定要是新下载并且刚刚解压缩出来的,没有修改过的文件,有时候,某些不经意的修改会导致编译不成功。
然后将源码释放的c:\openssl-1.0.1j目录中。
进入openssl源码目录。
cd c:\openssl-1.0.1j
cd c:\openssl-1.0.1j
以下为参照该目录下的文件INSTALL.W32的执行过程:
运行configure:
perl Configure VC-WIN32 --prefix=c:/openssl
<div class="crayon-num" data-line="crayon-59e3ad
perl Configure VC-WIN32 --prefix=c:/openssl
创建Makefile文件:
此处建议执行 do_ms ,有时候执行do_nasm会不正常,尽管文档中说执行 do_nasm
编译动态库:
nmake -f ms\ntdll.mak
nmake -f ms\ntdll.mak
编译静态库:
nmake -f ms\nt.mak
<div class="crayon-num" data-line="crayon-59e3ad
nmake -f ms\nt.mak
测试动态库:
nmake -f ms\ntdll.mak test
<div class="crayon-num" data-line="crayon-59e3ad
nmake -f ms\ntdll.mak test
测试静态库:
nmake -f ms\nt.mak test
<div class="crayon-num" data-line="crayon-59e3ad
nmake -f ms\nt.mak test
安装动态库:
nmake -f ms\ntdll.mak install
nmake -f ms\ntdll.mak install
安装静态库:
nmake -f ms\nt.mak install
nmake -f ms\nt.mak install
清除上次动态库的编译,以便重新编译:
nmake -f ms\ntdll.mak clean
<div class="crayon-num" data-line="crayon-59e3ad
nmake -f ms\ntdll.mak clean
清除上次静态库的编译,以便重新编译:
nmake -f ms\nt.mak clean
<div class="crayon-num" data-line="crayon-59e3ad
nmake -f ms\nt.mak clean
本节讨论 CCM 在 WiFi 中的实际应用 -- CCMP 协议
根据 RFC 3610,完成 CCMP 报文的加解密,需要提供:分组密钥(K)、随机数(Nonce)、附加认证数据(AAD),这三个参数从哪里来?
另外, 作为处理对象的 CCMP 报文又来自哪里? 正常是通过抓包获取,但无线报文比普通的有线(以太)报文抓取相对麻烦点
幸运的是,万能的 Internet 已经给我们准备好了,在 Wireshark 网站 -- wiki.wireshark.org -- 中有个网页链接
主流协议的报文都被世界各地的网友抓取并上传到链接指向的页面上
进入页面,下载其中一个叫
()的抓包文件,该文件将作为后续的解密报文
至于分组密钥 K,它与 STA 如何接入 WiFi 网络有关,具体而言
如果 STA 是通过 WPA-PSK/WPA2-PSK 模式(这是家用无线路由器中使用最多的模式)接入,则 K 来源于配置此模式时输入的密码(后面记为 PSK)
如果 STA 是通过 WPA-Enterprise/WPA2-Enterprise 模式接入,则 K 来自 802.1X 认证过程中协商出来的密钥(后续会单独讨论 802.1X 认证)
这两种模式下,STA/AP 双方最终都会得到名为 PMK 的密钥
PMK 的作用类似一个密钥种子,它衍生出(更为准确说是协商出)密钥 PTK(其中就包括分组密钥 K)
就文件 wpa-Induction.cap 而言,它抓取的是 WPA-PSK 模式下 STA 与 AP 的交互报文,AP 的密码(PSK)为 Induction
本节讨论 WPA-PSK 模式下:无线网络密码(PSK) --& PMK --& PTK --& K 的具体变化情况
在无线路由器上配置过 WPA-PSK 模式的网友知道,配置时除了要输入 PSK,还要指定无线网络名(标准名为 SSID)
SSID 有两个作用:标识 AP 自己的名称(与其他 AP 区分出来),另一个就是参与 PMK 的构造
构造过程遵循 PKCS #5 v2.0 中的 PBKDF2 标准,简言之,我们可以认为 PMK = PBKDF2(PSK, SSID)
wpa-Induction.cap 中的 SSID 又是多少?这需要查看类型为 Beacon 的报文
其中有个字段解析为 SSID parameter set: Coherer,即 SSID 名称为 Coherer
这里我们看到,一旦输入的 PSK 和 SSID 固定,PMK 就不再变化,这带来了一定的安全性问题
因为知道 PSK 的 STA 可以通过抓取四次握手报文,嗅探别的 STA 与 AP 之间的流量(见后面详细说明)
在 WPA-Enterprise/WPA2-Enterprise 模式中,PMK 是动态生成的,避免了上述担心
脚本 PBKDF2.pl 是生成 PMK 过程的代码实现,下面是其内容及执行结果
use Digest::HMAC_SHA1 qw(hmac_sha1 hmac_sha1_hex);
use Digest::SHA1
qw(sha1 sha1_hex sha1_base64);
# PBKDF2(passphrase, ssid, ) -- underlying function is HMAC-SHA1
#(The first argument to the pseudorandom function PRF serves as HMAC's
"key," and the second serves as HMAC's "text."
In the case of PBKDF2, the "key" is thus the password and the "text" is the salt.)
SHA-1 has a variable key length and a 20-octet (160-bit) output
if( $#ARGV != 1)
print "Usage: perl $0 passphrase ssid -- ASCII string form\n";
$count = 4096;
$salt = $ARGV[1];
= $ARGV[0];
print "Salt = SSID = $salt\nPassword
= $password\n";
#PBKDF2 (P, S, c, dkLen)
password, an octet string
salt, an octet string
iteration count, a positive integer
intended length in octets of the derived
key, a positive integer, at most
(2^32 - 1) * hLen
derived key, a dkLen-octet string
2. Let l be the number of hLen-octet blocks in the derived key,
rounding up, and let r be the number of octets in the last
l = CEIL (dkLen / hLen) ,
r = dkLen - (l - 1) * hLen .
Here, CEIL (x) is the "ceiling" function, i.e. the smallest
integer greater than, or equal to, x.
$round = 2; # ceiling(256 bit/20)
3. For each block of the derived key apply the function F defined
below to the password P, the salt S, the iteration count c, and
the block index to compute the block:
T_1 = F (P, S, c, 1) ,
T_2 = F (P, S, c, 2) ,
T_l = F (P, S, c, l) ,
for $i (1..$round)
$r .= &F($password, $salt, $count, $i);
$r = substr $r, 0, 32;
print "WPA-PSK:PMK = ", uc unpack('H*', $r);
($password, $salt, $count, $ii) = @_;
$int_4 = pack 'N', $
$yyy = $xxx = hmac_sha1(join ('',$salt,$int_4), $password);
for $i (2..$count)
$xxx = hmac_sha1($xxx, $password);
$yyy = $yyy ^ $
<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad
use Digest::HMAC_SHA1 qw(hmac_sha1 hmac_sha1_hex);use Digest::SHA1&&qw(sha1 sha1_hex sha1_base64);# PBKDF2(passphrase, ssid, ) -- underlying function is HMAC-SHA1&#(The first argument to the pseudorandom function PRF serves as HMAC's#&& "key," and the second serves as HMAC's "text." #&& In the case of PBKDF2, the "key" is thus the password and the "text" is the salt.)&&HMAC-#&& SHA-1 has a variable key length and a 20-octet (160-bit) output#&& value.&if( $#ARGV != 1){&&print "Usage: perl $0 passphrase ssid -- ASCII string form\n";&&exit 0;}&$count = 4096;$salt = $ARGV[1];$password&&= $ARGV[0];print "Salt = SSID = $salt\nPassword&&&&= $password\n";&#PBKDF2 (P, S, c, dkLen)#&& Input:&&&&&&&&&&P&&&&&&&&&&password, an octet string#&&&&&&&&&&&&&&&&&& S&&&&&&&&&&salt, an octet string#&&&&&&&&&&&&&&&&&& c&&&&&&&&&&iteration count, a positive integer#&&&&&&&&&&&&&&&&&& dkLen&&&&&&intended length in octets of the derived#&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&key, a positive integer, at most#&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&(2^32 - 1) * hLen##&& Output:&&&&&&&& DK&&&&&&&& derived key, a dkLen-octet string##&&&&&&2. Let l be the number of hLen-octet blocks in the derived key,#&&&&&&&& rounding up, and let r be the number of octets in the last#&&&&&&&& block:##&&&&&&&&&&&&&&&&&& l = CEIL (dkLen / hLen) ,#&&&&&&&&&&&&&&&&&& r = dkLen - (l - 1) * hLen .##&&&&&&&& Here, CEIL (x) is the "ceiling" function, i.e. the smallest#&&&&&&&& integer greater than, or equal to, x.#$round = 2; # ceiling(256 bit/20)##&&&&&&3. For each block of the derived key apply the function F defined#&&&&&&&& below to the password P, the salt S, the iteration count c, and#&&&&&&&& the block index to compute the block:##&&&&&&&&&&&&&&&&&& T_1 = F (P, S, c, 1) ,#&&&&&&&&&&&&&&&&&& T_2 = F (P, S, c, 2) ,#&&&&&&&&&&&&&&&&&& ...#&&&&&&&&&&&&&&&&&& T_l = F (P, S, c, l) ,#for $i (1..$round){&&$r .= &F($password, $salt, $count, $i);}$r = substr $r, 0, 32;print "WPA-PSK:PMK = ", uc unpack('H*', $r);sub F{&&($password, $salt, $count, $ii) = @_;&&$int_4 = pack 'N', $ii;&&$yyy = $xxx = hmac_sha1(join ('',$salt,$int_4), $password);&&for $i (2..$count)&&{&&&&$xxx = hmac_sha1($xxx, $password);&&&&$yyy = $yyy ^ $xxx;&&}&&return $yyy;}
C:\&perl PBKDF2.pl Induction Coherer
输出如下:
Salt = SSID = Coherer
= Induction
WPA-PSK:PMK = A288FCF0CAAACDA9A9F52A01D9C10BA5E02EFDF8CB5D730CE7BC
前已述及,PMK 会协商出 PTK,这个协商过程就是著名的 EAPOL-Key 四次握手
具体而言,四次握手的前两个报文(分别由 STA/AP 发出)各自包括了一串名为 WPA Key Nonce 的随机数(分别记为 ANonce/SNonce)
在 wpa-Induction.cap 中,EAPOL-Key 四次握手报文分别为 #87 #89 #92 #94,其中
#87 报文包含 WPA Key Nonce: 3e8e967dacd960324cac5b6aab989f49d04ed47c6933 -- ANonce
#89 报文包含 WPA Key Nonce: cdf405ceb9d889ef3decfae546b7add7baecbb1a394eac -- SNonce
光有这两个随机数还不够,IEEE 802.11i 中还规定,STA 和 AP 的无线 MAC 地址(分别记为 AA/SPA)也要参与 PTK 的生成
最终生成 PTK 需要五个参数:PMK、AA、SPA、ANonce、SNonce
脚本 PMK2PTK.pl 对上述过程进行了实现,下面是其内容及执行结果
PMK2PTK.pl
use Digest::HMAC_SHA1 qw(hmac_sha1);
if( $#ARGV != 4)
print "Usage: perl $0 PMK AA SPA ANonce SNonce\n";
-- Pairwise Master Key
32 bytes\n";
-- Authenticator MAC address
6 bytes\n";
-- Supplicant MAC address
6 bytes\n";
-- Authenticator Nonce
32 bytes\n";
-- Supplicant Nonce
32 bytes\n";
print "All input should be hexadecimal characters\n";
if(length $ARGV[0] !=64)
print "PMK MUST be 32 bytes\n";
if(length $ARGV[1] !=12)
print "AA MUST be 6 bytes\n";
if(length $ARGV[2] !=12)
print "SPA MUST be 6 bytes\n";
if(length $ARGV[3] !=64)
print "ANonce MUST be 32 bytes\n";
if(length $ARGV[4] !=64)
print "SNonce MUST be 32 bytes\n";
$ARGV[0]=uc $ARGV[0];
$ARGV[1]=uc $ARGV[1];
$ARGV[2]=uc $ARGV[2];
$ARGV[3]=uc $ARGV[3];
$ARGV[4]=uc $ARGV[4];
= pack 'H*', $ARGV[0];
= pack 'H*', $ARGV[1];
= pack 'H*', $ARGV[2];
$anonce = pack 'H*', $ARGV[3];
$snonce = pack 'H*', $ARGV[4];
= sort $ARGV[1],$ARGV[2];
= $z[0].$z[1];
= sort $ARGV[3],$ARGV[4];
.= $z[0].$z[1];
= pack 'H*', $
my $debug = 0;
if ($debug)
print &&QQQ;
以下摘自 IEEE 802.11i
PRF-X(PMK, "Pairwise key expansion", Min(AA,SPA) || Max(AA,SPA) || Min(ANonce,SNonce) || Max(ANonce,SNonce))
= PRF-X(K,
TKIP uses X = 512 and CCMP uses X = 384
PRF-384(K, A, B) = PRF(K, A, B, 384)
PRF-512(K, A, B) = PRF(K, A, B, 512)
PRF(K, A, B, Len)
← 0 to (Len+159)/160 do
R ← R || H-SHA-1(K, A, B, i)
return L(R, 0, Len)
H-SHA-1(K, A, B, X) ← HMAC-SHA-1(K, A || Y || B || X)
K is a key
A is a unique label for each different purpose of the PRF
B is a variable-length string
Y is a single octet containing 0
X is a single octet containing the loop parameter i
|| denotes concatenation
B = min(AA,SPA) || Max(AA,SPA) || Min(ANonce,SNonce) || Max(ANonce,SNonce)
hmac_sha1("Pairwise key expansion"||0x00||B||0x00, PMK)
|| hmac_sha1("Pairwise key expansion"||0x00||B||0x01, PMK)
|| hmac_sha1("Pairwise key expansion"||0x00||B||0x02, PMK)
|| hmac_sha1("Pairwise key expansion"||0x00||B||0x03, PMK)
取上述结果前 384/512 Bit
$Len = 512/8; # 384 -- TKIP, 512 -- CCMP
$zero = pack 'H2',0;
$a = "Pairwise key expansion";
for $i (0 ... ($Len+19)/20)
$idx = pack 'h2',$i;
$R .= hmac_sha1($a.$zero.$b.$idx, $pmk);
print "\n";
print 'EAPOL-Key Confirm Key
', unpack('H*',substr($R, 0, 16)),"\n";
print 'EAPOL-Key Encrypt Key
', unpack('H*',substr($R, 16, 16)),"\n";
print '(TKIP|CCMP) Temporal Key
', unpack('H*',substr($R, 32, 16)),"\n";
print 'TKIP MIC Key(for Authenticator Tx)
', unpack('H*',substr($R, 48, 8)),"\n";
print 'TKIP MIC Key(for Supplicant Tx)
', unpack('H*',substr($R, 56, 8)),"\n";
<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad0<div class="crayon-num" data-line="crayon-59e3ad1<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad2<div class="crayon-num" data-line="crayon-59e3ad3<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad4<div class="crayon-num" data-line="crayon-59e3ad5<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad6<div class="crayon-num" data-line="crayon-59e3ad7<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad8<div class="crayon-num" data-line="crayon-59e3ad9<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad0<div class="crayon-num" data-line="crayon-59e3ad1
use Digest::HMAC_SHA1 qw(hmac_sha1);&if( $#ARGV != 4){&&print "Usage: perl $0 PMK AA SPA ANonce SNonce\n";&&print "&&&&&& PMK&&&& -- Pairwise Master Key&&&&&& 32 bytes\n";&&print "&&&&&& AA&&&&&&-- Authenticator MAC address&&6 bytes\n";&&print "&&&&&& SPA&&&& -- Supplicant MAC address&&&& 6 bytes\n";&&print "&&&&&& ANonce&&-- Authenticator Nonce&&&&&& 32 bytes\n";&&print "&&&&&& SNonce&&-- Supplicant Nonce&&&&&&&&&&32 bytes\n";&&print "All input should be hexadecimal characters\n";&&exit 0;}&if(length $ARGV[0] !=64){&&print "PMK MUST be 32 bytes\n";&&exit 0;}if(length $ARGV[1] !=12){&&print "AA MUST be 6 bytes\n";&&exit 0;}if(length $ARGV[2] !=12){&&print "SPA MUST be 6 bytes\n";&&exit 0;}if(length $ARGV[3] !=64){&&print "ANonce MUST be 32 bytes\n";&&exit 0;}if(length $ARGV[4] !=64){&&print "SNonce MUST be 32 bytes\n";&&exit 0;}&$ARGV[0]=uc $ARGV[0];$ARGV[1]=uc $ARGV[1];$ARGV[2]=uc $ARGV[2];$ARGV[3]=uc $ARGV[3];$ARGV[4]=uc $ARGV[4];&$pmk&&&&= pack 'H*', $ARGV[0];$aa&&&& = pack 'H*', $ARGV[1];$spa&&&&= pack 'H*', $ARGV[2];$anonce = pack 'H*', $ARGV[3];$snonce = pack 'H*', $ARGV[4];@z&&&&&&= sort $ARGV[1],$ARGV[2];$bb&&&& = $z[0].$z[1];@z&&&&&&= sort $ARGV[3],$ARGV[4];$bb&&&&.= $z[0].$z[1];$b&&&&&&= pack 'H*', $bb;&my $debug = 0;&if ($debug){&&print &&QQQ;&&&&以下摘自 IEEE 802.11i&&&&PTK ←&&PRF-X(PMK, "Pairwise key expansion", Min(AA,SPA) || Max(AA,SPA) || Min(ANonce,SNonce) || Max(ANonce,SNonce))&&&&&&&&&&= PRF-X(K,&&&&A,&&&&&&&&&&&&&&&&&&&&&& B)&&&&&&&&TKIP uses X = 512 and CCMP uses X = 384&&&&&&&&PRF-384(K, A, B) = PRF(K, A, B, 384)&&&&PRF-512(K, A, B) = PRF(K, A, B, 512)&&&&&&&&PRF(K, A, B, Len)&&&&&&for i&&← 0 to (Len+159)/160 do&&&&&&&&R ← R || H-SHA-1(K, A, B, i)&&&&&&return L(R, 0, Len)&&&&&&&&H-SHA-1(K, A, B, X) ← HMAC-SHA-1(K, A || Y || B || X)&&&&K is a key&&&&A is a unique label for each different purpose of the PRF&&&&B is a variable-length string&&&&Y is a single octet containing 0&&&&X is a single octet containing the loop parameter i&&&&|| denotes concatenation&&&&&&&&总结&&&&B = min(AA,SPA) || Max(AA,SPA) || Min(ANonce,SNonce) || Max(ANonce,SNonce)&&&&计算&& hmac_sha1("Pairwise key expansion"||0x00||B||0x00, PMK)&&&&&&&&|| hmac_sha1("Pairwise key expansion"||0x00||B||0x01, PMK)&&&&&&&&|| hmac_sha1("Pairwise key expansion"||0x00||B||0x02, PMK)&&&&&&&&|| hmac_sha1("Pairwise key expansion"||0x00||B||0x03, PMK)&&&&&&&&|| ...&&&&取上述结果前 384/512 BitQQQ}&undef $R;$Len = 512/8; # 384 -- TKIP, 512 -- CCMP$zero = pack 'H2',0;$a = "Pairwise key expansion";for $i (0 ... ($Len+19)/20){&&$idx = pack 'h2',$i;&&$R .= hmac_sha1($a.$zero.$b.$idx, $pmk);}&print "\n";print 'EAPOL-Key Confirm Key&&&&&&&&&&&&&& ', unpack('H*',substr($R, 0, 16)),"\n";print 'EAPOL-Key Encrypt Key&&&&&&&&&&&&&& ', unpack('H*',substr($R, 16, 16)),"\n";print '(TKIP|CCMP) Temporal Key&&&&&&&&&&&&', unpack('H*',substr($R, 32, 16)),"\n";print 'TKIP MIC Key(for Authenticator Tx)&&', unpack('H*',substr($R, 48, 8)),"\n";print 'TKIP MIC Key(for Supplicant Tx)&&&& ', unpack('H*',substr($R, 56, 8)),"\n";
C:\&perl PMK2PTK.pl a288fcf0caaacda9a9f52a01d9c10ba5e02efdf8cb5d730ce7bc 000cd9382363a
3e8e967dacd960324cac5b6aab989f49d04ed47c6933
cdf405ceb9d889ef3decfae546b7add7baecbb1a394eac
上面命令行实际在一行内输入,只处为折行显示
输出如下:
EAPOL-Key Confirm Key
b1cdfd16511
EAPOL-Key Encrypt Key
82a644133bfa4e0b75d96d
(TKIP|CCMP) Temporal Key
beaeab32f12c7e
TKIP MIC Key(for Authenticator Tx)
TKIP MIC Key(for Supplicant Tx)
从输出结果中看到,PTK 并不是一个单独的密钥,而是分成若干部分
其中 EAPOL-Key Confirm Key 和 EAPOL-Key Encrypt Key 仅用于 EAPOL-Key 的四次握手(对握手报文起加密和认证作用)
第三行 (TKIP|CCMP) Temporal Key 参与报文的加解密,在我们讨论的上下文中,就是 CCM 中的分组密钥 K
最后二行 TKIP MIC Key(...) 仅适用于 TKIP 协议,与 CCMP 协议无关
下面以报文 #99 为例,剖析 CCMP 的具体操作,报文内容如下
08 41 2c 00 00 0c 41 82 b2 55 00 0d 93 82 36 3a -- IEEE 802.11 Data 报文头
ff ff ff ff ff ff b0 01 01 00 00 20 00 00 00 00
7e cc f6 0a c1 dd ff b0 47 96 c3 0b a1 9c 92 c6 -- 此行开始共 336 字节(共 21 行)为密文部分
6f 4d 1c e7 27 08 c2 95 cf 58 19 45 8c 18 d5 1f
提取为文件 wpa-Induction-cipher.txt
64 56 7a 7c c5 ff 85 e7 a6 8b 23 8a 33 5e 44 44
f7 de 0c 5e ef 72 1d 9f db 0d 51 44 03 d1 c9 06
46 15 23 3e fc e2 4b 41 6d 53 8c 88 84 5e 46 0d
29 63 0e da 72 97 fd db b5 66 ac 0a 05 f9 21 1f
bf 24 39 9a 15 a9 15 11 04 39 bd 0c 0c 51 0a 08
4a 88 90 50 01 fc 64 cc 9a 4f ca d2 51 d6 e0 f1
55 00 b7 13 fb 42 c2 44 60 58 2a 68 d0 a5 b9 9c
80 8e 01 2c 20 0a c5 27 b0 eb 32 0f 75 7d 60 ea
01 fa 79 f6 5c 2f c3 55 66 90 62 d9 25 e3 e4 4c
02 91 c1 a7 36 d5 0f 0b 8c 6c 68 de 9e 53 6e d9
7f eb 43 93 82 80 4b 73 92 3a 61 7f cc ef 37 60
cf 65 98 f7 7e 39 b9 90 a6 d1 67 ab 5c a6 a9 57
76 38 fe a8 34 2c 97 ab d5 54 f5 6f ea 48 eb 48
be 52 df c8 27 66 7b 1c 09 08 78 58 b9 96 9a 74
10 2d 53 e3 7d 35 2e e4 62 44 84 3d 02 f5 1b 04
43 64 cb 26 33 fd 2e 8c 16 0a 21 31 24 56 e5 74
74 89 33 e0 d8 49 5b e8 23 97 d8 9c b7 39 f7 ab
a0 e8 44 c2 b8 dc 3a 3d 57 d1 a7 b0 7e a9 ff 97
a3 d7 17 ff 02 83 0b 58 2c a8 94 27
-- 本行中前 8 字节为认证字段部分,后 4 字节为 FCS
CCMP 协议规定:认证字段长度 M = 8
现在已经知道分组密钥 K = beaeab32f12c7e
另两个参数 AAD/Nonce,它们在 IEEE 802.11i 有详细定义,这里直接给出结果
AAD = l(a) || a,构造比较复杂,我们估且认为它是下列字段的组合(实际上做了一些修正,感兴趣可参考标准)
l(a) || Frame Control || Address 1 || Address 2 || Address 3 || Sequence Control || Address 4 || Qos Control
其中最后两个字段 Address 4、Qos Control 为可选字段, 所以 AAD 长度范围是 24-32 字节
将 AAD 以 16 字节为单位分组,得到 B_1、B_2 两个附加认证分组,其中 B_2 可能要用 0 填充
在本例中,实际的 AAD 内容为(最后两个字段 Address 4、Qos Control 不存在,末尾填充 0)
00 16 08 41 00 0c 41 82 b2 55 00 0d 93 82 36 3a ff ff ff ff ff ff 00 00 00 00 00 00 00 00 00 00
此处开始用 0 填充
生成 AAD 分组文件
C:\&perl -e "binmode STDOUT; print pack('H*','cd9382363affffffffffff')" & aad.txt
Nonce 相对简单,其长度 = 15 - L = 15 - 2 = 13,格式为
Nonce = Priority Octet || A2
|| 00 0d 93 82 36 3a || 00 00 00 00 00 01
= 00 00 0d 93 82 36 3a 00 00 00 00 00 01
B_0 = Flags || Nonce
|| 00 00 0d 93 82 36 3a 00 00 00 00 00 01 || 01 50 -- 0x0150 = 336
= 59 00 00 0d 93 82 36 3a 00 00 00 00 00 01 01 50
生成 B_0 分组文件
C:\&perl -e "binmode STDOUT; print pack('H*','')" & b_0.txt
计算 A_i ...
A_0 = 01 00 00 0d 93 82 36 3a 00 00 00 00 00 01 00 00
A_1 = 01 00 00 0d 93 82 36 3a 00 00 00 00 00 01 00 01
生成 A_1 || A_2 || ... 分组文件
C:\&perl -e "binmode STDOUT; for($i=1;$i&22;$i++){print pack('H28n','00001',$i)}" & a_i.txt
# 循环 21 次,因为 21 * 16 = 336,索引为何从 1 开始,参见上节
计算密钥流 E( K, A_1 || A_2 || ... )
C:\&openssl enc -aes-128-ecb -K beaeab32f12c7e -iv 0 -nopad -in a_i.txt & enc_key.txt
密文 与 加密密钥 异或,得到明文
xor_file.pl
if ( $#ARGV &= 0 )
print &&QQQ;
用法:perl $0 file1 file2 ...
举例:perl $0 a.txt b.txt c.txt
说明:文件个数必须 &= 2
binmode STDOUT;
# 检查其余入参是否为十六进制和长度相等
foreach (@ARGV){
open INFILE, "&", $_ or die $!;
binmode INFILE;
local $/ =
$buffer = &INFILE&; # 一次性读入所有文件内容
close (INFILE);
push @file_content, $
my $result = pack('H2', "00");
# 逐一提取每个文件内容,进行 XOR
foreach (@file_content){
$result = $result ^ $_;
#print uc unpack('H*', $result);
<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad
if ( $#ARGV &= 0 ){&&print &&QQQ;&&&&用法:perl $0 file1 file2 ...&&&&举例:perl $0 a.txt b.txt c.txt&&&&说明:文件个数必须 &= 2QQQ&&exit 0;}&my @file_content;&binmode STDOUT;&# 检查其余入参是否为十六进制和长度相等foreach (@ARGV){&&open INFILE, "&", $_ or die $!;&&binmode INFILE;&&local $/ = undef;&&$buffer = &INFILE&; # 一次性读入所有文件内容&&close (INFILE);&&push @file_content, $buffer;}&my $result = pack('H2', "00");# 逐一提取每个文件内容,进行 XORforeach (@file_content){&&$result = $result ^ $_;}&#print uc unpack('H*', $result);print $result;
C:\&perl xor_file.pl wpa-Induction-cipher.txt enc_key.txt & wpa-Induction-plain.txt
明文内容是什么呢?我们对下答案,看看 Wireshark 自身的 CCMP 解密结果,如下图
原来是 DHCP Request 报文,这也说明 WiFi 安全属于二层安全范畴
仔细对比明文 wpa-Induction-plain.txt 的内容,完全符合
仅仅满足数据的机密性还是不够的,如何判断报文是否被篡改过?
CCMP 是通过附在密文后的 8 字节认证字段(红色显示部分)来解决的,下面按照 RFC 3610 中的规定进行验证
已知 A_0 = 01 00 00 0d 93 82 36 3a 00 00 00 00 00 01 00 00
生成 A_0 分组文件
C:\&perl -e "binmode STDOUT; print pack('H*','')" & a_0.txt
生成数据校验密钥 E(K, A_0)
C:\&openssl enc -aes-128-ecb -K beaeab32f12c7e -iv 0 -nopad -in a_0.txt & mac_key.txt
C:\&od -An -tx1 mac_key.txt
37 ef 73 a5 87 be 43 61 92 b3 6e ed c2 01 a3 49 -- 取前 8 字节 37 ef 73 a5 87 be 43 61
数据校验密钥 与 认证字段 异或,得到 X_n+1(即 CBC-MAC)的期望值
C:\&perl xor.pl 37ef73a587beff02830b58
结果为 XOR = D4839
而真实的 CBC-MAC 由密钥 K 对 -- B_0 || AAD分组 || WiFi明文分组(wpa-Induction-plain.txt) -- 进行 CBC 加密得到
合并 B_0 || AAD分组 || WiFi明文分组
C:\&perl -pe "BEGIN{binmode STDOUT;}" b_0.txt aad.txt wpa-Induction-plain.txt & b.txt
AES 加密计算 CBC-MAC
AES-CBC.pl
use Crypt::CBC;
if( $#ARGV != 3)
print "Usage: perl $0 encrypt/decrypt Key(hex) IV(hex) infile\n";
$cipher = Crypt::CBC-&new(
pack('H*', $ARGV[1]),
'Rijndael',
pack('H*', $ARGV[2]),
-blocksize
-literal_key
open INFILE, "&", $ARGV[3] or die $!;
binmode INFILE;
binmode STDOUT;
if ($ARGV[0] =~ /^e/)
$cipher-&start('encrypting');
local $/ =
$buffer = &INFILE&; # 一次性读入所有文件内容
print $cipher-&encrypt($buffer);
elsif ($ARGV[0] =~ /^d/)
$cipher-&start('decrypting');
local $/ =
$buffer = &INFILE&; # 一次性读入所有文件内容
print $cipher-&decrypt($buffer);
print "not encrypt/decrypt";
<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad
use Crypt::CBC;&if( $#ARGV != 3){&&print "Usage: perl $0 encrypt/decrypt Key(hex) IV(hex) infile\n";&&exit 0;}&$cipher = Crypt::CBC-&new(&&&&&&&&&&&&&&-key&&&&&&&&&&=&&&pack('H*', $ARGV[1]),&&&&&&&&&&&&&&-cipher&&&&&& =&&&'Rijndael',&&&&&&&&&&&&&&-header&&&&&& =&&&'none',&&&&&&&&&&&&&&-iv&&&&&&&&&& =&&&pack('H*', $ARGV[2]),&&&&&&&&&&&&&&-padding&&&&&&=&&&'none',&&&&&&&&&&&&&&-keysize&&&&&&=&&&16,&&&&&&&&&&&&&&-blocksize&&&&=&&&16,&&&&&&&&&&&&&&-literal_key&&=&&&1,);&open INFILE, "&", $ARGV[3] or die $!;binmode INFILE;binmode STDOUT;if ($ARGV[0] =~ /^e/){&&$cipher-&start('encrypting');&&local $/ = undef;&&$buffer = &INFILE&; # 一次性读入所有文件内容&&print $cipher-&encrypt($buffer);}elsif ($ARGV[0] =~ /^d/){&&$cipher-&start('decrypting');&&local $/ = undef;&&$buffer = &INFILE&; # 一次性读入所有文件内容&&print $cipher-&decrypt($buffer);}else{&&print "not encrypt/decrypt";}
C:\&perl AES-CBC.pl encrypt beaeab32f12c7e
b.txt & cbc-mac.txt
文件 cbc-mac.txt 的最后一个分组为
94 38 64 5A 85 3D 48 39 5B 35 A9 89 E6 47 A3 3B
其前 8 字节 D4839 与 期望值 相同,校验成功,说明报文未被篡改
再看报文最后一个字段 FCS(蓝色显示部分),在 CCMP 中也是起校验作用
不过校验范围为除 FCS 外的整个报文,即:报文头 || 密文 || 认证字段,不像 WEP 报文中是针对明文校验
同样也可以利用 perl 自带的 crc32.bat 脚本进行验证
CCMP(CTR with CBC-MAC Protocol) 是 IEEE 802.11i 中推出使用基于 AES 的 CCM 模式的安全加密协议。
与原来脆弱的 WEP 算法及临时补救措施 TKIP 协议相比,它具有更好的安全性,在 WiFi 中得到广泛的应用。
CCM(Counter with CBC-MAC) 定义在 RFC 3610 中,它是一种使用分组算法(例如 AES)进行数据认证和加密的通用模式。
下面是 RFC 3610 中重要部分的中文注释和说明
Introduction
Counter with CBC-MAC (CCM) is a generic authenticated encryption block cipher mode.
CCM 对明文数据(记为 m,其长度记为 l(m))进行分组加密和认证,处理结果同时包括密文和认证字段
CCM is defined for use with 128-bit block ciphers, such as the Advanced Encryption Standard (AES).
专门用于 block size 为 128 位的分组加密算法,如 AES
CCM Mode Specification
For the generic CCM mode there are two parameter choices.
CCM 有 2 个参数选项
The first choice is M, the size of the authentication field.
Valid values are 4, 6, 8, 10, 12, 14, and 16 octets.
第 1 个选项: M -- 输出的认证字段长度(单位:字节),取值范围:4, 6, 8, 10, 12, 14, and 16
The second choice is L, the size of the length field.
Valid values of L range between 2 octets and 8 octets.
第 2 个选项: L -- 表示 l(m) 值的字节数( l(m) & 2^(8L) ),取值范围:2-8
将 M 和 L 转换为 M' 和 L'(以便容纳在一个字节中),转换关系如下
Description
----------------------------------------
Number of octets in authentication field
Number of octets in length field
CCMP 协议规定:M = 8 L = 2, 即 m 最长为 65535 字节,认证字段为 8 字节
Inputs -- 认证加密 m 所需的参数
An encryption key K suitable for the block cipher.
分组密钥 K
A nonce N of 15-L octets.
Within the scope of any encryption key K,
the nonce value MUST be unique.
随机数 N,15-L 字节长,在 K 的生命过程中要确保 N 不被重复使用
The message m, consisting of a string of l(m) octets where 0 &=
l(m) & 2^(8L).
The length restriction ensures that l(m) can be
encoded in a field of L octets.
此段内容上面已讲得很清楚
Additional authenticated data a, consisting of a string of l(a)
octets where 0 &= l(a) & 2^64.
This additional data is
authenticated but not encrypted, and is not included in the
output of this mode.
It can be used to authenticate plaintext
packet headers, or contextual information that affects the
interpretation of the message.
Users who do not wish to
authenticate additional data can provide a string of length zero.
附加认证数据 a,用于数据的完整性校验(不参与加密运算),可选
通常用于认证 报文头的明文字段 或 对消息理解有影响的上下文
The inputs are summarized as:
Description
-----------------------------------
-----------------------
Block cipher key/分组加密密钥
Depends on block cipher
Nonce/随机数
15-L octets
Message to authenticate and encrypt
l(m) octets
Additional authenticated data/附加认证数据
l(a) octets
Authentication -- 生成认证字段
The first step is to compute the authentication field T.
done using CBC-MAC [MAC].
We first define a sequence of blocks B_0,
B_1, ..., B_n and then apply CBC-MAC to these blocks.
第一步计算认证字段 T,使用 CBC-MAC 算法,该算法涉及输入分组 B_0,B_1, ..., B_n
The first block B_0 is formatted as follows, where l(m) is encoded in
most-significant-byte first order:
第一个数据分组 B_0 构成如下
Octet Number
------------
1 ... 15-L
16-L ... 15
字节(L 的值见 Flags 字节)
Within the first block B_0, the Flags field is formatted as follows:
分组 B_0 中的首字节 Flags 构成如下
Bit Number
----------
----------------------
Reserved (always zero)
M' (1--7) = (M-2)/2
L' (1--7) = L-1
Another way say the same thing is:
Flags = 64*Adata + 8*M' + L'.
B_0 构成如下
+----+-----+-----------+------------+
| 1 .. 15-L | 16-L .. 15 |
+----+-----+-----------+------------+
|内容 |Flags|
+----+-----+-----------+------------+
L -- m 的长度表示范围
(L 越大,m 可以越长)
/ Flags 展开后
+----+-+-----+-+-+-+-+-+-+
|L'(L) 决定
|5|4|3|2|1|0|
|Nonce 的长度
+----+-+-----+-+-+-+-+-+-+
|内容 |0|Adata| M'
+----+-+-----+-+-+-+-+-+-+
The Adata bit is set to zero if l(a)=0, and set to one if l(a)&0.
如果 Bit6(Adata 位)=0,表示要生成附加认证数据 a,否则表示没有
If l(a)&0 (as indicated by the Adata field), then one or more blocks
of authentication data are added.
These blocks contain l(a) and a
encoded in a reversible manner.
We first construct a string that
encodes l(a).
生成附加认证数据 a,需要构造认证数据块(一个或多个),数据块编码如下
If 0 & l(a) & (2^16 - 2^8), then the length field is encoded as two
octets which contain the value l(a) in most-significant-byte first
a 长度 & ,此情况比较普遍
The length encoding conventions are summarized in the following
Note that all fields are interpreted in most-significant-byte
first order.
First two octets
Followed by
-----------------
----------------
-------------------------------
0x0001 ... 0xFEFF
For 0 & l(a) & (2^16 - 2^8)
0xFF00 ... 0xFFFD
4 octets of l(a)
For (2^16 - 2^8) &= l(a) & 2^32
8 octets of l(a)
For 2^32 &= l(a) & 2^64
The blocks encoding a are formed by concatenating this string that
encodes l(a) with a itself, and splitting the result into 16-octet
blocks, and then padding the last block with zeroes if necessary.
These blocks are appended to the first block B0.
将 l(a)||a 分成 16 字节长的分组,必要时最后一个分组添加 0x00 补齐
这些分组依次添加到 B_0 后面(记为 B_1、B_2……)
After the (optional) additional authentication blocks have been
added, we add the message blocks.
The message blocks are formed by
splitting the message m into 16-octet blocks, and then padding the
last block with zeroes if necessary.
If the message m consists of
the empty string, then no blocks are added in this step.
附加认证分组添加后,我们构造明文分组,将 m 分成 16 字节长的分组
必要时最后一个分组补 0 对齐(如果 m 为空串,则此步省略)
The result is a sequence of blocks B0, B1, ..., Bn.
The CBC-MAC is
computed by:
最终得到 B_0||附加认证分组||明文分组,按下列公式计算 CBC-MAC
:= E( K, B_0 )
X_i+1 := E( K, X_i XOR B_i )
for i=1, ..., n
:= first-M-bytes( X_n+1 ) -- T 作为 MAC 值
+----+ | +----+
K--&|加密 | | |加密|
+----+ | +----+
Encryption -- 生成密文
To encrypt the message data we use Counter (CTR) mode.
define the key stream blocks by:
使用 Counter (CTR) 模式加密,首先计算如下密钥流
S_i := E( K, A_i )
for i=0, 1, 2, ...
The values A_i are formatted as follows, where the Counter field i is
encoded in most-significant-byte first order:
Octet Number
------------
1 ... 15-L
16-L ... 15
The Flags field is formatted as follows:
Bit Number
----------
----------------------
Reserved (always zero)
Reserved (always zero)
Another way say the same thing is:
Flags = L'.
A_i 构成如下
+----+-----+-----------+------------+
| 1 .. 15-L | 16-L .. 15 |
+----+-----+-----------+------------+
|内容 |Flags|
| Counter i
| -- Counter i 的值能够在 L 字节内表示
+----+-----+-----------+------------+
(因为 i &= l(m))
/ Flags 展开后
+----+-+-----+-+-+-+-+-+-+
|L'(L) 决定
|7|Adata|5|4|3|2|1|0|
|Nonce 的长度
+----+-+-----+-+-+-+-+-+-+
|M'=0 | L'
+----+-+-----+-+-+-+-+-+-+
M' 不同于 B_0(B_0 中始终不为 0)
The message is encrypted by XORing the octets of message m with the
first l(m) octets of the concatenation of S_1, S_2, S_3, ... .
that S_0 is not used to encrypt the message.
明文与密钥流异或,得到密文,S_0 不用于加密,但参与数据校验
K--&|加密 |
| 加密| ... |加密|
密钥: S_1 | S_2 | ... | S_n
明文: M_1 | M_2 | ... | M_n
密文: C_1 | C_2 | ... | C_n
The authentication value U is computed by encrypting T with the key
stream block S_0 and truncating it to the desired length.
T 与 S_0 的异或结果取前 M 字节,得到认证字段
U := T XOR first-M-bytes( S_0 )
Output -- 最终输出
取前 l(m) 字节
取前 M 字节
=================================
============
S_1/E(K,A_1) | S_2/E(K,A_2) | ... || S_0/E(K,A_0)
-----------------------------------------------------
= 最终输出 c
其中 X_i 计算如下
:= E( K, B_0 )
X_i+1 := E( K, X_i XOR B_i )
for i=1, ..., n
Test Vectors -- 使用测试数据进行计算演示
=============== Packet Vector #1 ==================
C0 C1 C2 C3
C4 C5 C6 C7
C8 C9 CA CB
CC CD CE CF
00 00 00 03
02 01 00 A0
A1 A2 A3 A4
Total packet length = 31. [Input with 8 cleartext header octets]
扣除 8 字节明文头,只有 31-8=23 字节需要处理
00 01 02 03
04 05 06 07
08 09 0A 0B
0C 0D 0E 0F
10 11 12 13
14 15 16 17
18 19 1A 1B
M_1 -- 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17
M_2 -- 18 19 1A 1B 1C 1D 1E
以下计算数据认证字段
CBC IV in: 59 00 00 00
03 02 01 00
A0 A1 A2 A3
A4 A5 00 17 -- 实际就是 B_0
|&--------------- Nonce ---------------&|
Flags = 0 1 0 1 1 0 0 1 (binary)
| | |---| |---|
L'=1 &--& L=2
M'=3 &--& M=8
| Adata=1 表示有认证字段
Reserved (always zero)
CBC IV out:EB 9D 55 47
73 09 55 AB
23 1E 0A 2D
FE 4B 90 D6
验证 X_1 := E( K, B_0 )
C:\&perl -e "binmode STDOUT; print pack('H*','A2A3A4A50017')" & B_0.txt
C:\&openssl enc -aes-128-ecb -K C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF -iv 0 -nopad -in B_0.txt & X_1.txt
C:\&od -An -tx1 -v X_1.txt
eb 9d 55 47 73 09 55 ab 23 1e 0a 2d fe 4b 90 d6
After xor: EB 95 55 46
71 0A 51 AE
25 19 0A 2D
FE 4B 90 D6
验证 X_1 XOR B_1 -- xor.pl 源码见后面
C:\&perl xor.pl
EB9DAB231E0A2DFE4B90D6
B_1 附加认证数据(8 字节)
EB9DAB231E0A2DFE4B90D6 X_1
--------------------------------------
XOR = EBAE25190A2DFE4B90D6
After AES: CD B6 41 1E
3C DC 9B 4F
5D 92 58 B6
9E E7 F0 91
验证 X_2 := E( K, X_1 XOR B_1 )
C:\&perl -e "binmode STDOUT; print pack('H*','EBAE25190A2DFE4B90D6')" & X_1_XOR_B_1.txt
C:\&openssl enc -aes-128-ecb -K C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF -iv 0 -nopad -in X_1_XOR_B_1.txt & X_2.txt
C:\&od -An -tx1 -v X_2.txt
cd b6 41 1e 3c dc 9b 4f 5d 92 58 b6 9e e7 f0 91
After xor: C5 BF 4B 15
30 D1 95 40
4D 83 4A A5
8A F2 E6 86
验证 X_2 XOR B_2
C:\&perl xor.pl C0D0E0F1617 CDB6411E3CDC9B4F5DF091
C0D0E0F1617 B_2 -- 从 B_2 开始起为明文部分
CDB6411E3CDC9B4F5DF091 X_2
--------------------------------------
XOR = C5BF4BD834AA58AF2E686
After AES: 9C 38 40 5E
A0 3C 1B C9
04 B5 8B 40
C7 6C A2 EB
验证 X_3 := E( K, X_2 XOR B_2 )
C:\&perl -e "binmode STDOUT; print pack('H*','C5BF4BD834AA58AF2E686')" & X_2_XOR_B_2.txt
C:\&openssl enc -aes-128-ecb -K C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF -iv 0 -nopad -in X_2_XOR_B_2.txt & X_3.txt
C:\&od -An -tx1 -v X_3.txt
<span style="color: # 40 5e a0 3c 1b c9 04 b5 8b 40 c7 6c a2 eb
After xor: 84 21 5A 45
BC 21 05 C9
04 B5 8B 40
C7 6C A2 EB
验证 X_3 XOR B_3
C:\&perl xor.pl C1D1EC3BC904B58B40C76CA2EB
C1D1E000000 B_3 -- B_3 作为明文最后一个分组,以 0 字节补齐
9C3BC904B58B40C76CA2EB X_3
--------------------------------------
XOR = 05C904B58B40C76CA2EB
After AES: 2D C6 97 E4
11 CA 83 A8
60 C2 C4 06
CC AA 54 2F
验证 X_4 := E( K, X_3 XOR B_3 )
C:\&perl -e "binmode STDOUT; print pack('H*','05C904B58B40C76CA2EB')" & X_3_XOR_B_3.txt
C:\&openssl enc -aes-128-ecb -K C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF -iv 0 -nopad -in X_3_XOR_B_3.txt & X_4.txt
C:\&od -An -tx1 -v X_4.txt
2d c6 97 e4 11 ca 83 a8 60 c2 c4 06 cc aa 54 2f
: 2D C6 97 E4
11 CA 83 A8 -- 取前 8 字节
以下计算密钥流
S_i := E( K, A_i )
for i=0, 1, 2, ...
A_i 是 L、Nonce、i 的函数,格式如下
01 00 00 00
03 02 01 00
A0 A1 A2 A3
A4 A5 00 00
|&--------------- Nonce ---------------&|
Counter(、0002...)
Flags = 0 0 0 0 0 0 0 1 (binary)
| | |---| |---|
L'=1 &--& L=2
| 相当于 Adata=0
Reserved (always zero)
CTR Start: 01 00 00 00
03 02 01 00
A0 A1 A2 A3
A4 A5 00 01 -- A_1
CTR[0001]: 50 85 9D 91
6D CB 6D DD
E0 77 C2 D1
D4 EC 9F 97 -- S_1
CTR[0002]: 75 46 71 7A
C6 DE 9A FF
64 0C 9C 06
DE 6D 0D 8F -- S_2
CTR[MAC ]: 3A 2E 46 C8
EC 33 A5 48
-- S_0 取前 M 字节
C:\&od -An -tx1 -v A_.txt
01 00 00 00 03 02 01 00 a0 a1 a2 a3 a4 a5 00 00 -- A_0
01 00 00 00 03 02 01 00 a0 a1 a2 a3 a4 a5 00 01 -- A_1
01 00 00 00 03 02 01 00 a0 a1 a2 a3 a4 a5 00 02 -- A_2
C:\&openssl enc -aes-128-ecb -K C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF -iv 0 -nopad -in A_.txt & key.txt
C:\&od -An -tx1 -v key.txt
3a 2e 46 c8 ec 33 a5 48 56 20 54 2c 02 2c c0 7d -- S_0
50 85 9d 91 6d cb 6d dd e0 77 c2 d1 d4 ec 9f 97 -- S_1
75 46 71 7a c6 de 9a ff 64 0c 9c 06 de 6d 0d 8f -- S_2
Total packet length = 39. [Authenticated and Encrypted Output]
00 01 02 03
04 05 06 07
58 8C 97 9A
61 C6 63 D2
F0 66 D0 C2
C0 F9 89 80
6D 5F 6B 61
DA C3 84 17
E8 D1 2C FD
----------------------------------------------================
<span style="color: #A0B0C0D0E0FB1C1D1E2DC697E411CA83A8
--------------------------------==============----------------
dcb6ddde077c2d1d4ec9fac6de9a3a2e46c8ec33a548
C:\&perl xor.pl C0D0E0FB1C1D1E2DC697E411CA83A8 dcb6ddde077c2d1d4ec9fac6de9a3a2e46c8ec33a548
C0D0E0FB1C1D1E2DC697E411CA83A8
dcb6ddde077c2d1d4ec9fac6de9a3a2e46c8ec33a548
--------------------------------------------------------------------
XOR = 588C979A61C663D2F066D0C2C0FF6B61DACCFDF926E0 正确
在 CCMP 中,对称密钥 K 同时对明文数据进行加密和认证,C(Confidentiality) 和 I(Integrality) 都得到了保证
而 S(Signature) 和 A(Authentication) 是否达标,则取决于对称密钥 K 的安全性
从 IEEE 802.11i 中我们知道,K 是由著名的 EAPOL-Key 四次握手衍生得到,其安全性又取决于 PMK
PMK 又来自哪里?
IEEE 802.11i 标准中有两种工作模式:PSK 和 802.1X。
在 PSK 模式中,AP 和所有 STA 预先共享同一个密钥,该共享密钥经过简单的变换得到 PMK(后面将给出公式)
原则上 AP 无法区别不同的 STA -- 排除其他方式比如 MAC 地址过滤 -- 所以做不到 A(Authentication)
因为 AP 只知道有一个掌握了预共享密钥的家伙连上我了
至于这个家伙是谁?他的预共享密钥是不是偷来的?AP 一概不知
PSK 模式下 STA 反过来也无法认证 AP,这有点类似 GSM 网络中的伪基站
在 802.1X 模式中,安全性得到了增强,认证协议为 EAP,包含的认证子协议有 EAP-TLS/EAP-TTLS/EAP-PEAP 等
上述三种子协议都采用 TLS 隧道加密,天然支持 STA 对 AP 的认证
如果是 EAP-TLS 协议,还需要部署 STA 证书,因而可以做到相互认证,在这种情况下 SCIA,安全特性一个也不少
最后附上 xor.pl 源代码
if ( $#ARGV &= 0 )
print &&QQQ;
用法:perl $0 arg1[十六进制] arg2[十六进制] ...
举例:perl $0 90
规定:入参个数必须 &= 2,且所有入参长度必须相同(因为是位操作)
$debug = 1;
$first_arg = $ARGV[0];
$first_arg_len = length $first_
die "$first_arg is NOT hex number\n" if ( ! is_hex($first_arg) );
die $first_arg, "'s length is NOT even number\n" if ( $first_arg_len % 2 );
# 检查其余入参是否为十六进制和长度相等
foreach (@ARGV){
$cur = $_;
die "$cur is NOT hex number\n" if ( ! is_hex($cur) );
$curlen = length($cur);
die $cur, "'s length is NOT equal to first arg: [$first_arg]'s\n" if ( $curlen != $first_arg_len );
$_\n" foreach @ARGV;
print " ------", "-" x $first_arg_len, "\n XOR = ";
# 从前往后,逐一抽取所有入参的每个字节,进行 XOR
$xor_len = $first_arg_len / 2;
foreach $cur_index (1 .. $xor_len){
my @bytearry = map {substr($_,2*($cur_index-1),2)} @ARGV;
xor_args(@bytearry);
sub xor_args {
my $result = pack('H2', "00");
foreach (@_){
my $cur_byte = pack('H2', $_);
$result = $result ^ $cur_
print uc unpack('H2', $result);
sub is_hex {
return 0 if ($_[0] =~ /[^A-Fa-f0-9]/);
<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad
if ( $#ARGV &= 0 ){&&print &&QQQ;&&&&用法:perl $0 arg1[十六进制] arg2[十六进制] ...&&&&举例:perl $0
&&&&规定:入参个数必须 &= 2,且所有入参长度必须相同(因为是位操作)QQQ&&exit 0;}&$debug = 1;&$first_arg = $ARGV[0];$first_arg_len = length $first_arg;die "$first_arg is NOT hex number\n" if ( ! is_hex($first_arg) );die $first_arg, "'s length is NOT even number\n" if ( $first_arg_len % 2 );&# 检查其余入参是否为十六进制和长度相等foreach (@ARGV){&&$cur = $_;&&die "$cur is NOT hex number\n" if ( ! is_hex($cur) );&&$curlen = length($cur);&&die $cur, "'s length is NOT equal to first arg: [$first_arg]'s\n" if ( $curlen != $first_arg_len );}&print "&&&&&& $_\n" foreach @ARGV;print " ------", "-" x $first_arg_len, "\n XOR = ";&# 从前往后,逐一抽取所有入参的每个字节,进行 XOR$xor_len = $first_arg_len / 2;foreach $cur_index (1 .. $xor_len){&&my @bytearry = map {substr($_,2*($cur_index-1),2)} @ARGV;&&xor_args(@bytearry);}&sub xor_args {&&my $result = pack('H2', "00");&&foreach (@_){&&&&my $cur_byte = pack('H2', $_);&&&&$result = $result ^ $cur_byte;&&}&&print uc unpack('H2', $result);}&sub is_hex {&&return 0 if ($_[0] =~ /[^A-Fa-f0-9]/);&&1;}
WEP加密报文如下,其加密密钥为ASCII字符串:12345
将报文以十六进制显示,红色表示加密部分
22 33 44 55 10 00
00 00 3C FC BF 00 9A 6E
D C4 2D 3D 6B B1 55
FD DB D9 2F 9F EB 81 5F
A0 53 E2 DD CD E5 25 83
E9 87 98 D1 70 2E 55 8A
9D A9 21 35 FF 09 E8 03
0E 77 DD F9 8D 5C 0A 78
E8 C6 08 76 99 BD 6F BF
75 48 4F BD 5D 76 C5 F9
3D A5 5D BA EE DD
具体加密过程见下图 -- 引用自 Wikipedia(加上评注)
上图说明,将报文中的 Initialization Vector 字段和 WEP 密钥(连接后)作为 RC4 算法的密钥种子,生成密钥码流,再逐个与明文异或,就得到密文
现在已知报文密钥,剩下就是利用工具对其解密得到明文—这里我们继续利用 OpenSSL
OpenSSL 的 enc 命令支持 rc4 算法,其 -K 选项后跟 RC4 密钥种子,对应上图中的 seed
不过在使用前,需要改动一点代码,因为 enc 命令强制使用固定长度的 seed(实际 RC4 允许变长的 seed),具体为
如果 -K 选项指定的 seed 长度不足,则会用零补齐,凑够固定长度,如下
C:\&openssl rc4 -K ABC -iv 0 -nosalt -e -nopad -P
key=ABC00000
<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad
C:\&openssl rc4 -K ABC -iv 0 -nosalt -e -nopad -Pkey=ABC00000
如果 seed 超出固定长度,则截短为固定长度
C:\&openssl rc4 -K ABCDEFABCDEF0 -iv 0 -nosalt -e -nopad -P
key=ABCDEFABCDEF
C:\&openssl rc4 -K ABCDEFABCDEF0 -iv 0 -nosalt -e -nopad -Pkey=ABCDEFABCDEF
以上使用 -P 选项打印实际的 key(其实是 seed)
这里 RC4 密钥种子为 Initialization Vector||WEP Key = 0x3cfcbf,为 64 位,会被补零,造成解密错误
怎么改呢?只要修改文件 crypto\evp\e_rc4.c,如下,将 EVP_CIPHER_CTX_key_length(ctx) 改为 strlen(key)
static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
RC4_set_key(&data(ctx)-&ks, /*EVP_CIPHER_CTX_key_length(ctx)*/ strlen(key),
<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad<div class="crayon-num" data-line="crayon-59e3ad
static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,&&&&&&const unsigned char *iv, int enc){&&RC4_set_key(&data(ctx)-&ks, /*EVP_CIPHER_CTX_key_length(ctx)*/ strlen(key),&&&&&&&&key);&&return 1;}
需要指出,这只是临时的 Workaround,它会影响 -k(小写) 选项:OpenSSL 内部会先调用 EVP_BytesToKey 函数进行 Key Derivation
随后在 rc4_init_key 函数中,RC4_set_key 的入参会发生变化。感兴趣可以调试跟踪一下
顺带说下,EVP_BytesToKey 不兼容标准的 PBKDF2(参见 RFC2898)
运行修改版本的 OpenSSL
C:\&openssl rc4 -K 3cfcbf -iv 0 -nosalt -e -nopad -p -in wep_cipher.txt -out wep_plain.txt
key=3CFCBF00
<div class="crayon-num" data-line="crayon-59e3ad<div class="crayon-num crayon-striped-num" data-line="crayon-59e3ad
C:\&openssl rc4 -K 3cfcbf -iv 0 -nosalt -e -nopad -p -in wep_cipher.txt -out wep_plain.txtkey=3CFCBF00
wep_cipher.txt 文件内容如下
h: 9A 6E 50 1D C4 2D 3D 6B B1 55 FD DB D9 2F 9F EB
h: 81 5F A0 53 E2 DD CD E5 25 83 E9 87 98 D1 70 2E
h: 55 8A 9D A9 21 35 FF 09 E8 03 0E 77 DD F9 8D 5C
h: 0A 78 E8 C6 08 76 99 BD 6F BF 75 48 4F BD 5D 76
h: C5 F9 3D A5 5D BA EE DD
wep_plain.txt 文件内容如下
h: AA AA 03 00 00 00 08 00 45 00 00 3C 7A 8C 00 00
h: 80 01 3C CC C0 A8 01 16 C0 A8 01 02 00 00 86 56
h: 02 00 CD 05 61 62 63 64 65 66 67 68 69 6A 6B 6C
h: 6D 6E 6F 70 71 72 73 74 75 76 77 61 62 63 64 65
h: 66 67 68 69 42 74 BA 61
究竟明文是什么报文呢?我们可以使用 wireshark(本例为版本 1.8.6)查看,前提是添加解密密钥,如下
菜单【Edit】--&【Preferences】,选 IEEE 802.11 --& Edit
下图为 wiresharek 显示的明文
原来是 ICMP ping 报文
有两个地方需要注意
1、wireshark 显示明文长度为 68 字节,少了 wep_plain.txt 后面的 4 个字节(见上面蓝色4字节),原因是 WEP 使用 CRC32}

我要回帖

更多关于 点g是三角形abc的重心 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信