开局一张图:后面的详细过程,还是推荐看遍课程演示,文字不好解释,略过。
用Python实现AES加解密(ECB)
这和之前的DES写法很想,得融汇贯通。
hex编码
from Crypto.Cipher import AES
import binascii
key = b'0123456789123456'#密钥必须是16字节
text = 'www.52ying.top'
#明文数据必须是16字节的倍数,否则就要进行填充
text = text + (16-len(text)%16)*'='
print('填充之后:',text)
aes = AES.new(key,AES.MODE_ECB)
enCryptext = binascii.b2a_hex(aes.encrypt(text.encode()))
print("加密并编码后:",enCryptext)
deCryptext = aes.decrypt(binascii.a2b_hex(enCryptext))
print("解码并解密后:",deCryptext)
base64编码
from Crypto.Cipher import AES
import base64
key = b'0123456789123456'
text = 'www.52ying.top'
text = text+(16-(len(text)%16))*"-"
print('填充后:',text)
aes = AES.new(key,AES.MODE_ECB)
enCryptext = base64.standard_b64encode(aes.encrypt(text.encode()))
print('加密并编码后:',enCryptext)
deCryptext = aes.decrypt(base64.standard_b64decode(enCryptext))
print("解密并解码:",deCryptext)
AES-ECB-196
区别就是密钥长度变成了24字节
from Crypto.Cipher import AES
from Crypto import Random
import base64
key = b'012345678901234567891234'#密钥必须是24字节
text = 'www.52ying.top'
pad = lambda s:s+(16-len(text)%16)*chr((16-len(text)%16))
unpad = lambda s:s[0:-s[-1]]
text = pad(text)#填充处理
print("填充后:",text)
aes = AES.new(key,AES.MODE_ECB)
deCryptext = base64.standard_b64encode(aes.encrypt(text.encode()))
print("加密并编码后:",deCryptext)
enCryptext = aes.decrypt(base64.standard_b64decode(deCryptext))
print("解密后解码:",unpad(enCryptext))
AES算法的数据块大小有128、196和265等,在Python实现的过程中需要注意密钥的大小,对应的密钥大小分别是16, 24 或 32 位长度。
用Python实现AES加解密(CBC)
from Crypto.Cipher import AES
import base64
#填充方式PKCS7Padding
pad = lambda s:s+(16 - len(s) % 16) * chr(16 - len(s) % 16)
unpad = lambda s:s[0:-s[-1]]
# key可以是16, 24 或 32 位长度, 其对应 AES-128, AES-196 和 AES-256
key = b'12345678901234567890123456789012'
iv=b'1234567887654321'
text = 'www.52ying.top'
text = pad(text)
print('填充后:',text)
aes = AES.new(key,AES.MODE_CBC,iv)
enCryptext = base64.standard_b64encode(aes.encrypt(text.encode()))
print("加密并编码:",enCryptext)
aes1 = AES.new(key,AES.MODE_CBC,iv)
deCryptext = aes1.decrypt(base64.standard_b64decode(enCryptext))
print("解密并解码:",unpad(deCryptext))
注意一个小tips,在DES和AES的CBC模式下,不能实例化同一个对象进行加密与解密,必须实例化两个不同的对象,分别进行加密和解密哦。
例题
[ACTF新生赛2020]crypto-aes(考点:AES)_ctf aes-CSDN博客
MD5
import hashlib
def encrypt_md5(str):
new_md5 = hashlib.md5()
new_md5.update(str.encode(encoding='utf-8'))
return new_md5.hexdigest()
if __name__ == "__main__":
str = encrypt_md5('www.52ying.top')
print(str)
盐值的处理方式有多种,有些系统或者CMS中在处理用户密码的时候会添加"salt"来增强密码的安全性,下面整理一些加盐的处理方式。
MD5(password+salt)
MD5(salt+password)
MD5(salt+password),N次MD5加密
MD5(MD5(password)+salt)
MD5(salt+password+slat)
MD5(MD5(salt)+password+MD5(salt))
sha-1
from hashlib import sha1
def encrypt_sha1(str):
new_sha1 = sha1()
new_sha1.update(str.encode(encoding='utf-8'))
return new_sha1.hexdigest()
if __name__ == '__main__':
print("data: wwww.52ying.top")
mid_result = encrypt_sha1('www.52yibng.top')
print('sha1:',mid_result)
sha-256
SHA256是SHA-2下细分出的一种算法,哈希值长度是256位
from hashlib import sha256
def encrypt_sha256(str):
new_sha256=sha256()
new_sha256.update(str.encode(encoding='utf-8'))
return new_sha256.hexdigest()
if __name__ == '__main__':
print("data: www.52ying.top")
sha256_result = encrypt_sha256("www.52ying.top")
print("sha256: ",sha256_result)
sha-512
SHA256是SHA-2下细分出的一种算法,哈希值长度是512位
from hashlib import sha512
例题,0e绕过MD5()==比较
题目
<?php
include_once "flag.php";
ini_set("display_errors", 0);
$str = strstr($_SERVER['REQUEST_URI'], '?');
$str = substr($str,1);
$str = str_replace('key','',$str);
parse_str($str);#将用户提交的字符串转变成变量
echo md5($key1);
echo '<br>';
echo md5($key2);
echo '<br>';
if(md5($key1) == md5($key2) && $key1 !== $key2)
{
echo "取得flag:".$flag;
}
?>
这里的代码的大致功能有:
(1)、接收前端的数据并转换为变量,变量中过滤key;
(2)、计算两个变量的MD5值;
(3)、变量的MD5值相等且两个变量不相同的情况下打印flag
如果要获取flag,则需要绕过str_replace以及if中的条件。
(1)key关键词双写,kekeyy1/kekeyy2即可
(2)两个变量的MD5值以0e开头即可
PHP是弱类型语言,"=="在PHP下条件中基本上都是可以绕过的,如1和"1"、1和"1abc"等等,在题目中只要保证MD5的结果是以0e开头即可,在PHP中会被当做科学计数法,0e123==0eabc。在MD5值中以0e开头的数据大致有:s214587387a、QNKCDZO、240610708、s878926199a、s155964671a等,题目测试情况如下;
Payload:http://127.0.0.1:8800/?kekeyy1=s214587387a\&kkeyey2=240610708
结果:
0e848240448830537924465865611904
0e462097431906509019562988736854
取得flag:flag{www.ms08067.com}
数组绕过md5()== 比较
题目
<?php
include('flag.php');
$_GET['id']=urldecode($_GET['id']);
if (isset($_GET['uname']) & isset($_POST['passwd'])) {
echo 123;
if ($_GET['uname']==$_POST['passwd']) {
echo 'passwd can not be uname';
}else if (sha1($_GET['uname'])===sha1($_POST['passwd'])&
$_GET['id']=='cream') {
die('Flag:'.$flag);
}else
{
echo 'sorry!!!';
}
}
如果要获取flag,则需要满足一些条件,如:
(1)提交id、uname、passwd三个参数;
(2)uname和passwd不能相等,但是他们的sha1值恒等于
可以使用数组的方式来保证uname和passwd的值一样。所以最后测试的payload是:
http://192.168.1.215:88/sha1/?id=cream\&uname\[\]=abc
post数据:passwd[]=123