一篇讲清楚什么是密码加密和加盐算法 | 附Java代码实现

目录

前言:

一、密码加密

  1. MD5介绍 

2.彩虹表攻击

3.测试复杂密码是否能被攻破

二、加盐算法

1.对密码123456演示加盐算法

2.盐值的储存

3.密码加盐思想总结

三、Java代码实现


前言:

      早些年,数据泄露屡见不鲜,每个班上总有一两个人qq被盗然后群发信息...这是因为,在以前,我们的密码在数据库里都是明文储存。

   以前黑客看到的:账号:123456 密码:123456

            黑客: 

          而现在,我们的密码在数据库里都是密文储存,黑客破解难度大大增加。

现在黑客看到的:账号:123456 密码:e10adc3949ba59abbe56e057f20f883e


一、密码加密

这一串复杂字符其实就是“123456”通过md5加密得到的。

md5加密网站

  1. MD5介绍 

     MD5是一种摘要算法, 摘要算法是一种将任意长度的输入数据转换为固定长度的哈希值的算法。这个哈希值可以视为输入数据的“指纹”,因为它能够唯一地表示原始数据。

主要特点包括:

  1. 固定长度输出:无论输入数据的长度是多少,摘要算法都会生成一个固定长度的哈希值。比如,MD5 总是生成 128 位(16 字节)的哈希值,而 SHA-256 总是生成 256 位(32 字节)的哈希值。

  2. 不可逆性摘要算法是单向的,意味着从生成的哈希值无法反向推导出原始数据。

  3. 高敏感性:即使输入数据的改变非常微小(比如仅改变一个字符),生成的哈希值也会有很大的不同。

  4. 抗碰撞性:不同的输入数据不应生成相同的哈希值。然而,在理论上可能存在哈希碰撞(即两个不同的输入数据生成相同的哈希值),但好的摘要算法会使这种碰撞非常难以发生。 


2.彩虹表攻击

     黑客无法直接从e10adc3949ba59abbe56e057f20f883e看出或计算出这个是“123456”。

     最怕黑客动脑子...

     黑客可以猜你的密码可能是123456,看看出来的值是否与e10adc3949ba59abbe56e057f20f883e相等。如果相等就说明密码是123456。

md5解密网站

事实上,不用手动阀一个一个去猜那么麻烦,有些网站输入密文能破解出。

        而这个破解并不是真的可以从密文里看出明文,而是背后维护了一个密文明文表。已经有前人通过枚举的方式,把常见密码的md5都收集起来了,这样子的话就能快速找到对应的原始密码。这个也叫做彩虹表攻击。

     彩虹表攻击是一种利用预计算哈希值来破解密码的技术。它通过建立一个包含常见密码及其对应哈希值的巨大数据库,允许攻击者快速查找某个哈希值对应的原始密码,而无需逐一尝试所有可能的密码。但彩虹表攻击只适用于简单密码。

彩虹表攻击的原理

  1. 哈希函数:通常密码存储时,系统不会直接保存明文密码,而是保存密码的哈希值。这些哈希值是通过哈希函数(如 SHA-256)计算出来的,哈希函数具有不可逆性,即很难从哈希值反推出原始密码。

  2. 预计算:彩虹表是一种预计算哈希值的表,表中包含了大量可能的明文密码及其对应的哈希值。攻击者可以在获得某个密码的哈希值后,直接在彩虹表中查找相应的明文密码,而无需计算大量哈希值。

  3. 查找匹配:一旦找到匹配的哈希值,攻击者就能够知道原始密码,从而破解密码。

      这也就是为什么我们在一些应用上设置密码时,会要求我们密码增加难度,大小写加数字,这就是增加盲猜到密码的难度。


3.测试复杂密码是否能被攻破

现在我们随机拿一串复杂密码的md5,看看网站能不能解密...

加密过程:

尝试解密:

解密失败。

     这也是为什么,我们在找回密码这个操作时,都是重置密码,而不是告诉你之前的密码是什么,因为它们也不知道...

这样子显然针对复杂密码很有效,但当这个密码是6位数的银行卡密码呢?

6位密码穷举只有9^6=531,441种可能,如果只用md5作为加密算法,维护一个密码表是很容易的,因此密码就很容易被破解。


二、加盐算法

所以我们要把简单密码->复杂密码,就很难破解,这里就要引入加盐算法

而我们需要加在简单密码上加上一些 “盐”使之变成复杂字符串。

为什么叫加盐是因为菜谱上的适量盐,适量到底是多少!!没人知道,只有写菜谱的人才知道


1.对密码123456演示加盐算法

这里我们采用  复杂密码 = 复杂字符串(盐值)+原始密码

123456  ->  odaFEoisRjdDFjfio64854FDF!.F123456

      而如果每一个密码都采用统一的盐值,就等于白给,还是可以通过穷举算出来所有的6位密码。因此,要给每一个密码都配上单独的盐值。

