使用 Python 对密码进行加盐和哈希处理

2025-03-11 08:54:00
admin
原创
65
摘要:问题描述:此代码旨在使用盐对密码进行哈希处理。盐和哈希密码均保存在数据库中。但密码本身则不保存。鉴于该操作的敏感性,我想确保一切都能正常执行。import hashlib import base64 import uuid password = 'test_password' salt = base64.u...

问题描述:

此代码旨在使用盐对密码进行哈希处理。盐和哈希密码均保存在数据库中。但密码本身则不保存。

鉴于该操作的敏感性,我想确保一切都能正常执行。

import hashlib
import base64
import uuid

password = 'test_password'
salt = base64.urlsafe_b64encode(uuid.uuid4().bytes)


t_sha = hashlib.sha512()
t_sha.update(password + salt)
hashed_password = base64.urlsafe_b64encode(t_sha.digest())

解决方案 1:

根据对该问题的其他答案,我使用 bcrypt 实现了一种新方法。

为什么使用 bcrypt

bcrypt如果我理解正确的话,要使用的参数SHA512bcrypt设计为缓慢的。bcrypt还可以选择调整第一次生成散列密码时所需的速度:

# The '12' is the number that dictates the 'slowness'
bcrypt.hashpw(password, bcrypt.gensalt( 12 ))

缓慢是可取的,因为如果恶意方获得了包含散列密码的表,则暴力破解它们会变得更加困难。

执行

def get_hashed_password(plain_text_password):
    # Hash a password for the first time
    #   (Using bcrypt, the salt is saved into the hash itself)
    return bcrypt.hashpw(plain_text_password, bcrypt.gensalt())

def check_password(plain_text_password, hashed_password):
    # Check hashed password. Using bcrypt, the salt is saved into the hash itself
    return bcrypt.checkpw(plain_text_password, hashed_password)

笔记

我能够使用以下命令在 Linux 系统中轻松安装该库:

pip install py-bcrypt

但是,我在 Windows 系统上安装它时遇到了更多麻烦。它似乎需要补丁。请参阅此 Stack Overflow 问题:在 Win7 64 位 Python 上安装 py-bcrypt

解决方案 2:

编辑:这个答案是错误的。SHA512 的单次迭代速度很快,因此不适合用作密码哈希函数。请使用此处的其他答案之一。


我觉得没问题。但是,我很确定你实际上不需要 base64。你可以这样做:

import hashlib, uuid
salt = uuid.uuid4().hex
hashed_password = hashlib.sha512(password + salt).hexdigest()

如果不造成困难,您可以通过将盐和散列密码存储为原始字节而不是十六进制字符串来在数据库中获得稍微更高效的存储。为此,请将 替换hexbytes并将hexdigest替换为digest

解决方案 3:

编辑:

这个答案中建议的库现在已经过时了,并且这个答案中提到的hashlib 密钥派生功能:https://stackoverflow.com/a/56915300/893857是现在使用的好建议。

原始答案
明智的做法是不要自己编写加密,而是使用类似 passlib 的东西:https://passlib.readthedocs.io/en/stable/#

以安全的方式编写加密代码很容易搞砸。糟糕的是,使用非加密代码时,由于程序崩溃,您通常会立即注意到它无法正常工作。而使用加密代码时,您通常只能在为时已晚并且数据已被泄露后才发现。因此,我认为最好使用由熟悉该主题且基于经过实战测试的协议的其他人编写的软件包。

此外,passlib 还具有一些很好的特性,使其易于使用,并且如果旧协议被破坏,也易于升级到较新的密码哈希协议。

此外,仅进行一轮 sha512 更容易受到字典攻击。sha512 的设计目标是快速,而这在尝试安全存储密码时实际上是一件坏事。其他人已经对所有这类问题进行了长期而深入的思考,因此您最好利用这一点。

解决方案 4:

从 Python 3.4 开始,hashlib标准库中的模块包含“为安全密码散列而设计的”密钥派生函数。

因此,使用其中之一,例如hashlib.pbkdf2_hmac,使用以下方法生成的盐os.urandom

from typing import Tuple
import os
import hashlib
import hmac

def hash_new_password(password: str) -> Tuple[bytes, bytes]:
    """
    Hash the provided password with a randomly-generated salt and return the
    salt and hash to store in the database.
    """
    salt = os.urandom(16)
    pw_hash = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, 100000)
    return salt, pw_hash

def is_correct_password(salt: bytes, pw_hash: bytes, password: str) -> bool:
    """
    Given a previously-stored salt and hash, and a password provided by a user
    trying to log in, check whether the password is correct.
    """
    return hmac.compare_digest(
        pw_hash,
        hashlib.pbkdf2_hmac('sha256', password.encode(), salt, 100000)
    )

# Example usage:
salt, pw_hash = hash_new_password('correct horse battery staple')
assert is_correct_password(salt, pw_hash, 'correct horse battery staple')
assert not is_correct_password(salt, pw_hash, 'Tr0ub4dor&3')
assert not is_correct_password(salt, pw_hash, 'rosebud')

