有人可以解释 BCrypt 如何验证哈希吗?

2024-03-01

我正在使用 C# 和 BCrypt.Net 来哈希我的密码。

例如:

string salt = BCrypt.Net.BCrypt.GenerateSalt(6);
var hashedPassword = BCrypt.Net.BCrypt.HashPassword("password", salt);

//This evaluates to True. How? I'm not telling it the salt anywhere, nor
//is it a member of a BCrypt instance because there IS NO BCRYPT INSTANCE.
Console.WriteLine(BCrypt.Net.BCrypt.Verify("password", hashedPassword));
Console.WriteLine(hashedPassword);

如果 BCrypt 没有在任何地方保存盐,它如何使用哈希值验证密码。我唯一的想法是它以某种方式在哈希的末尾添加了盐。

这是一个正确的假设吗?


BCrypt 哈希值string好像:

$2a$10$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm
\__/\/ \____________________/\_____________________________/
 |   |        Salt                     Hash
 |  Cost
Version

Where

  • 2a:算法标识符(BCrypt,UTF8编码密码,以null结尾)
  • 10: Cost Factor (210 = 1,024 rounds)
  • Ro0CUfOqk6cXEKf3dyaM7O:OpenBSD-Base64 编码盐(16 字节 ⇒ 22 个字符)
  • hSCvnwM9s4wIX9JeLapehKK5YdLxKcm:OpenBSD-Base64 编码散列(24 字节 ⇒ 31 个字符)

Edit: 我刚刚注意到这些词完全合适。我必须分享:

$2a$10$TwentytwocharactersaltThirtyonecharacterspasswordhash
$==$==$======================-------------------------------

BCrypt does使用 16 字节 salt 创建 24 字节二进制哈希。您可以随意存储二进制哈希值和盐;你什么也没说have将其以 base-64 编码为字符串。

But BCrypt是由从事 OpenBSD 工作的人创建的。OpenBSD已经定义了他们的密码文件的格式:

$[HashAlgorithmIdentifier]$[AlgorithmSpecificData]

这意味着“bcrypt 规范”与 OpenBSD 密码文件格式有着千丝万缕的联系。每当有人创建一个“bcrypt 哈希” they always将其转换为以下格式的 ISO-8859-1 字符串:

$2a$[Cost]$[Base64Salt][Base64Hash]

几个要点:

  • 2a是算法标识符

    • 1: MD5
    • 2:早期的 bcrypt,对密码的编码方式存在混淆(已过时)
    • 2a:当前bcrypt,指定密码为UTF-8编码
  • Cost是计算哈希值时使用的成本因素。 “当前”值为 10,表示内部密钥设置经过 1,024 轮

    • 10: 210 = 1,024 iterations
    • 11: 211 = 2,048 iterations
    • 12: 212 = 4,096 iterations
  • OpenBSD 密码文件使用的 Base64 算法与以下的 Base64 编码不同:其他人用途;他们有自己的:

      Regular Base64 Alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
          BSD Base64 Alphabet: ./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
    

    因此 bcrypt 的任何实现都不能使用任何内置或标准的 base64 库


有了这些知识,您现在可以验证密码correctbatteryhorsestapler针对保存的哈希:

$2a$12$mACnM5lzNigHMaf7O1py1O3vlf6.BA8k8x3IoJ.Tq3IB/2e7g61Km

BCrypt 变体

bcrypt 版本存在很多混乱。

$2$

BCrypt 是由 OpenBSD 人员设计的。它旨在对密码进行哈希处理以存储在 OpenBSD 密码文件中。哈希密码以前缀存储,以识别所使用的算法。 BCrypt 得到了前缀$2$.

这与其他算法前缀形成对比:

  • $1$: MD5
  • $5$:SHA-256
  • $6$:SHA-512

$2a$

最初的 BCrypt 规范没有定义如何处理非 ASCII 字符,或者如何处理空终止符。该规范经过修订,指定在对字符串进行哈希处理时:

  • 字符串必须是 UTF-8 编码
  • 必须包含空终止符

$2x$, $2y$ (2011 年 6 月)

A bug was discovered in crypt_blowfish https://en.wikipedia.org/wiki/Bcrypt#Versioning_history???? https://archive.fo/CnnUz, a PHP implementation of BCrypt. It was mis-handling characters with the 8th bit set.

They suggested that system administrators update their existing password database, replacing $2a$ with $2x$, to indicate that those hashes are bad (and need to use the old broken algorithm). They also suggested the idea of having crypt_blowfish emit $2y$ for hashes generated by the fixed algorithm. Nobody else, including canonical OpenBSD, adopted the idea of 2x/2y. This version marker was was limited to crypt_blowfish http://seclists.org/oss-sec/2011/q2/632???? https://archive.fo/tqDGj.

