别再写假加密了!Python加密解密一篇就够
大家好,我是花姐,一个喜欢Python的技术控,表达能力不强,嘴笨但代码不笨。这篇文章我保证信息量巨大但不掉书袋,不整术语堆砌,咱要的是把事说清楚。
你会搞懂:
- 对称 vs 非对称加密到底是啥
- Python 里到底该用啥库,怎么用
- 实战中为什么你加密了还是被黑
- 不小心就会踩的坑,我给你全列出来
- 能直接跑、跑完就明白的代码
废话不多说,从一个“假加密”的例子讲起——
一、“假加密”入门:你被骗了不止一次
import base64
data = "密码123456"
encoded = base64.b64encode(data.encode())
print(encoded.decode())
Base64 是加密吗?不是。它只是编码,就像你把“猪”写成“ZHU”——谁都能看懂。 但很多 Python 初学者真的以为这样就加密了(糊弄糊弄普通人还行)
所以!今天我们搞的是正经货:对称加密、非对称加密、签名、认证,全安排。
二、对称加密:钥匙你我共用,用完别乱放
对称加密的核心在于使用相同密钥进行加密与解密。发送方和接收方必须共享同一密钥,密钥的安全性直接决定了加密数据的安全性。例如,AES算法通过密钥对明文进行多轮替换、置换等数学操作,生成无法直接识别的密文,只有持有正确密钥的接收方才能还原原始信息。
我们常用的:AES、ChaCha20,旧时代还有DES(三字母组合,别用了)。
加密算法选择:
- AES:业界标配,有块加速硬件,快,成熟。
- ChaCha20:谷歌亲儿子,快、现代、适合手机和 IoT,性能好于AES(尤其无硬件加速时)。
用 AES 来搞一搞(推荐库:PyCryptodome)
通过以下命令安装
pip install pycryptodome
示例代码:
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
key = get_random_bytes(16) # AES-128
cipher = AES.new(key, AES.MODE_EAX)
data = "花姐的钱包密码是:123456".encode("utf-8")
nonce = cipher.nonce
ciphertext, tag = cipher.encrypt_and_digest(data)
print("加密:", ciphertext)
# 解密
cipher2 = AES.new(key, AES.MODE_EAX, nonce=nonce)
plaintext = cipher2.decrypt_and_verify(ciphertext, tag)
print("解密:", plaintext.decode("utf-8"))
输出结果为:
加密: b'\xb4\x0c\xca\xac\xf1\xb5>\xaa\xf7:&}\x1c\xd6\xc5d\xed\xae\xcc\x0e[\xd9\x9dL2e\xaa\x0b\x8e}\x00\xc7\t'
解密: 花姐的钱包密码是:123456
✅ 这个代码就能跑。注意几点:
- key 要是 16、24 或 32 字节,别乱写
- nonce 要存着,解密时得用
- tag 是校验用的,防篡改
- 加密和解码时需使用相同的编码(如 UTF-8)
我强烈建议用 EAX 或 GCM 模式,它们自带“签名”功能。CBC 那种老年模式不推荐用了,除非你手动加 MAC(太麻烦,容易翻车)
密码不能直接做 key!
你不能拿 "123456"
直接当 key,那是送人破解:
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Hash import SHA256
password = "花姐最美"
salt = get_random_bytes(16)
key = PBKDF2(password, salt, dkLen=32, count=100_000, hmac_hash_module=SHA256)
记住:PBKDF2 是把“人类能记住的密码”变成“机器需要的密钥”。不然暴力破解起来分分钟搞定。
三、非对称加密:我有锁你有钥匙,别用反了
非对称加密的核心在于密钥对分离机制:使用一对数学关联但不可互推的密钥(公钥和私钥)完成加密与解密。
非对称加密的套路:
- 公钥:公开,用来加密
- 私钥:保密,用来解密
举个场景:你发我一个“花姐密信”,用我公钥加密,只有我能解密。
用Python搞非对称加密,我们一般用cryptography
这个包就挺顺的
RSA 加密/解密:
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import serialization, hashes
# 生成密钥对
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()
# 加密
message = "我爱花姐".encode("utf-8")
ciphertext = public_key.encrypt(
message,
padding.OAEP(
mgf=padding.MGF1(hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
# 解密
plaintext = private_key.decrypt(
ciphertext,
padding.OAEP(
mgf=padding.MGF1(hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
print("解密:", plaintext.decode("utf-8"))
📌 注意:非对称加密不能加密大文件!你要搞1MB上去它就喘气。
所以实际场景里会用“混合加密”: 用非对称加密传 AES 的 key,用 AES 负责加密大块数据。配合拳打才是王道。
四、签名:加密≠完整性保护
签名的作用不是保密,而是认证。
from cryptography.hazmat.primitives import hmac, hashes
key = 'super-secret'.encode('utf-8')
h = hmac.HMAC(key, hashes.SHA256())
h.update("花姐的秘籍".encode('utf-8'))
tag = h.finalize()
你传个文件、token、配置,要是没带签名,别人随便改改你都发现不了。
所以:
- AES 要配 HMAC
- JWT 要有签名(别只 base64 编个payload)
- 文件存储要加 hash 校验或签名防篡改
五、实战建议(花姐私藏技巧)
场景 | 加密方式 |
---|---|
密码存储 | 不加密!用 bcrypt、argon2(哈希 + 盐) |
数据传输 | HTTPS / TLS(别自己造协议) |
配置文件 | 加密后 base64 存,密钥别写在代码里 |
token 存库 | 用 AES + HMAC 签名 |
大文件加密 | AES-GCM,key 用 RSA 加密传输 |
推荐库:
cryptography
(官方推荐,功能全)PyCryptodome
(适合习惯 PyCrypto 的人)
六、为啥你加密了还是不安全?
你想,“我都加密了,咋还被黑?”
因为你很可能:
- 把密钥写在了代码里(config.py:SECRET_KEY = "abc123")
- nonce 每次都复用(攻击者可以分析密文)
- 用了 ECB 模式(每个块都一样,看图都能还原)
- 忘记加 tag(AES-GCM/EAX 的 tag 是必须的)
- 你压根没用 HTTPS 传数据……
加密不是写个 .encrypt()
就安全了,是你所有细节都得考虑周到。
七、最容易忽视的地方
AES.MODE_ECB
:别用,它是加密界的透明人base64
≠ 加密,别再base64.encode()
就当安心了- 明文密钥写死 = 开门送命,哪怕你觉得“本地运行没事”
- RSA 签名 vs 加密分不清?记住:签名保证来源和完整性,加密是为了保密
就写到这,记住几件事就行:
- 对称快但要藏好钥匙,非对称慢但适合传钥匙
- 加密 ≠ 安全,细节 ≠ 可忽视
- 不要自创协议,你打不过 NSA
你要是看到这儿还没晕,那说明你真的适合搞安全。欢迎来评论区分享你踩过的雷,咱一起给后人铺好地雷图。
花姐退下,记得: 你今天不管钥匙,明天钥匙管你。