Crypto入门-密码学杂谈

Diffie-Hellman密钥交换

在双方先前没有任何共同知识的情况下通过不安全信道协商出一个对称密钥。

DH密钥交换算法:双方选择一个pPZp的一个生成元g,在不安全的信道上发送。A选择一个秘密aZ,计算A=gamodp并发送给B。B选择一个秘密bZ,计算B=gbmodp并发送给A。A与B可共同得出密钥k=Abmodp=Bamodp=gabmodp

当中间人截获信息但不能修改时,知道A,B,g,p而不知道a,b,计算logaA,logbB很困难。

DH中间人攻击

当中间人可以截获并修改信息时。

中间人获取到pg。现在A正要把A发给B,此时中间人截获A,自己选定一个随机数e1,将A换成E1=ge1modp发给B。B把B发给A时同理,选定随机数e2,将B换成E2=ge2modp转发给A。

此时A计算出的密钥为k1=E2amodp=ge2amodp=Ae2modp,而B计算出的密钥为k2=E1bmodp=ge2amodp=Be1modp。此时中间人也可通过A,B,e1,e2计算出k1,k2,A向B发送加密消息时中间人拦截用k1解密,并用k2再次加密转发给B。

Hash长度扩展攻击

先了解基础知识:

以SHA-1举例,哈希函数拿到字符串后,将字节长度整除64取余数,如果正好等于56,则在字符串最后添上8字节长度描述符。如果不等于56,就先填充,填充的第一个字节为0x80,其他字节均用0x00,填充至余数为56后同样增加8个字节的长度描述符,这称为补位。

补位后,字符串每64字节为一组进行分组,每次进行一次逻辑函数序列后产生一组新的H值供下一次使用。当全部分组被处理完后,H中的值作为最终结果。

一般选择形如H(keymessage)的Hash函数,即在消息前固定一个密钥。但在MD型Hash算法(MD5、SHA-1等)的密钥长度已知、消息可控时易受到Hash长度扩展攻击。

具体攻击没看懂,挖坑待填。

例题:

php
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
$secret="XXXXXXXXXXXXXXX"; // This secret is 15 characters long for security!
$username="admin";
$password = $_POST["password"];
if($COOKIE["getmein"] === md5($secret . urldecode($username . $password))){
echo "Congratulations! You are a registered user.\n";
die ("The flag is ". $flag);
}
else{
die("Your cookies don't match up! STOP HACKING THIS SITE.");
}
//md5($secret."adminadmin")的值为571580b26c65f306376d4f64e53cb5c7
?>

$secret看成密钥,第一个“admin”当作密钥后半部分的可控制部分,这样一来密钥总长度为20,数据为第二个“admin”。

数据随便篡改为“pcat”,使用工具HashPump:

plaintext
1
2
3
4
5
# hashpump
Input Signature: 571580b26c65f306376d4f64e53cb5c7
Input Data: admin
Input Key Length: 20
Input Data to Add: pcat

得到结果:

plaintext
1
2
3e67e8f0c05e1ad68020df30bbc505f5
admin\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8\x00\x00\x00\x00\x00\x00\x00pcat

第一行塞Cookies的getmein中,第二行把“\x”改成“%”然后POST。

HashPump不好使,建议用pip安装hashpumpy,用法:

python
1
2
3
import hashpumpy
result=hashpumpy.hashpump('112bba932266ca5df55eb36dcd7050ec','This_is_salt','xx',28)
print(result[0],result[1])

Shamir门限方案

一种秘密共享方案,将秘密信息分成n份,只要有其中的k份即可将秘密解出。

设需要k份解出秘密消息m,选择k1个随机数a1,,ak1和大数pP,p>m,列出模p多项式f(x)=m+i=1k1aiximodp。随机选择n个整数x,代入上式得到n个数(x1,f(x1)),(x2,f(x2)),,(xn,f(xn))。恢复秘密信息时只需要k(xi,f(xi))对,利用拉格朗日插值法或矩阵乘法可求得秘密信息m

python
1
2
3
4
5
from secretsharing import PlaintextToHexSecretSharer
#加密 将字符串保存为5份密文 只需其中3份即可解密 密文存在shares中
shares=PlaintextToHexSecretSharer.split_secret('abcdefg',3,5)
#举例选前3个解密
res=PlaintextToHexSecretSharer.recover_secret(shares[0:3])