版本$2x$ and $2y$并不比“更好”或“更强”$2a$。它们是 BCrypt 的一种特定的有缺陷的实现的残余。

$2b$ (2014 年 2 月)

在 BCrypt 的 OpenBSD 实现中发现了一个错误。他们用不支持字符串的语言编写实现 - 因此他们用长度前缀、指向字符的指针来伪造它,然后用[]。不幸的是,他们将字符串的长度存储在一个unsigned char。如果密码长度超过 255 个字符,它将溢出并在 255 处换行。BCrypt 是为 OpenBSD 创建的。当他们遇到错误时their图书馆,他们决定可以升级版本。这意味着如果您想保持最新状态,其他人都需要效仿"their"规格。

  • ???? https://archive.fo/ZjV9P
  • ???? https://archive.fo/J7dRp

之间没有区别2a, 2x, 2y, and 2b。如果您正确编写了实现,它们都会输出相同的结果。

  • 如果您从一开始就做正确的事情(以 utf8 存储字符串并散列空终止符),那么:2, 2a, 2x, 2y, and 2b。如果您正确编写了实现,它们都会输出相同的结果。
  • 版本$2b$并不比“更好”或“更强”$2a$。它是 BCrypt 的一个特定的有缺陷的实现的残余。但由于 BCrypt 按照规范属于 OpenBSD,因此他们可以将版本标记更改为他们想要的任何内容。
  • 版本$2x$ and $2y$并不比任何事情更好,甚至更可取。它们是有缺陷的实现的残余物 - 应该立即被遗忘。

唯一需要关心 2x 和 2y 的人是那些您可能一直在使用的人地穴河豚回到2011年。唯一需要关心的人2b那些可能一直在运行 OpenBSD 的人。