验证密码的比对过程:

 最后比对两个红色部分是否相等来判断密码是否正确。

橙色是数据库中要储存的值。


2.盐值的储存

       每个用户的盐值也需要储存在数据库里,如果单独弄一列来储存,还是不够隐秘。所以我们采用盐值与 md5(盐值+注册密码)拼接的形式

举个例子:

蓝色部分是要存在数据库的字符串,解密时需要用到的两个字段。

拼接在一起存储:(怎么拼的?让别人猜去吧)

如图,拼接方式有很多,安全性大大提高。

      只有知道是怎么拼接的,才能从这个字段中提取出来需要的 盐值 和 md(盐值+密码) 两个字符串。只有写代码的人才知道是怎么拼接的。


3.密码加盐思想总结

1.生成随机盐值:每次为新密码生成一个独特的、随机的盐值,确保不同密码的哈希值不会因为相同的输入密码而相同。

2.盐值与密码组合:将生成的盐值与用户的密码组合在一起,然后对组合后的字符串进行哈希运算。

3.存储哈希值和盐值:在数据库中巧妙存储最终的哈希值和对应的盐值,而不存储明文密码。每次验证密码时,使用相同的盐值进行哈希计算并与存储的哈希值进行比较。

4.增加破解难度:加盐有效防御了彩虹表攻击等基于预计算哈希值的攻击,因为即使攻击者拥有彩虹表,也无法直接查找原始密码的哈希值,因为盐值的随机性使得每个哈希值都是独一无二的。

三、Java代码实现

需求分析:

1.生成盐值

2.加密:用盐值对给定密码进行加密得到哈希

3.解密:给定盐值和哈希,看是否能通过校验

导包:

import org.springframework.util.DigestUtils;// 用于生成 MD5 哈希值
import org.springframework.util.StringUtils;// 用于字符串处理的工具类,检查字符串是否为空
import java.util.UUID;// 用于生成全局唯一标识符(UUID)以生成随机盐值

