Bcrypt 哈希模块



将一个字符串转换为另一个字符串的过程称为哈希函数。哈希函数有很多形式,但它们都有一个共同点,那就是它们是不可逆的。这意味着转换应该是单向的,哈希长度应该设置好,并且输入字符串应该完全匹配哈希,以便以后可以进行比较。此属性使其非常适合密码和身份验证。

在本章中,我们将学习如何使用 bcrypt 模块对密码进行哈希处理。密码不应以明文形式存储,因为它们容易受到多种攻击。因此,有必要对其进行哈希处理。

Hashing Technique

Bcrypt 模块

Bcrypt 是一种安全地对密码进行哈希处理的方法。它由 Niels Provos 和 David Mazieres 于 1999 年创建。它基于 Blowfish 密码。Bcrypt 向密码添加“盐”以保护它们免受攻击。它也是自适应的,这意味着它可以随着时间的推移而减慢速度以防止暴力破解攻击,即使计算机速度加快也是如此。

它是 OpenBSD 的默认密码哈希,也是包括 SUSE Linux 在内的各种 Linux 发行版的默认密码哈希。

编程语言

Bcrypt 在多种编程语言中实现,包括 C、C++、C#、Delphi、Elixir、Go、Java、Python、JavaScript、Perl、PHP、Ruby 等。

函数描述

bcrypt 函数需要三个输入:一个 16 字节(128 位)的盐值、一个数字成本和密码字符串(最多 72 字节)。通常,盐具有随机值。Bcrypt 使用这些输入生成一个 24 字节(192 位)的哈希值。bcrypt 函数的结果是以下格式的字符串

$2$[cost]$[22 字符盐][31 字符哈希]

例如,如果输入密码为“abc123xyz”,成本为 12,并且使用随机盐,则 bcrypt 的输出将如下所示:

$2a$12$R9h/cIPz0gi.URNNX3kh2OPST9/PgBkqquzi.Ss7KIUgO2t0jWMUW

分析它 -

  • $2a$ - 表示 bcrypt 是哈希算法。
  • 12 - 表示输入成本(2^12 轮,即 4096 次迭代)。
  • R9h/cIPz0gi.URNNX3kh2O - 以 Base-64 编码的输入盐。
  • PST9/PgBkqquzi.Ss7KIUgO2t0jWMUW - 生成的 24 字节哈希的前 23 字节的 Base-64 编码。

注意 - RFC 4648 Base64 标准编码与 bcrypt 中使用的 base-64 编码不同。"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789," 是使用的表。

使用 Python 的 Bcrypt

我们需要使用以下命令安装 Bcrypt -

pip install bcrypt

使用的 Bcrypt 函数为 -

  • bcrypt.gensalt() - 此函数用于生成盐。一个称为“盐”的伪随机字符串附加到密码。如果有人可以访问数据库,则哈希可能会被破坏,因为它会为相同的输入始终产生相同的结果。因此,在哈希之前,盐会附加到密码的末尾。它返回一个伪随机字符串,并且不需要任何参数。
  • bcrypt.hashpw() - 使用函数 bcrypt.hashpw() 创建最终保存在数据库中的哈希值。
  • 参数 - 我们可以以密码和盐的形式传递字节码。
  • 返回值 - 如果哈希过程成功,则返回一个哈希字符串。

对给定密码进行哈希处理

要在 Python 中使用 bcrypt 对密码进行哈希处理,首先导入 bcrypt 模块。然后,使用 bcrypt.hashpw() 函数,该函数接受两个参数:密码字符串(以字节为单位)和盐(哈希函数中使用的随机数据)。这是一个例子。

import bcrypt

# Password to hash
password = b"my_password"

# Generate a random salt
salt = bcrypt.gensalt()

# Hash the password with the salt
hashed_password = bcrypt.hashpw(password, salt)

# Print the hashed password
print("Hashed password:", hashed_password)

在此示例中,将“my_password”替换为您要哈希的密码。bcrypt.gensalt() 函数生成一个随机盐,然后 bcrypt.hashpw() 使用该盐对密码进行哈希处理。

输出

Hashed password: b'$2b$12$TFKa30kHN1JwE9DrAUlI9e2xeiNdXxFcWBfEeEysx5l2j1yhJ87Lu'

检查密码

使用 Python 中的 bcrypt 检查用户输入的密码是否与哈希密码匹配。因此,我们可以使用 bcrypt.checkpw() 函数。此函数接受两个参数:用户输入的密码和哈希密码。这是一个例子 -

import bcrypt

# Hashed password stored in the database
hashed_password = b'$2a$12$R9h/cIPz0gi.URNNX3kh2OPST9/PgBkqquzi.Ss7KIUgO2t0jWMUW'

# User-entered password
user_password = b"wrong_password"

# Check if the user-entered password matches the hashed password
if bcrypt.checkpw(user_password, hashed_password):
   print("Password is correct!")
else:
   print("Password is incorrect.")

如果用户输入的密码与哈希密码匹配,则 bcrypt.checkpw() 函数将返回 True,否则返回 False。

Password is incorrect.

Bcrypt npm 包

JavaScript 中的 bcrypt npm 包用于安全地对密码进行哈希处理。与可以反转以获取原始密码的加密不同,哈希是不可逆的单向函数。

当用户输入密码时,您的 JavaScript 应用程序对其进行哈希处理并将哈希值保存到数据库中。稍后,在身份验证期间,您将输入的密码与存储的哈希值进行比较以查看它们是否匹配。

bcrypt 库通过提供安全的方法来对密码进行哈希处理和比较,从而简化了此过程。

要使用该库,您必须首先使用您的包管理器安装它 -

npm install bcrypt
# or
yarn add bcrypt

然后,使用 require 将模块添加到您的 JavaScript 代码中 -

const bcrypt = require("bcrypt");

创建密码

要使用 bycrypt 模块生成密码,请调用 hash() 方法,该方法接受密码字符串、轮数和回调函数。

const bcrypt = require('bcrypt');

// Hash a password
const password = 'itsmypassword';
bcrypt.hash(password, 10, function(err, hash) {
   if (err) throw err;
   // Store hash in your password DB.
   console.log('Hashed password:', hash);
});

// Check if a password matches the hash
const inputPassword = 'itsmypassword';
const hashedPassword = '$2b$10$r1X5kL93Q8Vtqfbcxhkd8Od6iGgHsqQ6yMv48ZyB9N3hZLxrFhfmS';

bcrypt.compare(inputPassword, hashedPassword, function(err, result) {
   if (err) throw err;
   if (result) {
      console.log('Password matches!');
   } else {
      console.log('Password does not match.');
   }
});

将提供的代码保存在一个文件中,例如 bcrypt_example.js。使用 Node.js 运行脚本 -

node bcrypt_example.js
Password does not match.
Hashed password: $2b$10$IE83WAENrak/7n88FmKgD.Z2EFMy.uJRf8nqJG2h/FqMD7/6tb2n.

总结

密码需要使用 bcrypt 进行哈希以增强安全性。它可以防止密码以明文形式保存,并增强抵御多种攻击的保护能力。Python 和 Node.js 都包含 bcrypt 模块,用于创建安全的密码哈希。

广告