当前位置: 首页 > news >正文

一文读懂如何安全地存储密码

目录

引言

明文存储

基本哈希存储

加盐哈希存储

适应性哈希算法

密码加密存储

小结


引言

密码是最常用的身份验证手段,既简单又高效。密码安全是网络安全的基石,对保护个人和组织信息的安全具有根本性的作用。然而有关密码泄漏的安全问题一再发生,大部分都是因为密码的存储不安全导致的,那么该如何安全地存储密码呢?接下来就详细讲解一下各种密码存储方案以及对应的优缺点,通过各种方案的对比来选择出最佳的方案。

明文存储

明文存储密码是指在数据库或其他存储系统中直接存储用户密码的原始形式,没有进行任何加密或散列处理。这种方式意味着密码以可读形式保存,任何可以访问存储系统的人都能直接看到明文密码。

这种方式在早期的 Web 应用里面非常常见,一来是为了实现简单,二来是那个时候安全问题不是特别突出,开发人员没有对应的安全意识。随着安全问题日益增多,开发人员安全意识也日益提高,当下这种方式已经很少见了,但是依然有很多缺乏安全意识的同学还这么干。这种方式的缺点就是极其不安全,主要是以下几个方面:

  • 安全性极低:如果数据库遭到未授权访问,攻击者可以立即获取所有用户的密码。不仅危害用户在当前系统中的安全,还威胁用户在其他系统中账户的安全(因为许多用户会在不同的系统中使用同样的密码)。
  • 违反合规性:多数现代的数据保护法规和标准,如欧盟的通用数据保护条例(GDPR)和支付卡行业数据安全标准(PCI DSS),都要求对敏感数据进行加密处理,明文存储密码已经违反了这些法规。
  • 内部威胁:即使外部攻击者无法访问数据库,公司内部的员工也可能无意或有意地泄露密码,增加了内部安全问题发生的风险。

因为这些缺点,明文存储密码是绝对不能使用的方法。

基本哈希存储

基本哈希存储密码是指使用哈希函数(如 MD5、SHA-1 或 SHA-256)将密码转换成固定长度的字符串存储在数据库或其他存储系统中。哈希函数是单向函数,理论上不能从哈希值逆向推导出原始密码。这种方式虽然比明文存储安全性高一些,但仍然有一些明显的缺点:

  • 容易产生哈希碰撞:基本的哈希算法例如 MD5 和 SHA-1,已经被证明存在哈希碰撞的问题,即不同的输入可能产生相同的输出,降低了安全性。
  • 易被破解:因为相同的密码总是产生相同的哈希值,使得攻击者可以使用彩虹表(预先计算的哈希值表)来反向查找密码。另外由于基本哈希函数的计算速度很快,攻击者可以在短时间内尝试大量可能的密码,使用暴力攻击或字典攻击方法来找到原始密码。

这种方式最好不要使用。

加盐哈希存储

加盐哈希存储密码是指在对密码散列过程中加入一个额外的随机值(称为“盐”),这个盐是在用户每次注册或更改密码时随机生成的,与密码一起被哈希处理。然后将盐和哈希值一起存储在数据库中或其他存储系统中。当用户尝试登录时,取出这个盐并与用户输入的密码一起哈希,然后比较这个哈希值与存储的哈希值是否匹配。加盐哈希的目的是为了增加密码存储的复杂性和安全性,用于抵御彩虹表攻击。因为即使两个用户使用相同的密码,由于盐的不同,对应的哈希值也会不同。这种方式虽然可以抵抗彩虹表攻击,但如果使用的哈希函数计算速度很快(如 MD5、SHA-1),则依然容易被暴力破解。使用这种方式需要注意以下几点:

  • 盐的管理:盐必须独特且随机,同时需要安全地存储。如果盐的生成不够随机或者存储不当,那么安全性就会大打折扣。
  • 使用方式:对于每个用户都要使用不同的盐并且在服务器端进行哈希,如使用相同的盐或者在客户端进行哈希,安全性会大大降低。
  • 使用强哈希函数:由于弱哈希函数例如 MD5、SHA-1 等已经被证明不够安全,建议至少选择使用 SHA256 算法。

这种方式目前被广泛使用,但是还有更优的方式。

适应性哈希算法