所有其他正确的实现都是相同且正确的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有人可以解释 BCrypt 如何验证哈希吗? 的相关文章

  • 尚未注册类型“IServiceProviderFactory[Autofac.ContainerBuilder]”的服务

    当运行以下命令添加数据库迁移脚本时 出现以下错误 dotnet ef migrations add InitialCreate v o Migrations context MyContext 访问 Microsoft Extensions
  • 在 C/C++ 中获得正模数的最快方法

    通常在我的内部循环中 我需要以 环绕 方式索引数组 因此 例如 如果数组大小为 100 并且我的代码要求元素 2 则应该给它元素 98 高级语言 例如 Python 可以简单地使用my array index array size 但由于某
  • 我如何理解这个 C 类型声明?

    double bar int double double double double 在查看讲座幻灯片时 我发现了留给学生的练习 用简单的英语来说 什么是类型bar在这个 C 声明中 Please帮助我解决这个问题 我什至不知道从哪里开始
  • 防止 boost::asio::io_context 在空轮询调用时停止

    此代码调用发布的句柄 boost asio io context ioc boost asio post ioc std cout lt lt lol lt lt std endl ioc poll 而这并没有 boost asio io
  • 与 Qt 项目的静态链接

    我有一个在 Visual Studio 2010 Professional 中构建的 Qt 项目 但是 当我运行它 在调试或发布模式下 时 它会要求一些 Qt dll 如果我提供 dll 并将它们放入 System32 中 它就可以工作 但
  • 如何在 SqlDataReader.Read() 期间从死锁异常中恢复

    我的 NET 应用程序的事件日志显示 它在从 Sql Server 读取数据时偶尔会出现死锁 这种情况通常非常罕见 因为我们已经优化了查询以避免死锁 但有时仍然会发生 过去 我们在调用ExecuteReader函数在我们的SqlComman
  • GCC 和 ld 找不到导出的符号...但它们在那里

    我有一个 C 库和一个 C 应用程序 尝试使用从该库导出的函数和类 该库构建良好 应用程序可以编译 但无法链接 我得到的错误遵循以下形式 app source file cpp text 0x2fdb 对 lib namespace Get
  • 找不到 assimp-vc140-mt.dll ASSIMP

    我已经从以下位置下载了 Assimp 项目http assimp sourceforge net main downloads html http assimp sourceforge net main downloads html Ass
  • 时间:2019-03-17 标签:c#ThreadSafeDeepCopy

    我一直在阅读很多其他问题以及大量谷歌搜索 但我一直无法找到明确的解决方案 根据我读过的一些最佳实践 类的静态方法应该创建线程安全的 并且实例成员应该将线程安全留给消费者 我想为该类实现深度复制方法 该类本身还有其他引用类型成员 有没有什么方
  • Visual Studio Code:如何配置 includePath 以获得更好的 IntelliSense 结果

    我是使用 Visual Studio Code 的完全初学者 我不知道我在做什么 我已经四处搜索 也许还不够 但我找不到像我这样的人如何配置的简单解释c cpp properties json每当我单击带有绿色波浪线下划线的行旁边的黄色灯泡
  • C++ php 和静态库

    我创建了一个library a 其中包含 cpp 和 h 文件 其中包含很多类 嵌套类和方法 我想在 php 示例中包含这个静态库并尝试使用它 我想提一下 我是 php 新手 我已经在 test cpp 文件中测试了我的 libray a
  • 给出 5 个参数,但在终端中只得到 3 个参数

    我想将一个文件传递给一个c 程序 如果我在 IDE 中执行此操作 test string string lt test txt return argc 5 但在终端上我刚刚得到argc 3 看来 这是因为 什么是 lt 意思是 我正在使用
  • AES 输出是否小于输入?

    我想加密一个字符串并将其嵌入到 URL 中 因此我想确保加密的输出不大于输入 AES 是可行的方法吗 不可能创建任何始终会创建比输入更小的输出的算法 但可以将任何输出反转回输入 如果您允许 不大于输入 那么基本上您只是在谈论同构算法alwa
  • 将标量添加到特征矩阵(向量)

    我刚刚开始使用 Eigen 库 无法理解如何向所有矩阵成员添加标量值 假设我有一个矩阵 Eigen Matrix3Xf mtx Eigen Matrix3Xf Ones 3 4 mtx mtx 1 main cxx 104 13 error
  • 是否有相当于 Clang/LLVM 的 .spec 文件,在哪里可以找到参考?

    The gcc驱动程序可以配置为使用特定的链接器 特定的选项和其他细节 例如覆盖系统头 specs files 当前 截至撰写本文时 GCC 版本 4 9 0 的手册此处描述了规范文件 https gcc gnu org onlinedoc
  • IEnumerable.Except 不起作用,那么我该怎么办?

    我有一个 linq to sql 数据库 非常简单 我们有 3 个表 项目和用户 有一个名为 User Projects 的连接表将它们连接在一起 我已经有了一个获得的工作方法IEnumberable
  • 使用restsharp序列化对象并将其传递给WebApi而不是序列化列表

    我有一个看起来像的视图模型 public class StoreItemViewModel public Guid ItemId get set public List
  • 矩阵到数组 C#

    这将是转换方阵的最有效方法 例如 1 2 3 4 5 6 7 8 9 into 1 2 3 4 5 6 7 8 9 in c 我在做 int array2D new int 1 2 3 4 5 6 7 8 9 int array1D new
  • 从 JavaScript 中的 OnClientClick 事件中阻止 C# 中的 asp:Button OnClick 事件?

    我有一个asp Button在我的网页上 它调用 JavaScript 函数和代码隐藏方法 后者进行调用以导航到另一个页面 在 JavaScript 函数中 我正在检查条件 如果不满足这个条件 我想中止导航 以便OnClick方法未被调用
  • Java 和/C++ 在多线程方面的差异

    我读过一些提示 多线程实现很大程度上取决于您正在使用的目标操作系统 操作系统最终提供了多线程能力 比如Linux有POSIX标准实现 而windows32有另一种方式 但我想知道编程语言水平的主要不同 C似乎为同步提供了更多选择 例如互斥锁