生成盐值和加密:

 public static String encrypt(String inputPassword) {//生成随机盐值String salt= UUID.randomUUID().toString().replace("-","");//md5(明文+盐值)String finalPassword = DigestUtils.md5DigestAsHex((inputPassword+salt).getBytes());//返回最后数据库中存储的哈希(我这里采用的时盐值+md5(明文+盐值))return salt + finalPassword;}

校验方法:

public static boolean verify(String inputPassword,String sqlPassword) {//校验参数是否合法if(!StringUtils.hasLength(inputPassword)){return false;}if (sqlPassword==null || sqlPassword.length()!=64){return false;}//获取盐值String salt=sqlPassword.substring(0,32);//[0,31)//计算密文String calFinalPassword = DigestUtils.md5DigestAsHex((inputPassword+salt).getBytes());//看是否对应return (salt+calFinalPassword).equals(sqlPassword);}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/398004.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Web前端】vue3整合eslint约束代码格式

一、整合eslint 整合eslint的两种方式: 在已有项目中整合eslint:# 安装eslint及其vue插件即可 npm i -D eslint eslint-plugin-vue创建项目时整合eslint: 提示 是否引入ESLint用于代码质量检测 时选择 是# 创建vue3项目 npx create-vue # 下…

.NET8使用VS2022打包Docker镜像

NET8使用VS2022打包Docker镜像 1. 项目中添加Docker支持文件2. 自定义镜像名称3. 发布Docker镜像3.1 安装Docker3.2 控制台切换到项目根目录,执行以下命令发布镜像 3.3 修改镜像名称4. 保存镜像到本地 1. 项目中添加Docker支持文件 2. 自定义镜像名称 项目文件PropertyGroup节…

vue3中 ref 和 reactive 的区别

相同:均是声明响应式对象。且声明的响应式对象是深层的 1. 数据类型不同:ref用于包装JavaScript基本类型的数据(如字符串、数字、布尔值等),而reactive可以用于包装JavaScript对象和数组等复杂类型的数据。 2.访问方式…

力扣45:跳跃游戏2题解

题目链接: https://leetcode.cn/problems/jump-game-ii/description/?envTypestudy-plan-v2&envIdtop-100-liked 参考的代码随想录里面的题解: 题目 难度 中等,标的是中等难度,而且我之前做过这道题,但是我没写…

AI大模型赋能开发者|海云安创始人谢朝海受邀在ISC.AI 2024大会就“大模型在软件开发安全领域的应用”主题发表演讲

近日,ISC.AI 2024 第十二届互联网安全大会在北京国家会议中心盛大开幕。作为全球规格最高、规模最大、影响力最深远的安全峰会之一,本次大会以“打造安全大模型 引领安全行业革命”为主题,聚焦安全与AI两大领域,吸引了众多行业领袖…

【NLP】文本张量表示方法【word2vec、词嵌入】

文章目录 1、文本张量表示2、one-hot词向量表示2.1、one-hot编码代码实现:2.2、onehot编码器的使用2.3、one-hot编码的优劣势 3、word2vec模型3.1、模型介绍3.2、CBOW模式3.3、skipgram模式3.4、word2vec的训练和使用3.4.1、获取训练数据3.4.2、训练词向量3.4.3、查…

学习笔记第二十三天

1.程序与进程 程序(Program):是静态的,它是一组指令的集合,这些指令被存储硬盘上,,程序本身 不占用CPU或内存资源,直到它被加载到内存中执行。 程序---静态---硬盘 进程&#xff08…

C++速学day4

类的继承关系 蛇 和 爬行类动物 //这两个类就是继承关系 子类 父类 //它们的关系相当于 派生类 基类 继承的作用 1、 吸收基类成员 2、改造基类成员 3、添加新的成员 class Dervid…

docker基本管理和应用

docker是一个开源的应用容器引擎,基于go语言开发的 docker是运行在linux的容器化工具,可以理解为轻量级的虚拟机 可以在任何主机上,轻松创建的一个轻量级,可移植的,自给自足的容器 鲸鱼--------->宿主机 集装箱…

vulnstack-7(红日靶场七)

环境配置 vlunstack是红日安全团队出品的一个实战环境,具体介绍请访问:漏洞详情http://vulnstack.qiyuanxuetang.net/vuln/detail/9/ 添加两个网卡 DMZ区域: 给Ubuntu (Web 1) 配置了两个网卡,一个可以对外提供服务;…

前端路由VueRouter总结

简介: Vue路由vue-router是官方的路由插件,能够轻松的管理 SPA 项目中组件的切换。Vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来vue-router 目前有 3.x 的版本和 4.x 的版本,vue-…

设计模式(1)创建型模式和结构型模式

1、目标 本文的主要目标是学习创建型模式和结构型模式,并分别代码实现每种设计模式 2、创建型模式 2.1 单例模式(singleton) 单例模式是创建一个对象保证只有这个类的唯一实例,单例模式分为饿汉式和懒汉式,饿汉式是…

sliver源码分析-初始化以及脚手架

引言 项目概述:对开源的C2框架sliver进行源码分析,意图学习其原理。本篇分析sliver的入口以及脚手架,和基本的配置文件目标与读者:网络安全兴趣爱好者 准备工作 源码路径BishopFox/sliver: Adversary Emulation Framework (git…

[C++][opencv]基于opencv实现photoshop算法图像旋转

【测试环境】 vs2019 opencv4.8.0 【效果演示】 【核心实现代码】 //图像旋转: src为原图像, dst为新图像, angle为旋转角度, isClip表示是采取缩小图片的方式 int imageRotate4(InputArray src, OutputArray dst, double angle, bool isClip) {Mat input src.…

【c++】类和对象 (中) (类的默认成员函数)

类的默认成员函数 在C中,如果你定义了一个类但没有显式地提供特定的成员函数(比如构造函数、析构函数、拷贝构造函数、拷贝赋值运算符等),编译器会为这些函数生成默认的实现。这些默认生成的成员函数称为类的默认成员函数。那么既…

C#学习笔记15:上位机助手_usercontrol窗体内嵌的应用

今日完善一下之前的上位机助手,做一个组合窗体内嵌的多功能助手软件应用, 与之前的上位机软件相比: 更注重控件能够随着窗体缩放而缩放变换,串口助手部分能自动后台检测串口设备,解决市面上大部分串口助手的打开初始化会卡顿的问题 ( 多线程后…

Linux服务管理-Nginx配置

静态解析主要解析html、css动态解析需要解析php 动态资源通过轮询分配到后端的Apache服务器处理 apache是同步阻塞,nginx是异步非阻塞

论文阅读笔记:Efficient Teacher: Semi-Supervised Object Detection for YOLOv5

Efficient Teacher: Semi-Supervised Object Detection for YOLOv5 1 背景1.1 动机1.2 问题 2 创新点3 方法4 模块4.1 伪标签分配4.2 Epoch Adapter 5 效果5.1 与SOTA方法对比5.2 消融实验 论文:https://arxiv.org/pdf/2302.07577v3.pdf 代码:https://g…

Python 常用内置函数

目录 1、enumerate函数 1.1、for循环中使用 1.2、enumerate指定索引的起始值 1.3、enumerate在线程中的作用 2、Map 函数 2.1、map()函数可以传多个迭代器对象 3、lambda表达式(匿名函数) 示例 4、sort函数和sorted函数 4.1、sort()函数 4.2、…

map和set的使用

关联式容器 在学习关联式容器之前&#xff0c;我们学习过的容器有vector、list、deque…这些容器称为序列式容器&#xff0c;单纯的存储数据存储的数据没有关联性。 即将学习的map 和set属于关联式容器&#xff0c;其里面存储的是<key, value>结构的键值对&#xff0c;…