本文

官方文档: https://pkg.go.dev/golang.org/x/crypto/bcrypt

前言

之前讲过JWT Token https://www.cnblogs.com/zichliang/p/17303759.html JWT呢是信息是经过数字签名的,因此可以被验证和信任。

然后今天就来说说密码学,我们在做鉴权 做用户处理时 会把密码存储到数据库中,但是这个密码我们肯定不能明文去存储,如果这个数据库链接一旦被别人拿到

那后果是不堪设想的。不仅仅是为了防止系统管理员或者DBA等公司人员获得用户的密码,也是防止被黑客拖库产生更大的信息泄露。

如果黑客通过不法手段获取了服务的数据库存储信息,盗取里面的内容,从而直接获得明文密码,那么影响就会很大。

所以我们的密码一般通过几种方式去加密存储

  1. MD5

    其实个人觉得MD5加密不太好,因为MD5是不加盐的,虽然是不可逆的,但是黑客其实会针对常见的一些密码,生成彩虹表。

    彩虹表是什么呢?

    是用于加密散列函数逆运算的预先计算好的表,常用于破解加密过的密码散列(维基百科)

    所以相对的感觉安全等级不是很够。

  2. SHA1及其他

    SHA-1基于MD5,MD5又基于MD4

    SHA-1是由美国标准技术局(NIST)颁布的国家标准,是一种应用最为广泛的Hash函数算法,也是目前最先进的加密技术,被政府部门和私营业主用来处理敏感的信息。

    这个缺点个人认为和 MD5一样。

  3. hmacsha

    我之前也写过相应的文章[https://www.cnblogs.com/zichliang/p/16653303.html] 里面有相应的hmasha加密

    HMAC是密钥相关的哈希运算消息认证码(Hash-basedMessageAuthenticationCode),HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。

    HMAC是需要一个密钥的。所以,HMACSHA1也是需要一个密钥的,而SHA1不需要。

  4. CRC

    CRC的全称为CyclicRedundancyCheck,中文名称为循环冗余校验。它是一类重要的线性分组码,编码和解码方法简单,检错和纠错能力强,在通信领域广泛地用于实现差错控制。实际上,除数据通信外,CRC在其它很多领域也是大有用武之地的。例如我们读软盘上的文件,以及解压一个ZIP文件时,偶尔会碰到“BadCRC”错误,由此它在数据存储方面的应用可略见一斑。

  5. 还有很多加密方式这里就不一 一赘述了...

本文介绍一种加密方式 bcrypt

概述

bcrypt是一个由美国计算机科学家尼尔斯·普罗沃斯(Niels Provos)以及大卫·马齐耶(David Mazières)根据Blowfish加密算法所设计的密码散列函数,于1999年在USENIX中展示[1]。实现中bcrypt会使用一个加盐的流程以防御彩虹表攻击,同时bcrypt还是适应性函数,它可以借由增加迭代之次数来抵御日益增进的电脑运算能力透过暴力法破解。

由bcrypt加密的文件可在所有支持的操作系统和处理器上进行转移。它的口令必须是8至56个字符,并将在内部被转化为448位的密钥。然而,所提供的所有字符都具有十分重要的意义。密码越强大,数据就越安全。

除了对数据进行加密,默认情况下,bcrypt在删除数据之前将使用随机数据三次覆盖原始输入文件,以阻挠可能会获得计算机数据的人恢复数据的尝试。如果您不想使用此功能,可设置禁用此功能。

具体来说,bcrypt使用美国密码学家保罗·柯切尔的算法实现。随bcrypt一起发布的源代码对原始版本作了略微改动。

以上内容来自于wiki维基百科 >>>> https://zh.wikipedia.org/wiki/Bcrypt

bcrypt基本介绍

其实简单来说

bcrypt就是一种加盐的单向Hash,不可逆的加密算法,同一种明文(plaintext),每次加密后的密文都不一样,而且不可反向破解生成明文,破解难度很大

而我们熟知的另一种不可逆的加密算法

md5 是不加盐的单向Hash,不可逆的加密算法,同一个密码经过hash的时候生成的是同一个hash值,在大多数的情况下,有些经过md5加密的方法将会被破解。

Bcrypt生成的密文是60位的。而MD5的是32位的。

总的来说,BCrypt比MD5更安全,但加密更慢。

各有优缺点吧。

这里推荐个网站可以完成 bcrypt的加密 我们来尝尝鲜。

https://www.bejson.com/encrypt/bcrpyt_encode/

安装

这里找遍了全网好像也没找到github地址。并且也没有什么安装的教程。

go get -u golang.org/x/crypto/bcrypt

cost常量分类

const (
MinCost int = 4 // 传递给GenerateFromPassword的最小允许开销
MaxCost int = 31 // 传递给GenerateFromPassword的最大允许开销
DefaultCost int = 10 // 如果将低于MinCost的cost传递给GenerateFromPassword,则实际设置的cost
)

使用

这里我们直接看官方写好的测试用例,可能需要 ...(你懂的)

https://cs.opensource.google/go/x/crypto/+/refs/tags/v0.8.0:bcrypt/bcrypt_test.go

GenerateFromPassword 生成一个hash密码

GenerateFromPassword以给定的代价返回密码的bcrypt散列。如果给定的cost小于MinCost,则该cost将被设置为DefaultCost。

GenerateFromPassword不接受长度超过72字节的密码,这是bcrypt操作的最长密码

password, _ := bcrypt.GenerateFromPassword([]byte("123"), bcrypt.DefaultCost)
fmt.Println(string(password))

结果如下

第一次

$2a\(10\)SNRLHrG.ExJHKfR8LihSLOqAJOu/hCpP0ARhwoKvsduxv5xMXkl4u

第二次

$2a\(10\)Np1EBVQ9DZXMvIUkT7Y2P.cA0psEmW2SAVJYcCDqDDN8TsASo7aZm

注: 每次结果都不一样 因为这不是MD5加密,会通过加盐来完成不可逆的加密

Cost方法 返回给定的cost

Cost返回用于创建给定散列密码的散列成本。将来,当密码系统的哈希成本需要增加以适应更大的计算能力时,这个功能允许人们确定需要更新哪些密码。

简单来说 返回上文的 bcrypt.DefaultCost

cost, _ := bcrypt.Cost([]byte("$2a$10$XgLBtSfJsrBd.liLOYWddOYWYWboBUAlKmivcSwq647C3vTNUOVMO"))
fmt.Println(cost)

结果如下

10

CompareHashAndPassword 对比明文密码和散列密码

CompareHashAndPassword,将返回的散列密码与其明文版本进行比较。

password, _ := bcrypt.GenerateFromPassword([]byte("123"), bcrypt.DefaultCost)
fmt.Println(string(password)) // 可以解析出上文
cost, _ := bcrypt.Cost([]byte("$2a$10$XgLBtSfJsrBd.liLOYWddOYWYWboBUAlKmivcSwq647C3vTNUOVMO"))
fmt.Println(cost) err := bcrypt.CompareHashAndPassword(password, []byte("123"))
if err != nil {
fmt.Println("密码验证错误", err)
}
fmt.Println("密码验证成功>>>", nil)

结果

$2a\(10\)ANuBn8FthHbgfYir4v65AOvdtqoR3xjZ0G8duN5ynH1Vm0h3yUF/G

10

密码验证成功>>>

bcrypt某些错误类型

  • type HashVersionTooNewError byte

使用 创建哈希时从 CompareHashAndPassword 返回的错误 比此实现更新的 bcrypt 算法。

func (hv HashVersionTooNewError) Error() string 调用error返回字符串

  • type InvalidCostError int

类型 无效cost错误

func (ic InvalidCostError) Error() string 调用error返回字符串

  • type InvalidHashPrefixError byte

类型无效哈希前缀错误

当哈希以“$”以外的内容开头时,从 CompareHashAndPassword 返回的错误

func (ih InvalidHashPrefixError) Error() string 调用error返回字符串

本文

Golang每日一库之bcrypt的更多相关文章

  1. Go 每日一库之 go-carbon,优雅的golang日期时间处理库

    Carbon 是一个轻量级.语义化.对开发者友好的 golang 时间处理库,支持链式调用. Carbon 已被 awesome-go 收录, 如果您觉得不错,请给个 star 吧. github.c ...

  2. Go 每日一库之 flag

    缘起 我一直在想,有什么方式可以让人比较轻易地保持每日学习,持续输出的状态.写博客是一种方式,但不是每天都有想写的,值得写的东西. 有时候一个技术比较复杂,写博客的时候经常会写着写着发现自己的理解有偏 ...

  3. Golang实现requests库

    Golang实现requests库 简单的封装下,方便使用,像python的requests库一样. Github地址 Github 支持 GET.POST.PUT.DELETE applicatio ...

  4. Golang 的 TOML库

    TOML 的全称是 Tom's Obvious, Minimal Language,因为它的作者是 GitHub 联合创始人 Tom Preston-Werner. TOML 的目标是成为一个极简的配 ...

  5. 『Golang』—— 标准库之 os

    Golang 的 os 库基本承袭 Unix 下 C 语言的用法 path 库: func Base(path string) string //取文件名,不含目录部分 func Dir(path s ...

  6. Go 每日一库之 viper

    简介 上一篇文章介绍 cobra 的时候提到了 viper,今天我们就来介绍一下这个库. viper 是一个配置解决方案,拥有丰富的特性: 支持 JSON/TOML/YAML/HCL/envfile/ ...

  7. Go 每日一库之 fsnotify

    简介 上一篇文章Go 每日一库之 viper中,我们介绍了 viper 可以监听文件修改进而自动重新加载. 其内部使用的就是fsnotify这个库,它是跨平台的.今天我们就来介绍一下它. 快速使用 先 ...

  8. Golang编写动态库实现回调函数

    Golang编写动态库实现回调函数 我们现在要做一个动态库,但是C++实在是比较难,于是就想能不能用更简单的golang来实现,golang也就是最近的版本才支持编译成动态库,在网上也没找到可用的案例 ...

  9. golang命令行库cobra的使用

    简介 Cobra既是一个用来创建强大的现代CLI命令行的golang库,也是一个生成程序应用和命令行文件的程序.下面是Cobra使用的一个演示: Cobra提供的功能 简易的子命令行模式,如 app ...

  10. golang使用simplejson库解析复杂json

    cnblogs原创 golang自带的json解析库encoding/json提供了json字符串到json对象的相互转换,在json字符串比较简单的情况下还是挺好用的,但是当json字符串比较复杂或 ...

随机推荐

  1. .net 生成Excel并保存

    void SaveQuestionToExcel(List<Question> datas, string path) { using (Workbook workbook = new H ...

  2. js 字符串和16进制的互相转换(转)

    字符串转16进制 function strToHexCharCode(str) { if(str === "") return ""; var hexCharC ...

  3. CVE-2016-2183(SSL/TLS)漏洞的办法

    运行gpedit.msc,打开"本地组策略编辑器" 启用"SSL密码套件顺序" TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_ ...

  4. Executors.newScheduledThreadPool()定时任务线程池

    定时任务线程池是由 Timer 进化而来 jdk中的计划任务 Timer 工具类提供了以计时器或计划任务的功能来实现按指定时间或时间间隔执行任务,但由于 Timer 工具类并不是以池 pool ,而是 ...

  5. win10无管理员权限下以压缩包方式安装JDK8

    使用场景:如果在没有管理员权限的情况下,无法运行.exe文件,可以使用这种方式安装,本次把JDK安装到D:\jdk-8u152 一:获取JDK8的压缩包 1.JDK8 华为镜像地址 2.将下载好的ex ...

  6. 【MSSQL】远程打开对象

    opendatasource https://docs.microsoft.com/zh-cn/sql/t-sql/functions/opendatasource-transact-sql?view ...

  7. c# 数组 集合 属性访问 设置

    当只修改数组或者集合的某一个特定值时不会经过CLR属性封装器

  8. vue项目 - 自定义数字输入指令 | 限制自定义小数位输入

    1.在main.js中直接加入代码: import Vue from 'vue' Vue.directive("input-limit", { bind(el, binding) ...

  9. JsonResult向前端返回值,报错500

    1,问题原因 因为返回信息为json对象,我在controller方法所在的入口类上,添加的注解是:@Controller 而@Controller是不适合返回json内容的 2,解决方法 方法一:不 ...

  10. 【桥接设计模式详解】Java/JS/Go/Python/TS不同语言实现

    [桥接设计模式详解]Java/JS/Go/Python/TS不同语言实现 简介 桥接模式(Bridge Pattern)是一种结构型设计模式,它将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的 ...