今天来聊聊python中的算法,比如AES,DES,RSA.......
1.MD5加密
md5是一个大的hash算法,它不存在解密的逻辑,市面上所为的解密是通过撞库来实现的.
我们可以简单的理解为生活中的防伪码
(1).不加salt----------简单理解为密钥
from hashlib import md5
obj=md5()
#准备加密的内容 #密钥也必须是字节
password="dasdas" #update给的必须是字节
obj.update(password.encode("utf-8"))#encode("utf-8"):把字符串变为字节
#获取秘文
miwen=obj.hexdigest()
print(miwen) #89defae676abd3e3a42b41df17c40096
(2).加salt
from hashlib import md5
salt=b"dsadasdasdasdasdasd" #密钥也必须是字节
obj=md5(salt)
#准备加密的内容
password="dasdas" #update给的必须是字节
obj.update(password.encode("utf-8"))#encode("utf-8"):把字符串变为字节
#获取秘文
miwen=obj.hexdigest()
print(miwen)
#加密后的0dfcc23994e6e7c63783ba4eb13d6a5c
2.base64
“Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法”。
(1).为什么会有 Base64 编码呢?
因为有些网络传送渠道并不支持所有的字节,例如:传统的邮件只支持可见字符的传送,像 ASCII 码的控制字符就不能通过邮件传送。这样用途就受到了很大的限制。
图片的二进制流的每个字节不可能全部是可见字符,这就导致图片的二进制流无法传送。最好的解决方式就是在不改变传统协议的情况下,做一种扩展方案来支持二进制文件的传送。即把不可打印的字符也能用可打印字符来表示,问题就解决了。
import base64
bs="我要吃饭了".encode("utf-8")
s=base64.b64encode(bs)
print(s) # b'5oiR6KaB5ZCD6aWt5LqG'
"""
变为base64字节的形式,
base64主要是要来处理字节的
把字节按照base64的规则,进行编码,编码成base64字符串形式
传入的内容必须是字节的形式
"""
import base64
bs="我要吃饭了".encode("utf-8")
#base64主要是要来处理字节的
#把字节按照base64的规则,进行编码,编码成base64字符串形式
s=base64.b64encode(bs).decode("utf-8")
print(s) #5oiR6KaB5ZCD6aWt5LqG
encode编码:字符串变为字节
decode解码:字节变为字符串
3.AES
(1).加密
import base64
from Crypto.Cipher import AES
s="这个是我要加密的明文" #要加密的东西必须是16的倍数
key=b"dasdasdasdasasdx" #key必须是16 24 32 为
aes=AES.new(key=key,mode=AES.MODE_CBC,IV=b"0102030405060708")#ebc一般不需要给iv
bs=s.encode("utf-8")
que=16-len(bs)%16 #缺少字节的个数
bs+=(que*chr(que)).encode("utf-8")
resp=aes.encrypt(bs) #加密的内容必须是字节 #encrypt:加密
b64=base64.b64encode(resp).decode("utf-8")
print(b64)
注意:加密的内容必须是16的倍数
这里提供一个好的包 from Crypto.Util.Padding import pad,
import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
s="这个是我要加密的明文" #要加密的东西必须是16的倍数
key=b"dasdasdasdasasdx" #key必须是16 24 32 为
aes=AES.new(key=key,mode=AES.MODE_CBC,IV=b"0102030405060708")#ebc一般不需要给iv
bs=pad(s.encode(),16)
resp=aes.encrypt(bs) #加密的内容必须是字节 #encrypt:加密
b64=base64.b64encode(resp).decode("utf-8")
print(b64)
结果是一样的
提供一个函数,使用时也可以copy
def to_16(data):
pad_len = 16-(len(data) % 16)
data+=(chr(pad_len) * pad_len).encode("utf-8")
return data
import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
s="这个是我要加密的明文" #要加密的东西必须是16的倍数
key=b"dasdasdasdasasdx" #key必须是16 24 32 为
aes=AES.new(key=key,mode=AES.MODE_CBC,IV=b"0102030405060708")#ebc一般不需要给iv
bs=to_16(s.encode())
resp=aes.encrypt(bs) #加密的内容必须是字节 #encrypt:加密
b64=base64.b64encode(resp).decode("utf-8")
print(b64)
(2).解密
from Crypto.Cipher import AES
import base64
miwen="TB2i3MKyp6lYmtO7qfX6ao7ytbeSWMn0z48iGtLjSV0="
key=b"dasdasdasdasasdx"
aes=AES.new(key=key,mode=AES.MODE_CBC,IV=b"0102030405060708")#ebc一般不需要给iv
bs=base64.b64decode(miwen)
resp=aes.decrypt(bs).decode() #decrypt:解密
print(resp)
如果aes进行的加密,拿就不可以进行解密,必须重新写
4.DES
这个在写法上面和aes差不多,上代码
(1).加密
from Crypto.Cipher import DES
s="我爱黎明"
des = DES.new(b'alexissb',mode=DES.MODE_CBC,IV=b'01020304')
bs = s.encode("utf-8")
que = 8 - len(bs)% 8 # 缺少字节的个数
bs += (que * chr(que)).encode('utf-8')
result = des.encrypt(bs)
print(result) #\xf3\xe0iI\xb5\x7f:1\xa4\xe9\x8e\xbamcR\x96
同样的这个也需要填充16位,
(2).解密
from Crypto.Cipher import DES
miwei=b"\xf3\xe0iI\xb5\x7f:1\xa4\xe9\x8e\xbamcR\x96"
aes = DES.new(b'alexissb',mode=DES.MODE_CBC,IV=b'01020304')
resp=aes.decrypt(miwei).decode("utf-8")
print(resp.strip(""))
5.RSA
(1).使用rsa生成密钥(公钥和私🔑)
from Crypto.PublicKey import RSA #生成密钥
rsa_key=RSA.generate(2048)
private_key=rsa_key.exportKey() #私钥
pulic_key=rsa_key.public_key().exportKey() #共🔑
with open("rsa_pulic_pem.txt",mode="wb")as f:
f.write(pulic_key)
with open("rsa_private_pem.txt", mode="wb") as f:
f.write(private_key)
公钥和私钥都可用于加密和解密
公钥和私钥都可以用于加解密操作,用公钥加密的数据只能由对应的私钥解密,反之亦然。虽说两者都可用于加密,但是不同场景使用不同的密钥来加密,规则如下:
1、私钥用于签名、公钥用于验签
签名和加密作用不同,签名并不是为了保密,而是为了保证这个签名是由特定的某个人签名的,而不是被其它人伪造的签名,所以私钥的私有性就适合用在签名用途上。
私钥签名后,只能由对应的公钥解密,公钥又是公开的(很多人可持有),所以这些人拿着公钥来解密,解密成功后就能判断出是持有私钥的人做的签名,验证了身份合法性。
2、公钥用于加密、私钥用于解密,这才能起到加密作用
因为公钥是公开的,很多人可以持有公钥。若用私钥加密,那所有持有公钥的人都可以进行解密,这是不安全的!
若用公钥加密,那只能由私钥解密,而私钥是私有不公开的,只能由特定的私钥持有人解密,保证的数据的安全性。
(1)加密
from Crypto.Cipher import PKCS1_v1_5 #RSA加密
from Crypto.PublicKey import RSA
import base64
#1:明文
message="我爱黎明"
#2:读取公🔑
f=open("rsa_pulic_pem.txt",mode="r",encoding="utf-8")
#3:把公🔑转化为rsa_key
rsa_key=RSA.import_key(f.read())
#4:创建加密对象
rsa=PKCS1_v1_5.new(rsa_key)
#5:加密
miwen=rsa.encrypt(message.encode("utf-8"))
#6:base64的处理
miwen=base64.b64encode(miwen).decode("utf-8")
print(miwen)
(2)解密
from Crypto.Cipher import PKCS1_v1_5 #RSA加密
from Crypto.PublicKey import RSA
import base64
#1:准备密文
miwen="anW+yPcaMVDCpBjkN68n+2xWyhqq3jJ6TmHkLrmEvxxr7Ux7ln9vT6TEcmDXQWO0SnpfvcZla6cK0qPYBGZg8tOnV67O44L6XX1Pb7jDB3DlO26SE2qKpXwfKZfH9pejYSaTbalv38saB3BWVybmfMAXOPBS6NQo/w0BPdI3aal4VX+CMHTuDua3724qxZc2hy0WztSySeRJNSGBj7ufd3t3CpUC+VxRgQt5dT7HaW9j5ttv29ILOwYmqnCvfVm4b4XKbvfD2Sr4NCzs33YuC4uT/aEvslULI0ysKaRKUkOsDn5+t1NvoMy/4gT8M8Nz6DcOc4mJObDg0EPW512dUQ=="
#2:读取私钥
f=open("rsa_private_pem.txt",mode="r",encoding="utf-8")
#3:生成私钥对象
rsa_key=RSA.import_key(f.read())
#4:生成解密对象
rsa=PKCS1_v1_5.new(rsa_key)
#5:处理base64
miwen_bytee=rsa.decrypt(base64.b64decode(miwen),None)
#6:utf8处理
miwen_bytee=miwen_bytee.decode("utf-8")
print(miwen_bytee)
encrypt:加密 decrypt解密
在平时公钥是可以在逆向中那到的,但是私钥是不行的,使用加密的逻辑使用的比较多
一个ras的小案例
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64
import requests
heard={
"Content-Type": "application/json;charset=UTF-8",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
}
password="1234567988"
pulic_key="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDA5Zq6ZdH/RMSvC8WKhp5gj6Ue4Lqjo0Q2PnyGbSkTlYku0HtVzbh3S9F9oHbxeO55E8tEEQ5wj/+52VMLavcuwkDypG66N6c1z0Fo2HgxV3e0tqt1wyNtmbwg7ruIYmFM+dErIpTiLRDvOy+0vgPcBVDfSUHwUSgUtIkyC47UNQIDAQAB"
ras_key=RSA.import_key(base64.b64decode(pulic_key))#因为公钥不完整所以把他编码成base64的字符串形式
#拿data和密码连节进行加密
resp=requests.post("https://user.wangxiao.cn/apis//common/getTime",headers=heard).json()
data=resp["data"]
password=password+data
#加密
rsa=PKCS1_v1_5.new(ras_key)
mi=rsa.encrypt(password.encode("utf-8"))
mi=base64.b64encode(mi).decode("utf-8")
print(mi)