适应性哈希算法是针对密码存储做了特别设计的算法,设计时考虑了计算时间,可以调整计算复杂度,以适应硬件性能的提升,使得即使在计算能力增强的情况下,破解密码的难度也能保持在一个较高的水平。

这类算法比较有代表性的是 bcrypt、scrypt、Argon2 等,其中 bcrypt 是使用最广泛的,关于 bcrypt 的详解可以参考之前的文章 《安全高效又易用的密码哈希神器-bcrypt 算法解析》。

使用适应性哈希算法存储密码是目前的最佳实践,这些算法专门为密码存储而设计,提供了盐值的自动管理和计算强度的调整能力,以此来抵御各种攻击手段。唯一缺点可能就是兼容性问题了,在一些受限环境中,可能没有对应的实现。使用这种方式时需要注意的一点是要适当配置好工作因子,不然仍然可能受到攻击。

密码加密存储

密码加密存储是指使用加密算法(对称算法或非对称算法)对用户密码进行加密后存储在数据库中或其他存储系统中。与哈希方式不同的是加密是一个可逆的过程,可以通过解密得到原始密码。这通常涉及到一个密钥,只有知道这个密钥的人才能解密密码。

使用对称或非对称加密算法对密码进行加密,然后存储加密后的值。缺陷主要是以下几点:

  1. 密码加密的安全性极大地依赖于密钥的安全性。如果密钥被泄露,所有的密码都将以明文形式泄露。
  2. 存储可逆形式的密码可能会违反某些隐私和安全标准,如 GDPR 或 PCI DSS。
  3. 即使外部攻击者无法访问数据库,公司内部的员工也可能无意中或有意地使用秘钥解密密码,进而泄露密码,增加了内部安全问题发生的风险。

在现代的密码存储实践中,是不推荐使用可逆的加密算法存储的,所以这种方式不推荐使用。

小结

每种密码存储方法都有其优缺点,但最佳实践是使用适应性哈希算法,适应性哈希算法专门为密码存储而设计,提供了盐值的自动管理和计算强度的调整能力,以此来抵御各种攻击手段。

相关文章:

  • Docker的项目资源参考
  • 【TypeScript】常见数据结构与算法(二):链表
  • Interactive Visual Data Analysis
  • GitHub桌面版
  • java http
  • C/C++实现:找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和 某知名企业笔试题
  • SpringBoot封装Elasticsearch搜索引擎实现全文检索
  • Selenium介绍及基本使用方法
  • PDF 批量处理软件BatchOutput PDF mac中文版介绍
  • ElasticSearch之系统关键配置
  • 【开源】基于JAVA的在线课程教学系统
  • Linux系统查看各种信息的常用命令
  • Python 订阅 image_transport 压缩后的深度图 compressedDepth
  • 基于食肉植物算法优化概率神经网络PNN的分类预测 - 附代码
  • 98、Text2Room: Extracting Textured 3D Meshes from 2D Text-to-Image Models
  • 0基础学习移动端适配
  • Android系统模拟器绘制实现概述
  • C++回声服务器_9-epoll边缘触发模式版本服务器
  • ES6简单总结(搭配简单的讲解和小案例)
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • isset在php5.6-和php7.0+的一些差异
  • Logstash 参考指南(目录)
  • ng6--错误信息小结(持续更新)
  • React16时代,该用什么姿势写 React ?
  • session共享问题解决方案
  • Vue--数据传输
  • 高性能JavaScript阅读简记(三)
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 三分钟教你同步 Visual Studio Code 设置
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 使用 @font-face
  • 思维导图—你不知道的JavaScript中卷
  • 王永庆:技术创新改变教育未来
  • 小程序开发中的那些坑
  • 学习笔记:对象,原型和继承(1)
  • 译有关态射的一切
  • ​Spring Boot 分片上传文件
  • ​你们这样子,耽误我的工作进度怎么办?
  • # linux 中使用 visudo 命令,怎么保存退出?
  • #stm32整理(一)flash读写
  • (C++)八皇后问题
  • (python)数据结构---字典
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (备份) esp32 GPIO
  • (编译到47%失败)to be deleted
  • (附源码)ssm经济信息门户网站 毕业设计 141634
  • (六)Hibernate的二级缓存
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (排序详解之 堆排序)
  • (十) 初识 Docker file
  • (四) Graphivz 颜色选择
  • (一) springboot详细介绍
  • (转)Google的Objective-C编码规范
  • (转)linux下的时间函数使用