随机推荐

  • Hibernate:为什么使用或不使用类似天气的字段绑定显式@JoinColum注释?

    Is JoinColum当我们使用任何关联类型注释时隐式指定 例如 OneToOne OneToMany etc 这是摘自Student实体与Laptop实体 情况1 不使用显式 JoinColum OneToMany cascade Ca
  • boost::thread::id 的 tr1::hash 吗?

    我开始使用unordered set类来自tr1命名空间以加速对普通 基于树 STL 的访问map 但是 我想在 boost 中存储对线程 ID 的引用 boost thread id 并意识到这些标识符的 API 非常不透明 以至于您无法
  • 如何锁定和解锁 SQL SERVER 表?

    冒着过度解释我的问题的风险 我会错误地提供太多信息 我正在创建一个批量上传过程 将数据插入两个表中 这两个表大致如下所示 TableA是一个自引用表 允许 N 级引用 Parts self referencing table PartId
  • 语法错误,意外的 T_ENCAPSED_AND_WHITESPACE,期望 T_STRING 或 T_VARIABLE 或 T_NUM_STRING [重复]

    这个问题在这里已经有答案了 我已经盯着这个代码几个小时了 我不知道我的错误在哪里 我知道这种语法错误通常是由于缺少或不合适的大括号或单 双引号的一些问题而出现的 而且我不确定我的代码中是否存在这样的错误 我现在只是想修复我的语法 以便我可以
  • 模板部分专业化 - 有现实世界的例子吗?

    我正在思考partial specialization 虽然我理解这个想法 但我还没有看到这种技术在现实世界中的任何用法 Full specialization被用在很多地方STL所以我对此没有问题 你能告诉我一个现实世界的例子吗 part
  • 在 Mercurial 中进行合并时忽略空格

    在 Mercurial 中进行合并时 我们遇到了一个问题 其中空白更改会导致合并冲突 从而掩盖了我们可能遇到的任何 真实 冲突 并使合并成为一场噩梦 我们最近遵循了一种格式样式 该样式更改了某些分支中文件的缩进 并且从那时起合并几乎变得不可
  • 如何在Java字符类中表示空字符

    我想在 Java 中将空字符表示为 在字符串中 像那样char ch an empty character 其实我想替换一个字符而不留空格 我认为理解这意味着什么就足够了 没有字符 甚至没有空间 您可以分配 u0000 或 0 为此 请使用
  • 使用对话框框架的 primefaces 对话框未弹出

    我正在尝试使用 primefaces 对话框框架来简化我的代码 我已经按照 primefaces 4 0 用户指南中的示例进行操作 但它不起作用 我几乎逐字复制了该示例 创建了三个文件 一个包含对话框的文件 一个调用对话框的文件和一个支持
  • 在 R 中的命名空间中导入有什么好处?

    R 的命名空间机制允许人们export然后对用户可见的功能 此外 它还允许import来自其他包的函数 虽然出口的好处是显而易见的 但我在理解进口的好处时遇到了更多问题 一个好处似乎是 可以使用其他包中的功能 而无需附加包 从而节省内存 这
  • Objective-C/iOS:在后台保持蓝牙连接处于活动状态

    我已经研究了几天了 看起来当手机进入睡眠状态或应用程序在后台时 不可能保持蓝牙连接 然而 我发现一个应用程序声称它们可以一直运行 运行守护者应用程序 http itunes apple com ca app runkeeper id3002
  • jsPDF with Cordova - 添加图像

    我正在尝试使用 jsPDF 库生成 PDF https github com MrRio jsPDF https github com MrRio jsPDF 从移动 Cordova 应用程序中 我目前正在 Android 4 0 4 设备
  • Java反射带参数的私有方法最好的方法是什么?

    我正在尝试使用java反射调用私有方法我开发了一个小方法来调用其他方法迭代所有方法并按名称和参数类型进行比较我已成功调用4个方法 我有一个问题 1 这是最好的方法吗 因为我知道 class getMethod 仅匹配公共方法 Java有内置
  • 停止 ReSharper 添加注释

    我在我的 C 项目中使用 ReSharper 总的来说我很喜欢它 但是 当我执行某些重构操作时 它会不断向代码添加注释 例如 它添加了 NotNull 当我使用 检查参数是否为空 上下文操作时 Before context action p
  • SQL 连接:选择一对多关系中的最后一条记录

    假设我有一张客户表和一张采购表 每次购买都属于一位客户 我想获得所有客户的列表以及他们最后一次购买的商品SELECT陈述 最佳实践是什么 关于建立索引有什么建议吗 请在您的答案中使用这些表 列名称 顾客 id name 购买 id cust
  • Apache Camel 路由中的 Spring Boot 属性使用

    是否可以在 Apache Camel 路由中使用 Spring Boot 属性 Value 工作正常 但这是否可以直接放置表达式的占位符 Update 我知道 PropertiesComponent 但这将是除了我不喜欢的 Applicat
  • 根据时间/时间表交换 div 可见性

    在我的页面上 我有两个 div 一个 div 我希望从上午 10 点到下午 6 点 服务器时间 可见 而另一个 div 在剩余时间内可见 我尝试了一系列搜索来找到某种 javascript 或 jquery 内容交换器 但没有任何运气 感谢
  • 无法终止容器::尝试终止容器,但未收到退出事件

    我无法停止 删除或终止我的 docker 容器 下面给出的命令及其各自的错误消息 1 docker stop
  • 创建存储过程时是否需要“definer”?

    我已经将所有 MySQL 过程编写为root localhost CREATE DEFINER root localhost PROCEDURE p add user 问题是 当部署到另一台服务器时 我必须替换root与当前用户并替换loc
  • 奇怪的程序集名称从手机访问网站时出错

    我有一个用 Asp net MVC 制作的网站 它安装在共享托管环境的根目录中 现在 我已经在 Asp net MVC 中为该网站制作了一个移动版本 并将其安装为子域http m price tag org http m price tag
  • 有人可以解释 BCrypt 如何验证哈希吗?

    我正在使用 C 和 BCrypt Net 来哈希我的密码 例如 string salt BCrypt Net BCrypt GenerateSalt 6 var hashedPassword BCrypt Net BCrypt HashPa