Python 如何实现 SHA 加密?SHA1 / SHA256 / SHA512 实战教程

前言

开发中经常遇到加密需求:接口签名、密码摘要、文件校验、数据防篡改等场景,SHA 系列哈希算法使用极其广泛。

很多新手容易混淆几个常见误区:

  1. SHA 不是加密,是哈希摘要算法,不可逆,无法解密;
  2. 直接对中文字符串加密经常出现报错;
  3. 分不清 SHA1、SHA256、SHA512 使用场景;
  4. 不知道加盐哈希该如何实现。

本文基于 Python 内置 hashlib 库,无需额外安装第三方包,完整演示各类 SHA 哈希实现,附带常见踩坑解决方案。

环境说明:Python3.6+ 原生支持,Windows / Linux / Mac 通用。

一、基础概念区分

  1. SHA(Secure Hash Algorithm)安全哈希算法
    • SHA1:输出160位(40位十六进制字符串),安全性较弱,新项目不推荐;
    • SHA256:输出256位(64位十六进制),目前业务最常用;
    • SHA512:输出512位(128位十六进制),安全性更高;
  2. 重要特性
    • 单向不可逆:只能生成摘要,不能反向还原原始内容;
    • 雪崩效应:原始内容微小改动,摘要完全不同;
    • 相同输入一定得到相同摘要;
  3. 注意:哈希 ≠ 加密。加密可以解密,哈希无法解密。

二、基础环境:内置 hashlib

不需要 pip install,Python 自带:

python 复制代码
import hashlib

三、最简单示例:字符串 SHA256 摘要

⚠️ 关键点:hashlib 只支持 bytes 字节流,字符串必须先 .encode(),推荐编码 utf-8

python 复制代码
import hashlib

def get_sha256(text: str) -> str:
    # 1. 字符串转字节
    data = text.encode("utf-8")
    # 2. 创建sha256对象
    sha_obj = hashlib.sha256(data)
    # 3. 获取十六进制摘要
    result = sha_obj.hexdigest()
    return result


if __name__ == "__main__":
    content = "hello world"
    res = get_sha256(content)
    print("SHA256摘要:", res)

输出结果:

复制代码
SHA256摘要: b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9

四、SHA1、SHA512 通用写法

只需要更换 hashlib.sha1()hashlib.sha512()

python 复制代码
import hashlib

text = "测试文本123"
data = text.encode("utf-8")

sha1_res = hashlib.sha1(data).hexdigest()
sha256_res = hashlib.sha256(data).hexdigest()
sha512_res = hashlib.sha512(data).hexdigest()

print("SHA1:", sha1_res)
print("SHA256:", sha256_res)
print("SHA512:", sha512_res)

五、进阶:分段大文件 SHA 哈希(适合校验文件完整性)

如果文件很大,一次性读取全部内容占用内存,采用分段更新 update()

python 复制代码
import hashlib

def get_file_sha256(file_path: str, chunk_size=4096) -> str:
    sha_obj = hashlib.sha256()
    with open(file_path, "rb") as f:
        while chunk := f.read(chunk_size):
            sha_obj.update(chunk)
    return sha_obj.hexdigest()

# 使用
# print(get_file_sha256("test.zip"))

六、业务常用:加盐 SHA 摘要

直接 SHA 存在彩虹表碰撞风险,存储密码、接口签名建议加盐

两种主流方式:

python 复制代码
import hashlib

def get_sha256_salt(text: str, salt: str = "my_secret_2026") -> str:
    # 方式1:原始内容 + 盐拼接
    raw = text + salt
    return hashlib.sha256(raw.encode("utf-8")).hexdigest()

# 推荐:盐放在前后都可以,前后位置保持和服务端一致即可
print(get_sha256_salt("123456"))

重要提醒:加盐规则前后端必须完全统一,拼接顺序、编码不一致会导致摘要不匹配。

七、digest() 与 hexdigest() 区别