注意:

  • 使用 16 字节盐和 100000 次 PBKDF2 迭代符合 Python 文档中推荐的最小数量。进一步增加迭代次数将使您的哈希计算速度变慢,因此更安全。

  • os.urandom始终使用加密安全的随机源

  • hmac.compare_digest中使用的is_correct_password基本上只是==字符串运算符,但没有短路功能,这使得它不受时序攻击的影响。这可能并没有真正提供任何额外的安全价值,但也没有坏处,所以我继续使用它。

有关构成良好密码哈希的理论以及适合对密码进行哈希处理的其他函数列表,请参阅https://security.stackexchange.com/q/211/29805

解决方案 5:

为了使其在 Python 3 中正常工作,您需要进行 UTF-8 编码,例如:

hashed_password = hashlib.sha512(password.encode('utf-8') + salt.encode('utf-8')).hexdigest()

否则你会得到:

回溯(最近一次调用最后一次):

文件“”,第 1 行,在

hashed_pa​​ssword = hashlib.sha512(password + salt).hexdigest()

TypeError:Unicode 对象必须在散列之前进行编码

解决方案 6:

如果您需要使用现有系统存储的哈希值,passlib 似乎很有用。如果您可以控制格式,请使用 bcrypt 或 scrypt 等现代哈希值。目前,bcrypt 似乎更容易从 python 使用。

passlib 支持 bcrypt,建议安装 py-bcrypt 作为后端:http://pythonhosted.org/passlib/lib/passlib.hash.bcrypt.html

如果不想安装 passlib,也可以直接使用py-bcrypt 。自述文件中有基本使用的示例。

另请参阅:如何在 Python 中使用 scrypt 生成密码和盐的哈希值

解决方案 7:

我不想重新讨论旧话题,但是……任何想要使用现代最新安全解决方案的人都可以使用 argon2。

https://pypi.python.org/pypi/argon2_cffi

它赢得了密码哈希计算竞赛。(https://password-hashing.net/)它比 bcrypt 更易于使用,并且比 bcrypt 更安全。

解决方案 8:

import bcrypt

password = "You know my name"
salt = bcrypt.gensalt(2)
hashed = bcrypt.hashpw(password, salt)

hashed2 = bcrypt.hashpw("password1", hashed)

if hashed2 == hashed:
    print("It matches")
else:
    print("It does not match")

参考:https://github.com/erlichmen/py-bcrypt/blob/master/simple_test.py

pip install py-bcrypt

解决方案 9:

我以前在 NodeJs 中做过同样的事情:

 echo "console.log(require('crypto').createHmac('sha256', 'salt').update('password').digest('hex'))" | node

它在 Python 中的等效版本是:

python3 -c 'import hashlib;import base64;import hmac;print(hmac.new(b"salt", "password".encode(), hashlib.sha256).hexdigest())'

等效的 shell 命令是:

echo -n "password" | openssl sha256 -hmac "salt"

解决方案 10:

我个人会使用“swiftcrypt”模块。

pip install swiftcrypt

出于安全相关的原因,它具有许多功能。

import swiftCrypt

password= "coolPassword here"

salt = swiftCrypt.Salts().generate_salt(14)
hashedPass = swiftCrypt.Hash().hash_password(password,salt,"sha256")

print(hashedPass)

您可以生成具有自定义长度的盐,如果您想要随机长度,只需将其留空。

它将使用盐和您选择的算法创建一个散列密码。

然后您可以像这样验证密码:

verifiedPass = swiftCrypt.Checker().verify_password(password, hashedPass, salt,"sha256")
if verifiedPass == True:
    print("Password is correct!")
else:
    print("Password is incorrect!")                             

verify_password方法采用用户输入的密码、存储的散列密码、用于创建密码的盐以及使用的算法。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2787  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1710  
  产品配置管理在企业产品研发与生产过程中扮演着至关重要的角色,它能够确保产品在不同阶段的一致性、可追溯性以及高效的变更管理。PLM(产品生命周期管理)系统作为整合产品全生命周期信息的平台,为产品配置管理提供了强大的支持。随着技术的不断发展,到2025年,PLM系统在支持产品配置管理方面将有一系列值得关注的技术实践。基于人...
plm系统主要干什么的   11  
  敏捷迭代周期与 PLM 流程的适配是现代企业在产品开发过程中面临的重要课题。随着市场竞争的加剧和技术的快速发展,企业需要更加高效、灵活的产品开发模式,以满足客户不断变化的需求。敏捷迭代周期强调快速响应变化、持续交付价值,而 PLM 流程则侧重于产品全生命周期的管理和控制。如何将两者有机结合,优化交付节奏,成为提升企业竞...
plm是什么意思   10  
  在企业的数字化转型进程中,PLM(产品生命周期管理)与ERP(企业资源计划)作为两款重要的企业级系统,发挥着关键作用。然而,很多企业人员对它们之间的区别以及协同逻辑并不十分清晰。深入了解这两者的差异与协同方式,有助于企业更好地规划信息化建设,提升整体运营效率。PLM系统概述PLM系统聚焦于产品从概念设计到退役的全生命周...
国产plm软件   12  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用