Python 之 RSA 加解密和密码校验

常规的加解密方案一般是直接将通过公钥和明文加密后的密文存储到数据库中,但是如果私钥和密文泄露之后,很容易解密出原始密文。

为了确保安全性,我们可以采用一套严谨的密码处理流程,主要分为以下三步:

  1. 前端加密 (RSA):用户输入的密码在发送到服务器前,会先使用 RSA 公钥进行加密-。这可以防止密码在传输过程中被窃听。

  2. 后端解密与哈希 :服务器收到 RSA 加密的密码后,会使用私钥将其解密为明文。随后,后端会立即使用 Werkzeug 库generate_password_hash 单向哈希函数,将这个明文密码转换成一个哈希值。

  3. 数据库存储 :最后,只有这个单向哈希后的密码会被存储到数据库中。

与常规加解密的不同之处在于,用户密码数据库存储时并不直接存储加密后的密文,而是存储一个用generate_password_hash 单向哈希生成后的密码,校验时则使用check_password_hash 将数据库的密码哈希值与用户的密码进行比对校验,校验通过则说明密码正确。

当用户登录时,系统会将用户输入的密码进行同样的哈希处理,然后与数据库中存储的哈希值进行比对。由于哈希函数的单向性,即使私钥和数据库被泄露,攻击者也难以从哈希值逆推出原始密码,从而保证了用户密码的安全。

python 复制代码
import base64
import os
from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import PKCS1_OAEP
from pathlib import Path

from werkzeug.security import check_password_hash, generate_password_hash

current_dir = os.path.abspath(os.path.dirname(__file__))
private_key_path = os.path.join(current_dir, 'private.pem')
public_key_path = os.path.join(current_dir, 'public.pem')


def encrypt(line: str) -> str:
    rsa_key = RSA.importKey(Path(public_key_path).read_text(), "Welcome")
    cipher = PKCS1_OAEP.new(rsa_key)
    password_base64 = base64.b64encode(line.encode('utf-8')).decode('utf-8')
    encrypted_password = cipher.encrypt(password_base64.encode())
    return base64.b64encode(encrypted_password).decode('utf-8')


def decrypt(line: str) -> str:
    rsa_key = RSA.importKey(open(private_key_path).read(), "Welcome")
    cipher = PKCS1_OAEP.new(rsa_key)
    return cipher.decrypt(base64.b64decode(line)).decode()


if __name__ == '__main__':
    # 原始密码
    raw_password = "12345678"
    print("raw_password", raw_password)
    # 加密后用于安全传输的密文
    encrypt_password = encrypt(raw_password)
    print("encrypt_password", encrypt_password)
    # 解密后的 base64 编码的密码
    base64_decrypt_password = decrypt(encrypt_password)
    print("base64_decrypt_password", base64_decrypt_password)
    # 解密后的明文
    decrypt_password = base64.b64decode(base64_decrypt_password).decode('utf-8')
    print("decrypt_password", decrypt_password)
    # base64 密码生成的 hash
    hash_password = generate_password_hash(base64_decrypt_password)
    print("hash_password", hash_password)
    # hash 密码与 base64 密码进行校验
    check_result = check_password_hash(hash_password, base64_decrypt_password)
    print("check_password", check_result)
python 复制代码
raw_password 12345678
encrypt_password hy6nRk5p08YZiKPQwumUv09h3pHziRiUgRfO40QCZiV4UIJDZZfHii+8GEtP+IJlrc+Q0Vl/ZMs41dLbp7Efj2VWZStVzB/nbqsRUdeej+KYc6yLAr0pnexw9MvJzQjbgLBRIiHPrT8jDmrsKUtaZMyPy71BPzewaQhHN888Nuk=
base64_decrypt_password MTIzNDU2Nzg=
decrypt_password 12345678
hash_password scrypt:32768:8:1$08LI2OVO1I6YjPPs$4be22ea1b39b667ce2fa084c2c2e0f444d217688fbdb5572189395e436ea402bdeb7de4d875d0cc913e2ca81b054f4e291bdb293d4c525de821bfb8a3672a9bf
check_password True
相关推荐
要开心吖ZSH6 天前
公钥加密,私钥解密?私钥加密,公钥解密?哪个对?
密码学·aes·sha·rsa·sm2·sm3·签名验签
Ab_stupid2 个月前
CTF-Crypto培训笔记-现代密码
笔记·des·aes·rsa·crypto
张一西3 个月前
嵌入式系统中的加解密签名(3)---国密的签名与验证
签名·rsa·验签·sm2
恼书:-(空寄3 个月前
深入理解敏感信息加密:AES+RSA混合使用前后端对接
aes·数据加密·rsa
Asurplus3 个月前
【VUE】17、使用JSEncrypt对数据加解密
javascript·vue.js·jsencrypt·rsa
aovenus4 个月前
RSA 算法介绍
rsa
酿情师4 个月前
2026软件系统安全赛初赛RSA(赛后复盘)
android·网络·安全·密码学·rsa
温中志4 个月前
RSA加密算法入门
rsa·计算机密码学
Y5neKO5 个月前
某国赛CTF密码学题目Writeup:RSA
密码学·ctf·rsa