很多新手分不清这两个方法:

  1. .hexdigest():返回十六进制字符串,日常接口、日志打印首选;
  2. .digest():返回原始二进制字节串,一般极少直接使用。
python 复制代码
data = "demo".encode("utf-8")
print(hashlib.sha256(data).hexdigest())  # 字符串
print(hashlib.sha256(data).digest())     # bytes

八、高频踩坑清单

坑1:中文不编码直接加密,抛异常

python 复制代码
# 错误写法
# hashlib.sha256("中文")
# TypeError: Unicode-objects must be encoded before hashing

# 正确:必须encode
hashlib.sha256("中文".encode("utf-8"))

坑2:编码不一致导致摘要不同

同一文本,一方 utf-8,一方 gbk,算出的 sha256 完全不一样。

项目统一约定:全部使用 utf-8

坑3:SHA1 安全性不足

SHA1 已被证明存在碰撞漏洞,新项目禁止使用 SHA1 做签名、密码存储,优先 SHA256。

坑4:哈希用来存储密码不推荐

单纯 SHA256+简单盐依然不安全。用户密码存储推荐使用 bcrypt / passlib,内置多次迭代加盐。SHA 更适合接口签名、文件校验场景。

坑5:空格、换行、不可见字符引发摘要不一致

网络传输时,注意去除首尾多余空格,保证参与哈希的原始文本完全一致。

九、封装通用工具类(可直接放入项目)

python 复制代码
import hashlib

class HashUtil:
    @staticmethod
    def sha1(text: str, encoding="utf-8") -> str:
        return hashlib.sha1(text.encode(encoding)).hexdigest()

    @staticmethod
    def sha256(text: str, encoding="utf-8") -> str:
        return hashlib.sha256(text.encode(encoding)).hexdigest()

    @staticmethod
    def sha512(text: str, encoding="utf-8") -> str:
        return hashlib.sha512(text.encode(encoding)).hexdigest()

    @staticmethod
    def sha256_salt(text: str, salt: str, encoding="utf-8") -> str:
        content = text + salt
        return hashlib.sha256(content.encode(encoding)).hexdigest()


if __name__ == "__main__":
    print(HashUtil.sha256("hello python"))

十、常见业务场景选型建议

  1. 接口请求签名:SHA256 + 自定义盐(前后端约定拼接规则)
  2. 文件完整性校验:SHA256 / SHA512
  3. 日志数据摘要标识:SHA256
  4. 旧系统兼容:SHA1(新项目尽量规避)

总结

  1. Python 使用内置 hashlib 实现 SHA 系列哈希,无需第三方库;
  2. 字符串必须 encode 转为字节,统一使用 utf-8;
  3. hexdigest() 获取可读十六进制字符串,开发最常用;
  4. SHA 是单向哈希算法,不可逆,不要当作加密算法;
  5. 对外接口签名务必加盐,增加破解难度;
  6. 新项目优先 SHA256,淘汰 SHA1。
相关推荐
码云骑士1 小时前
106-模型量化技术-GGUF-GPTQ-AWQ-bitsandbytes对比
python
御风之翼_唤星者1 小时前
LoadFramePackModel模块报错bad escape
python·ai
有点。1 小时前
C++二叉树(一)
开发语言·数据结构·c++
民乐团扒谱机1 小时前
【微实验】谐波乘积谱(HPS)算法深度解析:原理、数学与代码实现
开发语言·人工智能·python·算法·语音识别·音乐
报错小能手2 小时前
Go 语言结构 基础语法
开发语言·后端·golang
Lazionr2 小时前
stack与queue:底层实现与容器适配器
开发语言·数据结构·c++
剩下了什么2 小时前
go语言 Ctx:「错误三:在 Context 中存储可变值」
开发语言·后端·golang
小白勇闯网安圈2 小时前
Django Ajax、批量操作与分页实践
python·django
Hello_Damon_Nikola2 小时前
CH573从入门到精通
c语言·开发语言·单片机·嵌入式硬件