常见的加密算法
作者:YXN-python 阅读量:23 发布日期:2024-10-25
URL encode加密
当URL中出现中文时,或者传递的参数含中文时,浏览器可以正常的显示中文,但是当你把它复制下来的时候便会发现是一串含有百分号的字符,这其实是正常的。
import urllib.parse
text = '我爱学习'
s = urllib.parse.quote(text)
print(s)
u = urllib.parse.unquote(s)
print(u)
上面的代码,使用urllib.parse.unquote()方法便可以将编码重新转换为中文
运行结果
%E6%88%91%E7%88%B1%E5%AD%A6%E4%B9%A0 我爱学习
unicode编码
这种其实不算加密与解密的过程,应该属于编码与解码,这种也是针对中文字符
text = '你好'
# 编码
entext = text.encode('unicode-escape').decode()
print(entext)
# 解码
detext = entext.encode().decode('unicode-escape')
print(detext)
在进行解码时,先通过entext.encode()方法将编码好的数据转换为二进制,再通过decode()方法将二进制转换为字符串。
运行结果
\u4f60\u597d 你好
Base64加密
base64是一种用64个字符来表示任意二进制数据的方法
import base64
# 加密
def base64_encode(data):
encode_data = base64.b64encode(data.encode())
return encode_data.decode()
# 解密
def base64_decode(encode_data):
decode_data = base64.b64decode(encode_data)
return decode_data.decode()
if __name__ == '__main__':
text = 'I love Python'
encode_data = base64_encode(text)
print(encode_data)
decode_data = base64_decode(encode_data.encode())
print(decode_data)
运行结果
SSBsb3ZlIFB5dGhvbg== I love Python
MD5
MD5的全称是消息摘要算法。消息摘要算法的加密是单向的,意味着加密之后就无法解密,当然目前很多网站不停的运算MD5算法的解密,就是将加密与解密数据形成一个映射。
另外,消息摘要算法的特征是提取明文的重要特征进行加密,也就是说两个不同的明文可能出现的密文是一样的,不过概率极低。
另一个特征则是,其密文的长度是固定的,它通过一个函数,把任意长度的数据转换为长度固定的数据串(通常用十六进制的字符表示)
import hashlib
def md5_test1():
text = 'I love Python'
md5 = hashlib.new('md5', text.encode('utf-8'))
print(md5.hexdigest())
print(len(md5.hexdigest()))
def md5_test2():
md5 = hashlib.md5()
md5.update('I love '.encode('utf-8'))
md5.update('Python'.encode('utf-8'))
print(md5.hexdigest())
if __name__ == '__main__':
md5_test1()
md5_test2()
上述代码,以两种不同的方式对字符串进行了加密的过程,一种是通过直接将一串字符进行加密,另一种情况是将字符进行拼接加密。
运行结果如下:
27eb2f69c24aa5f3503a6ae610f23a83 32 27eb2f69c24aa5f3503a6ae610f23a83
PBKDF2
PBKDF2是RSA实验室的公钥加密标准(PKCS)系列的一部分。
它是将明文和盐值(salt)作为输入参数,然后进行重复运算,并最终产生密钥,如果重复的次数足够大,破解的成本就会比较高。同样,它也是用十六进制数表示。
注意:
pycrypto、pycryptodome、crypto是同一个东西,crypto在python中的名字是pycrypto,它是一个第三方库,但是已经停更了三年,所以不建议安装这个库。
解决方法是:pip install pycryptodome
但是导入模块是有问题的,这个时候只要修改一个文件夹的名称即可。
在python的安装文件夹下的\Lib\site-packages,下面有个文件夹叫做crypto,将小写的c改为大写的C即可。
import binascii
from Crypto.Hash import SHA1
from Crypto.Protocol.KDF import PBKDF2
text = 'I love Python'
salt = b'123456'
result = PBKDF2(text, salt, count=1000, hmac_hash_module=SHA1)
print(binascii.hexlify(result).decode())
print(len(binascii.hexlify(result).decode()))
运行结果
757cf385b9857d7a27d4edc0cf557d6c 32
SHA
全称是安全哈希算法,主要使用于安全签名标准里面定义的数字签名算法。SHA通常指的是其家族的五个算法:SHA-1、SHA-224、SHA-256、SHA-384、SHA-512,后四者有时并称为SHA-2、SHA是比MD5更安全的摘要算法。MD5密文是32位、而SHA-1是40位,版本越强、密文越长,代价是速度越慢。
import hashlib
def sha1_test1():
text = 'I love Python'
sha1 = hashlib.new('sha1', text.encode('utf-8'))
print(sha1.hexdigest())
def sha2_test2():
sha1 = hashlib.sha1()
text = 'I love Python'
sha1.update(text.encode('utf-8'))
print(sha1.hexdigest())
if __name__ == '__main__':
sha1_test1()
sha2_test2()
运行结果
9233eac58259dd3a13d6c9c59f8001823b6b1fee 9233eac58259dd3a13d6c9c59f8001823b6b1fee
HMAC
简介:全称散列消息认证码、密钥相关的哈希运算消息认证码。
HMAC加密算法是一种安全的基于加密的Hash函数和共享密钥的消息认证协议,它要求通信双方共享密钥Key、约定算法、对报文进行Hash运算,形成固定长度的认证码。
import hashlib
import hmac
def hmac_test1():
massage = b'I love Python'
key = b'secret'
md5 = hmac.new(key, massage, digestmod='md5')
print(md5.hexdigest())
def hmac_test2():
key = 'secret'.encode('utf-8')
sha1 = hmac.new(key, digestmod='md5')
sha1.update('I love '.encode('utf-8'))
sha1.update('Python'.encode('utf-8'))
print(sha1.hexdigest())
if __name__ == '__main__':
hmac_test1()
hmac_test2()
运行结果
49c5cc68061a01a30a71f52cb70201e5 49c5cc68061a01a30a71f52cb70201e5
AES
全称是高级加密标准,加密时主要参数是密文、密钥和偏移量。它是一种对称加密算法。
mode 支持:CBC,CFB,CTR,CTRGladman,ECB,OFB 等。
padding 支持:ZeroPadding,NoPadding,AnsiX923,Iso10126,Iso97971,Pkcs7 等
import base64
from Crypto.Cipher import AES
# 需要补位,str不是16的倍数那就补足为16的倍数
def add_to_16(value):
while len(value) % 16 != 0:
value += '\0'
return str.encode(value)
# 加密方法
def aes_encrypt(key, t, iv):
aes = AES.new(add_to_16(key), AES.MODE_CBC, add_to_16(iv)) # 初始化加密器
encrypt_aes = aes.encrypt(add_to_16(t)) # 先进行 aes 加密
# 执行加密并转码返回 bytes
encrypted_text = str(base64.encodebytes(encrypt_aes), encoding='utf-8')
return encrypted_text
# 解密方法
def aes_decrypt(key, t, iv):
# 初始化加密器
aes = AES.new(add_to_16(key), AES.MODE_CBC, add_to_16(iv))
# 优先逆向解密 base64 成 bytes
base64_decrypted = base64.decodebytes(t.encode(encoding='utf-8'))
# 执行解密密并转码返回str
decrypted_text = str(aes.decrypt(base64_decrypted), encoding='utf-8').replace('\0', '')
return decrypted_text
if __name__ == '__main__':
secret_key = '12345678' # 密钥
text = 'I love Python!' # 加密对象
iv = secret_key # 初始向量
encrypted_str = aes_encrypt(secret_key, text, iv)
print('加密字符串:', encrypted_str)
decrypted_str = aes_decrypt(secret_key, encrypted_str, iv)
print('解密字符串:', decrypted_str)
# 加密字符串:lAVKvkQh+GtdNpoKf4/mHA==
# 解密字符串:I love Python!
运行结果
加密字符串:lAVKvkQh+GtdNpoKf4/mHA== 解密字符串:I love Python
RSA非对称加密
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
def generate_rsa_keys():
# 生成RSA密钥对
key = RSA.generate(2048)
private_key = key.export_key()
public_key = key.publickey().export_key()
return private_key, public_key
def rsa_encrypt(public_key, message):
# 使用公钥加密
key = RSA.import_key(public_key)
cipher = PKCS1_OAEP.new(key)
return cipher.encrypt(message.encode())
def rsa_decrypt(private_key, encrypted_msg):
# 使用私钥解密
key = RSA.import_key(private_key)
cipher = PKCS1_OAEP.new(key)
return cipher.decrypt(encrypted_msg).decode()
if __name__ == "__main__":
# 生成密钥对
private_key, public_key = generate_rsa_keys()
print("私钥:", private_key.decode())
print("公钥:", public_key.decode())
# 要加密的消息
message = "Hello, this is a secret message!"
# 加密消息
encrypted_message = rsa_encrypt(public_key, message)
print("加密:", encrypted_message)
# 解密消息
decrypted_message = rsa_decrypt(private_key, encrypted_message)
print("解密:", decrypted_message)
运行结果
私钥: -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAt+ERBdNpv6aRFRnhs6Gbq610FEBXjz/kuQOvmT6pfchPMZvk T14lCKIMEl+6UpucvasMSfvrhtu2QXBgvAEJktJANZm+Had/4EWyUuCzMpJILjJY ktJgX5Cc8M0BUoSjLfAKHmtyxgDbRjpwN8FcXhaGbuCCJuYpoXRjewRM6enQEqs8 PuGzeqM4lLsd7RfxEWVTi++L1U6LbqsxrdlnHjPTG9qPxPeCDfGYWttkUu8gz2Ks jOewGcTP+kRuzgaxbWVRHnzuuNFOINU7l8K31n5RJlHtgmvL5CBfeW73/GChNA6/ Y3F4liuOqoLDGvtzmdvM3/rmU/07eKYvjzcwRwIDAQABAoIBACH2n1dNImY01O1p 12d/fSprolovPD0IVy3ZQXDzwwipm/8UxUnnoL2EeOhX6Clj9sKNunpb3rgNEw/p OuTe6C7HSPbdi+EcVCFPnk1ylYbMwCpQQE32L7jXFDXiF9FvEFjm0mel/xAVjmrd Vmbl/zKdxHzsWP3oW14oCkvpkm9N4Tg4efRH/npU2HNzXSAEYBRTm45fZnS3aQch GKudoaJp57SN+3F9mh4JalH80n83ikALGM2+b8tJzuyi0TayeZWbNgl7pVNijVCx wDHAthwTW5jMAn7xxY3Eg9TuA/resWCdVuGLeS6sv0c4T+lmkqLHOn0+WNshWU25 vG6z3NECgYEAyiS6V4qFO7s/m8T1W2kX9iLFzCg0f0LMB6BAwAXB/EzQzsc40M9S 2bVM9D4wHiC5LctzwgL6q1QFmoeCHDBKRw8UjFkotNUIXcCQ7N9S7VvmrouoS5Fv fFG9e9Bdx+Q51eYww1j2pSmJm2Tsn6cdm8JAijB0Ba+NFzeEL9BLhFkCgYEA6N6d atpt4L3xtmUP6ikdeuKzv8V1My/FdGC3jgsvmwj5Zl1EVYESqHsVGZ/et72OVtgV 5UwgH2dprjzmXNHk7f5eu+qJGdQNnSGU+CvIC6785mxmA+wdprD8hNffHFK30uk6 egYSzaBntXordrgvuoCKt4UbW4Zhyz1eGV5ERZ8CgYEAlBIPRWy8Z6Kj13CQ4aK7 4JpcFU4mFkpRtgxXIdGV5UBHfBBGt/4GDF9XvVmIWalSvA7Z/nW8NJ/ZcvZsAkYF QsPzI1N0E/IwrKwP/NMhpai584Vtg91GsuQVToq1B2VQUDTL52xVT2p72A43nkMF 10CVkiQn+Lo9OZJ7C6MijhECgYEAshQTI3R4VEZNAqNUQUhB0AhvVvakQomEoROZ KtmpBREez8YBDLYQ06CUKS1VfwNJR2YlkFzfr8RAT8soitDEFa/RODkJsSO1aXUV 25Z3e1/M7FT2yocUwbVU1i3S43DqPDK40jm0xWSmCmSrujTt4tyLt/3lRt+EB40d WZ757JcCgYBw4gwC1sjbJEMp0Af80BKZ8/TNP9VpJeSvo0nvsdMkH73P/jzXraYw wcgMyj4cDIFITdurd1VrojOQQGSjKdLfpwOK9GdgEXJZFJvEvyZHHv+yuO7xQSnC mGWAqEct4F24X+R2X2/Be9XtyptHCOTIK1zxlsmOsR6IYiNIyS4jKA== -----END RSA PRIVATE KEY----- 公钥: -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt+ERBdNpv6aRFRnhs6Gb q610FEBXjz/kuQOvmT6pfchPMZvkT14lCKIMEl+6UpucvasMSfvrhtu2QXBgvAEJ ktJANZm+Had/4EWyUuCzMpJILjJYktJgX5Cc8M0BUoSjLfAKHmtyxgDbRjpwN8Fc XhaGbuCCJuYpoXRjewRM6enQEqs8PuGzeqM4lLsd7RfxEWVTi++L1U6Lbqsxrdln HjPTG9qPxPeCDfGYWttkUu8gz2KsjOewGcTP+kRuzgaxbWVRHnzuuNFOINU7l8K3 1n5RJlHtgmvL5CBfeW73/GChNA6/Y3F4liuOqoLDGvtzmdvM3/rmU/07eKYvjzcw RwIDAQAB -----END PUBLIC KEY----- 加密: b'mb\xf8Jx\x8e\\\x90\xe5\x81\xeb-1\x05oO\x8f_\x9a\x01\xd0]\xba\xb1\xe4\xd3\x90\x04\x04\x14\x7f\xf5\xf8\x96\x91\xc2w\xb5\x99\xf9\xca\xe7$\x94%\xac\x10\x10iO\x8c\x92Q\xf6F\x968Q\x89\xe4\x97\xf4\x99\xcc\xb3\xb3,\x8e\xa8\xb1\xa9\x84\x15uob\x16\x0ft\xe5\xccs\xa5s\xc7\xdd\xc7\xf8j\xdfX\xb1\x80\xa6?t\x83\xf5\xbf\x9fy\xc6IO\x02\xb8X&\x80/P\x1d0_6g\xac\x96\xf1\xbc\x19\xc6\xd6\xec\x83\xfd\xf0\xa9C\xc7(E\xd4\xfeq\x02\x8e.\xdd\x88\xd6\xda_\x0b\xc8\xce\xb0\xfb\xcb\x1a\xe4\x81`u,V\xb3rH\xe6\xf5\xdf\x8e\x1a^og\xc6\xc6\xb1k\xa3\xea\x14\xbas\xc6v\xef\x81\xb9\x08*\x81c\xd1\xc1\x07\xfd\x1d^\x0e\xa9\x94\xe5\xc1\x12\x1a6\x97V\x9dL\xae\x1a\x8d\x8e\x83\x8d\xa5\r\xf9\x15\xe57\x182t\xc3[\xa7\x92G\x87@\x84\xf1`;\x1c\xd6\x8a2\xbdt+\xbf;\xb0\x83^.\x95\x85\r\x87hM\x1d\xcd\x1a\xe0\x08\x1b\xa7\x8f' 解密: Hello, this is a secret message!
数字签名
from Crypto import Random
from Crypto.PublicKey import RSA
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256
def sign_message(private_key, message):
# 创建签名
key = RSA.import_key(private_key)
h = SHA256.new(message.encode())
return pkcs1_15.new(key).sign(h)
def verify_signature(public_key, message, signature):
# 验证签名
key = RSA.import_key(public_key)
h = SHA256.new(message.encode())
try:
pkcs1_15.new(key).verify(h, signature)
return True
except (ValueError, TypeError):
return False
if __name__ == "__main__":
# 生成密钥对
key = RSA.generate(2048, Random.new().read)
private_key = key.export_key()
public_key = key.publickey().export_key()
print(f"私钥: {private_key.decode()}")
print(f"公钥: {public_key.decode()}")
# 签名消息
message = "这是一封需要签名的邮件."
signature = sign_message(private_key, message)
print(f"签名: {signature}")
# 验证签名
is_valid = verify_signature(public_key, message, signature)
print(f"签名有效吗? {is_valid}")
运行结果
私钥: -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAk6t8ooVpORraHKVgGAiJw4x8vJtSS2jkEyNM6IMen8sVLiAy w8orLLOdgQGhhSKkeMa1iTirLYh8lTT2O8c8lfArUbnVT4ku6E0Le7n8bOGxzgZ0 22s9MlqO0rsuBQyEV3p3k9ObXnLiwP1mY2KVjkl9dHP3X5dgXpz6n/2xBhVmOzVd 0vMbtJlJrPOxEjwdfu0a2DUB29kVWhViYbQ85JK0rdyOscLYmo3fOS56Jq7oZpql rg+MesecWBPvIOvKI6NCpj8syR97y9rviGx7cnrtGlEZ7LLJoce7taKd5QTK13L0 KkJSoDHnqSfzqk3QSffsE1tNnurkbPENSvCzMQIDAQABAoIBABOohiCKmx3nhba/ i0HXzSMzrh1bngJ89bPYhLIFVovWOL0ZuzhWTxYV2Tdl1K9JE9UiOuOIID2hCFjC oq8FkHqzbMjl8NA0RoLVUtyHP2PtTcLMGD1nks+Dv7StB2zTpECTBJ0w0+Oobqhb c4hyhM9a2DErCPj4SXN++VxYJPtWpRfbYeodivT+/vqCZJb99UNQSoXaI7BGqSIo co/VYDLPbHP7opYhueJVofNnsSv1FgZ7HpBG80N3cS2IggWe/UFaxRSpwWW1o2uK Jf/xiEWjXPvWf5fqnBhppIAdJpfWQqLKX19yjuYi/Eyefhs2KtYF0N9B5n+HTG0g 1GsyfUsCgYEAtyvpX5LazGG27wp0YC0UZdcckHNQj6KO6ezXVzs6YTVH5hoBkTMJ gYjCI/hgOklIqeYFuC7DH3JpZWYBi1R+RyS+MOq1HO49+CGb3oe4ur3Ra+kYM15A MAJpu/DBlsO2i/V2gqrlyzsdNq82Fk132fI4PnSnFrwgYm3WoSFPxJsCgYEAzmIL Odhp9+VsPGWhN/FNNbfgzR13s3v9cPWf6NcqJduFzqsXnC/bPr4f7779U9fCDs3H LPuugKaT3QpY8VB77C3T4FnRgnBo+IvYaPRkWF92NcpY8d7a8TWuwKzBQiN3dUwW wkh6X/efFnv0GlDmZIxXS3dzPgSsUMa+Pb3iliMCgYBa4rjrKSzTWHCybxeLWRLT 7UZJDk6c1mXfABthNwwii5NfQuwgJZjD4x2hR25HvXEGjBGub9V1VwmgvFprzcLS fhK4ptyyvCuXYOW8Js+sKN8ukfvmEQ/8QlZAYJdNvVJoY6Un9LAMhQpbxdgqfMnJ JHxv0OXPTA0tiZ6DWMoBnQKBgDRtI3zmRMT8Oqp9Bp83ZO2ocCqquaWWcaMoQh7b yZEkWrFNNQov/fnKQkKcua16uYkZLOd4Z7O2nQkhf8aNM22jlpb/OgFwnLnGjIrc ykDIvzaa2E1Y1zU+9c1sFQvABrB9S6q+zpdiR79mbXPh6STRobtB9LxkY4GBewIk IlMRAoGBAIjoJTgLt5EaHrVAseVpfKh45hlp4oEIJLWMuVt0CEmxoP7tqiokNmbn PzWYfTgd3F5+BfAKhqJZGDspzgpUDYSMz9AiHDpI+N575MmEb+HjG37acogNNa66 5EbDEzsylavxzpVcMy6DD0WIn8H4Tm/kEPoQKDCm5w3hWQTog8T6 -----END RSA PRIVATE KEY----- 公钥: -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk6t8ooVpORraHKVgGAiJ w4x8vJtSS2jkEyNM6IMen8sVLiAyw8orLLOdgQGhhSKkeMa1iTirLYh8lTT2O8c8 lfArUbnVT4ku6E0Le7n8bOGxzgZ022s9MlqO0rsuBQyEV3p3k9ObXnLiwP1mY2KV jkl9dHP3X5dgXpz6n/2xBhVmOzVd0vMbtJlJrPOxEjwdfu0a2DUB29kVWhViYbQ8 5JK0rdyOscLYmo3fOS56Jq7oZpqlrg+MesecWBPvIOvKI6NCpj8syR97y9rviGx7 cnrtGlEZ7LLJoce7taKd5QTK13L0KkJSoDHnqSfzqk3QSffsE1tNnurkbPENSvCz MQIDAQAB -----END PUBLIC KEY----- 签名: b'T\xab\x07\x9f\t\xcdz\xedR\xa7\xf6\xc3?\xb1Q\xfc\xefua\x0fRQ\xb67\x1d\xf0\x84n7\xc7}\x01\xc9\t\xe4\xfcd\xc5zz4D\x88\x17\xc0d\xa34\xec\x88J\x05#\xc1\x83&\xd3\xdd\xb4\x18\x8f \xad"\xfd\xdfP\xc1MH7{\xcdf2A\x08Y\x85#j\x91\x90\xa3\xba\x14\x85N#(\xa8\x99=\x14\xbc\x0b\x0e\xd9\xfaG\x02\'\xfd\xd4\x91\xfb\xf4\xfbZ\x1b\xeeW!\xc3\xb6\x00\xa8\x87*\x1fs\x0b\xecd\x0f\xaf\xaa\x17y\xadb$(\xd3*P,\xdfgY\xf1\x89\x1b\xe0{\x1c\xcf\xe9\xfc\xb6*\xcb\xb9\xe9g\x80\x1f\x05!\x15\x9c\xfe\x0c\x9e\x0e\xf8\xbd\xd2\xd5D\x17{\x03R\xb0\xa74\x10\xa9\xb4\xfaF\xa7\x11\x1a\x83*\xd2\x14\x88/\xcb\x8c\xbei\x1b\xe2\x93u\x9a\xf6\xb6\x1bIU\xad\xbf?k\xed\x9e\xba\xb0\x9a\x85\xb3y9\xde\xac4\xc1n\xf9\xe9\x03~\x18zp\x99d\xd6VCA\x13\xb4\x96\x8c\xd7\x9buv\x99\xab\x11\xbf\x06\xa8\xed\x8d\xc1rS\xae' 签名有效吗? True
YXN-python
2024-10-25