首页 > 其他分享 >Golang每日一库之bcrypt

Golang每日一库之bcrypt

时间:2023-04-27 18:11:55浏览次数:51  
标签:GenerateFromPassword 加密 密码 Golang 一库 cost bcrypt MD5

本文

官方文档: 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返回字符串

本文

标签:GenerateFromPassword,加密,密码,Golang,一库,cost,bcrypt,MD5
From: https://www.cnblogs.com/zichliang/p/17356951.html

相关文章

  • 在Golang中使用Testify mock框架
    1.前言2.实现代码3.Mock和测试4.Mock无参方法5.Mock带参数的方法6.Mock带参数的方法,但是参数具体内容非测试重点7.Mock带参数的方法,并校验实际参数8.Mockery9.参考1.前言我使用golang已经有一段时间了,但直到最近我才终于明白如何在golang测试中进行对象......
  • Golang单元测试
    1.前言2.先决条件3.创建单元测试的示例程序4.创建单元测试5.使用gotest运行测试6.Table-driven的单元测试7.测试覆盖率8.Go基准测试9.为代码写示例10.总结11.参考文档1.前言原文:HowToWriteUnitTestsinGoAuthor:TobiBalogun译者:philoenglis......
  • golang1.6版本json包解析嵌套指针的问题小记
    指针的指针问题本地跑的好好的,测试环境跑的好好,预发布环境(准线上环境),跪了。起因就是:1a:=&struct{s:""}2json.Unmarshal([]byte{},&a)3fmt.Println(a.s)//报错行第一行代码进行&取地址,获得指针变量。第二行代码,进行json解析的时候,传入了&a, 指针的指针,a到了jso......
  • Golang 并发&同步的详细原理和使用技巧
    Golang并发概要说明并发模型Golang的并发模型属于一种很典型的CSP(communicatingsequentialprocesses)并发模型,其核心是不要通过共享内存来通信,而应该通过通信来共享内存。具体实现,就是通过goroutine来实现并发,然后并发的goroutine之间通过Channel来进行通信;为此,Gola......
  • Spring Security 报:Encoded password does not look like BCrypt
    SpringBoot集成Security时,报EncodedpassworddoesnotlooklikeBCrypt原因:SecurityConfig必须Bean的形式实例化/***配置用户身份的configure()方法**@paramauth*@throwsException*/@Overrideprotectedvoidconfigure(AuthenticationManagerBuilder......
  • Golang - 5 Golang的流程控制:if/else、for、switch
    5流程控制目录5流程控制1if/else1.1语法2for2.1语法2.2简单写法与实现while的功能2.3基于迭代的循环、基于索引的循环3switch3.1switch的基本使用3.2各种形式1if/else1.1语法 //基本形式if条件1{ }else条件2{ }else{ }多个分支age:=......
  • golang -WARNING: undefined behavior - version of Delve is too old for Go version
    1.背景启动警告 这是idea内置的dlv.exe调试器版本太低了2.解决安装最新的goinstallgithub.com/go-delve/delve/cmd/dlv@latest安装成功后,在golang的安装位置多出来个新的dlv.exe  idea打开配置 写上自己的地址即可下面是我的 重启idea生效......
  • 关于golang线程安全
    最近在字节面试,面试有一个提问:golang中的string赋值是线程安全的吗?如果是,怎么验证,如果不是,怎么验证第一反应,golang的string底层结构:typestringStructstruct{strunsafe.Pointerlenint}其中str是一个不变数组,所以该变字符串的内容都会重新生成一个底层数组,但......
  • 引用 maxmind golang 库导致的程序无法 recover crash 的问题
    新做的Gateway程序打算使用一个maxmind第三方库来解析地理信息,想了一下比较简单找了一个库直接使用。项目跑了一天得到了一堆panic,程序崩溃超过1s丢了不少数据。 从stack信息可以看到调用amxminddb-golang这个库的readLeft出现了错误,最后抛出了一个unexceptedf......
  • golang 使用 net包实现 tcp server 示例
    之前用到golang进行网络编程时,主要就是使用net/http和web框架gin,这些网络库的底层其实也还是用的标准库自带的net包,很多是对路由或者其他做封装,而且golang本身的长处之一也是网络IO的处理,这也得益于其底层的IO模型,今天我们分享的是基于TCPserver/client的简单实现,后......