一、引入

Gin是一个用Go语言编写的Web框架,而用户密码的加密通常是在应用程序中处理用户身份验证时的一个重要问题。

通常敏感信息你要防两类人:

  • 研发人员:包括你自己和你的同事。作为研发人员,你可能会接触到公司的敏感信息,如用户数据、商业机密等。
  • 攻击者:指那些有意获取或破坏敏感信息的人。他们可能是黑客、竞争对手、内部威胁等。

所以为了增加安全性,密码通常不应以明文形式存储在数据库中,而是应该经过适当的加密处理。

二、密码加密位置

实际上,你选择 servicerepositorydao,包括 domain 都可以:

  • service 加密:加密是一个业务概念,不是一个存储概念。
  • repository 加密:加密是一个存储概念,毕竟我们说的是“加密存储”。
  • dao 加密:加密是一个数据库概念,因为我完全可以选择利用数据库本身的加密功能来实现。
  • domain 加密:加密是一个业务概念,但是应该是“用户(User)”自己才知道怎么加密。

三、如何加密

加密算法的选择会直接影响你整个系统的安全性,因为攻击者一旦拿到了密码,差不多就可以为所欲为了。

选择加密算法的标准就一个,难破解。你要考虑以下问题:

  • 相同的密码,加密后的结果应该不同。你可以预期,很多用户习惯用 123456 这种密码,但是我们希望数据库存储的值还是不一样。
  • 难以通过碰撞、彩虹表来破解。

常见的加密算法无非就是下面这些,安全性逐步提高:

  1. md5 之类的哈希算法。

  2. 在 1 的基础上,引入了盐值(salt),或者进行多次哈希等。

  3. PBKDF2BCrypt 这一类随机盐值的加密算法,同样的文本加密后的结果都不同。

四、bcrypt 库加密

4.1 介绍

在Go语言中,可以使用bcrypt库来对密码进行安全加密,号称最安全的加密算法。

4.2 优点:

  • 不需要你自己去生成盐值。

  • 不需要额外存储盐值。

  • 可以通过控制 cost 来控制加密性能。

  • 同样的文本,加密后的结果不同。

4.3 使用

首先,你需要在Go中安装bcrypt库:

go get golang.org/x/crypto/bcrypt

下面是一个使用bcrypt库在对用户密码进行加密的示例:

package main

import (
"fmt"
"golang.org/x/crypto/bcrypt"
) func main() {
// 用户注册时使用的密码
password := "user_password" // 使用bcrypt库对密码进行哈希处理
hashedPassword, err := hashPassword(password)
if err != nil {
fmt.Println("Error hashing password:", err)
return
} fmt.Println("Original Password:", password)
fmt.Println("Hashed Password:", hashedPassword) // 模拟用户登录时的密码验证
err = comparePasswords(hashedPassword, "wrong_password")
if err != nil {
fmt.Println("Password does not match:", err)
} else {
fmt.Println("Password matches!")
} err = comparePasswords(hashedPassword, "user_password")
if err != nil {
fmt.Println("Password does not match:", err)
} else {
fmt.Println("Password matches!")
}
} func hashPassword(password string) (string, error) {
// 使用bcrypt库的GenerateFromPassword函数进行哈希处理
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
return "", err
}
return string(hashedPassword), nil
} func comparePasswords(hashedPassword, inputPassword string) error {
// 使用bcrypt库的CompareHashAndPassword函数比较密码
err := bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(inputPassword))
return err
}

加密后的结果如下:

五、小黄书密码加密实践

webook/internal/service/user.go:

func (svc *UserService) SignUp(ctx context.Context, u domain.User) error {
// 先加密密码
hash, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
if err != nil {
return err
}
u.Password = string(hash)
// 然后存起来
return svc.repo.Create(ctx, u)
} func (svc *UserService) Login(ctx context.Context, email, password string) (domain.User, error) {
// 先找用户
u, err := svc.repo.FindByEmail(ctx, email)
if err == repository.ErrUserNotFound {
return domain.User{}, ErrInvalidUserOrPassword
}
if err != nil {
return domain.User{}, err
}
// 比较密码了
err = bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
if err != nil {
return domain.User{}, ErrInvalidUserOrPassword
}
return u, nil
}

