Loading...  开局一张图:后面的详细过程,还是推荐看遍课程演示,文字不好解释,略过。 # 用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博客](https://blog.csdn.net/MikeCoke/article/details/113790052) # 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 最后修改:2023 年 11 月 19 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 2 如果觉得我的文章对你有用,请随意赞赏