Gin 框架之用户密码加密的更多相关文章

  1. 如何基于Security框架兼容多套用户密码加密方式

    一.说明 当已上线的系统存在使用其他的加密方式加密的密码数据,并且密码 不可逆 时,而新的数据采用了其他的加密方式,则需要同时兼容多种加密方式的密码校验. 例如下列几种情况: 旧系统用户的密码采用了 ...

  2. Maven-009-Nexus 用户密码加密(安全必须)

    信息数据大爆发的时代,我们关心什么?没错,数据安全!数据安全!数据安全!(重要事情说三遍,哈哈哈...) 之前我们存放在 maven settings.xml 文件中的 Nexus 私服用户密码都是明 ...

  3. C#:使用MD5对用户密码加密与解密

    C#中常涉及到对用户密码的加密于解密的算法,其中使用MD5加密是最常见的的实现方式.本文总结了通用的算法并结合了自己的一点小经验,分享给大家. 一.使用16位.32位.64位MD5方法对用户名加密 1 ...

  4. Cognos权限认证CJP方式之用户密码加密

    在项目开发过程中,用户往往对系统的安全都有明确的要求,下面针对cognos门户认证用户密码如何加密来提供一个简单的wf 1Cognos权限认证方式:CJP 2Cognos用户数据库类型:Oracle ...

  5. c# 对用户密码加密解密

    一.使用16位.32位.64位MD5方法对用户名加密 1)16位的MD5加密 ? 1 2 3 4 5 6 7 8 9 10 11 12 /// <summary> /// 16位MD5加密 ...

  6. 转 C#:使用MD5对用户密码加密与解密

    C#中常涉及到对用户密码的加密于解密的算法,其中使用MD5加密是最常见的的实现方式.本文总结了通用的算法并结合了自己的一点小经验,分享给大家. 一.使用16位.32位.64位MD5方法对用户名加密 1 ...

  7. java工具类学习,系统中用户密码加密总结

    现在项目,用户注册登录部分很少有涉及到了,原因:现在热门开发框架都已经在底层帮我们做了一套用户注册,密码加密,登录认证,权限控制,缓存数据等基本功能. 这有利于项目的快速完成,只需要搬砖码畜们专注于业 ...

  8. Openfire用户密码加密解密

    需求要求审核过程中都用匿名进行用户注册登录,注册用户审核通过后才使用openfire内置表 如何做到用户密码统一 Openfire是通过org.jivesoftware.util.Blowfish.j ...

  9. 使用bcrypt进行用户密码加密的简单实现

    Bcrypt百度百科: bcrypt,是一个跨平台的文件加密工具.由它加密的文件可在所有支持的操作系统和处理器上进行转移.它的口令必须是8至56个字符,并将在内部被转化为448位的密钥. 除了对您的数 ...

  10. php提供的用户密码加密函数

    在实际项目中,对用户的密码加密基本上采用的  md5加盐的方式, php5.5后提供了一个加密函数,不需要手动加盐,不需要去维护盐值, $str = "123456"; $pwd ...

随机推荐

  1. 利用Appuploader上架IPA步骤

      Appuploader可以辅助在Windows.linux或mac系统直接申请iOS证书p12,及上传ipa到App Store.方便在没有苹果电脑情况下上架IPA操作. 一.下载安装iOS上架辅 ...

  2. .Net Core NLog 配置

    using NLog; private static Logger logger = LogManager.GetCurrentClassLogger(); //初始化日志类 NLog.config ...

  3. Zookeeper面试题总结

    1.请简述Zookeeper的选举机制 假设有五台服务器组成的zookeeper集群,它们的id从1-5,同时它们都是最新启动的,也就是没有历史数据,在存放数据量这一点上,都是一样的. 假设这些服务器 ...

  4. Mongodb--用户/权限

    mongodb分为管理员用户和普通用户,并且还有个验证库,建立用户时use到的库(验证库),信息就存储在admin数据库下. 在使用用户时,要加上验证库才能登录,对于管理员用户,必须在admin下创建 ...

  5. C++实现简单的日期正则表达式

    简单的日期正则表达式 一个简单的日期解析程序,从yyyy-mm-dd格式的日期字符串中,分别获取年月日. 先设置一个简单的正则表达式,4位数字的"年",1-2位数字的"月 ...

  6. @Constraint注解,做特殊的入参校验

    // @Constraint 是 Java 中的注解之一,用于标记自定义的约束注解.约束注解通常用于数据验证,用来限制字段的取值或格式,确保数据的合法性. @Constraint(validatedB ...

  7. 配置项目按eslint规范格式化代码

    配置项⽬按eslint规范格式化代码 vscode下载 ESlint,Prettier,Vetur 插件 打开vscode的设置 添加如图配置(window系统,mac系统配置稍有不同) 可⾃定义es ...

  8. Feign源码解析6:如何集成discoveryClient获取服务列表

    背景 我们上一篇介绍了feign调用的整体流程,在@FeignClient没有写死url的情况下,就会生成一个支持客户端负载均衡的LoadBalancerClient.这个LoadBalancerCl ...

  9. 如何在Python中的子进程获取键盘输入

    场景:在Python中使用multiprocessing模块的Process创建子进程,试图在子进程中获取键盘输入. 使用input() 在子进程中使用input()会弹出报错信息:EOFError: ...

  10. 使用 nacos 搭建注册中心及配置中心

    本文为博主原创,转载请注明出处: 在分布式微服务框架中,现在都流行使用 nacos 作为分布式框架的注册中心与配置中心.当我们搭建一套spring boot 框架的时候,默认会将配置文件 放在 res ...