`
woshixushigang
  • 浏览: 581983 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

最简单的用户密码保存方式

 
阅读更多
最简单的用户密码保存方式

用户访问网站,在注册时需要输入用户名和密码,在仅考虑功能的前提下,可以把用户名和密码以明文的方式存储在数据表中。

Username Password
foobar foobar#123456

当用户登录时,直接使用用户提供的明文密码与数据库中的密码进行比对,如果相同则授权用户登录。

面临的安全问题 : 数据库被窃取导致密码泄露

明文密码保存方式在实现上非常简单,但面临的问题也很明显:没有任何安全防护机制,任何有权读取数据库的人都可以获取所有用户的密码。因此我们需要一种即使数据文件被窃取,窃取者也不能获取用户密码的方式。

解决方式:使用单向hash方式散列用户密码

通过hash的方式,可以比较有效的降低密码泄露的风险。 hash是把输入的数据流通过特定的算法处理后,输出是一个固定长度的字符串。如”foobar#123456”经过md5之后,值为”1276563ea8d2c0ef9b04979d59f5d93e”, 把这个字符串保存到数据库中替代密码明文。

Username Password
foobar 1276563ea8d2c0ef9b04979d59f5d93e

当用户登录时,把用户输入的密码经过md5之后与数据库中的字符串进行对比。

通过hash的处理,即使数据库文件被窃取,窃取者也不能直观的获取到foobar账号的密码是什么。

hash的特点是单向的:由输入流可以得到确定的输出字符串,但从输出的字符串反向获取输入流的代价极高,几乎是不可能做到的。

常见的hash处理方式是md5, sha1, sha256, sha512 等。

  • md5的输出是16byte,128bit 的字符串;
  • sha1的输出是20byte,160bit的字符串;
  • sha256的输出是32byte,256bit的字符串;
  • sha512的输出是64byte,512bit的字符串;输出结果的长度越大,hash方式的安全性就越高, 目前常用的是md5和sha1.
简单hash方式面临的问题: Rainbow攻击

使用md5,sha1等hash防止直接对用户密码进行加密,是存在一定的隐患的。 窃取者可以通过Rainbow的方式进行暴力破解。

Rainbow的方式很简单, 首先根据密码所使用字符范围和密码长度构造出所有可能的密码序列(称为词典),然后对这些密码序列进行hash(如md5), 然后把hash后的字符串与数据库中的Password字段进行对比。 这样可以非常快速的比对到foobar账号的真实密码是什么。有测试表明,破解一个7位长度,有a-z,A-Z,0-9构造出来的密码,只需要不到40秒的时间就可以了, 非常快。

改进的Hash处理方式:对抗Rainbow攻击
  1. 让用户使用更长,含有更多特殊字符的密码
  2. 如让用户必须使用含有数字、大小写字母,甚至包括!@#$% ^&*( 这种特殊字符的密码。这种方式能提高Rainbow攻击的hash词典的构造时间和比对时间,但由于以下两个原因,不建议过度使用该方式。
    a. 由于现在CPU的计算能力极为强大,词典的构造时间并不是关键因素
    b. 复杂的密码用户很难记忆,用户体验太差

  3. 使用更高长位的hash方式
  4. 相比于md5和sha1,可以使用sha256或者sha512的方式,更长的hash串意味着攻击者需要花费更多的时间准备词典。但基于CPU计算能力的强大,这种方式的安全性仍然不足。

  5. 使用salt进行hash
  6. 谓salt,其实是一个普通的字符串。在对密码进行hash之前,先把这个字符串与密码连接起来。如作为明文密码的前缀或者后缀,然后对新的字符串进行hash操作。 salt通常保存在代码中,这样即使数据库文件丢失,只要代码源文件不丢失,攻击者是没有办法获取原始密码的。

  7. 使用速度较慢的hash方式
  8. md5,shax系列的方式,都是通过优化的算法,每次的计算都极为迅速,攻击者准备攻击词典的时间也就大大的缩短。因此我们可以选择较慢的hash方式,如bcrypt。

    bcrypt是一种基于blowfish算命的hash方式,其特点是设计者可以根据选择hash的时间消耗。 如设置高等级的时间消耗,一次bcrypt甚至可以需要300毫秒才能计算完毕,而通常的md5甚至不需要1毫秒。 这样可以让攻击者的词典准备时间延长300倍,极大的增加了攻击时间成本。
完美的解决方案
  1. 使用bcrypt慢hash方法
  2. 为每个用户的hash过程提供salt
  3. 使用全局salt
  4. 通过这三个步骤, 密码的生成过程可这样表示 :

    $hashPasswd = hash( $global_salt + hash(cleartext_password + $user_only_salt));
推荐的解决方案

基于时间成本、项目复杂度和安全读需求,常规Web类项目的推荐解决方案如下

  1. 使用md5或者sha1
  2. 为每个用户的hash过程提供salt
  3. 使用全局salt
  4. 密码的生成过程为:

    $hashPasswd = sha1( $global_salt + sha1(cleartext_password + $user_only_salt));
分享到:
评论

相关推荐

    WPF将用户名和密码加密保存在文件当中

    在Windows Presentation Foundation(WPF)应用中,为了保护用户的敏感信息,如用户名和密码,开发者通常会选择将这些数据加密后存储在本地。本教程将详细解释如何在WPF客户端实现这个功能,涉及到的主要知识点包括...

    最简单的Windows系统登录密码解救方法

    本文将详细介绍一种最简单、高效的Windows系统登录密码解救方法,旨在帮助用户快速解决此类问题。 首先,我们需要了解Windows系统登录密码的类型。Windows系统支持本地账户和Microsoft账户两种登录方式,本地账户的...

    android实战 保存QQ密码(android studio源程序工程)

    在这个实例中,最可能使用的是Shared Preferences,因为它适用于保存简单的键值对数据,如用户名和密码,且易于操作。 Shared Preferences是Android提供的一种轻量级的数据存储机制,用于存储一些小型的配置数据。...

    最简单的增删改查,登陆、修改密码

    在这个“最简单的增删改查,登陆、修改密码”的项目中,开发者可能已经实现了一个基本的Web应用,用户可以进行数据操作并管理自己的账户。使用DB_51aspx作为数据库,初始账号和密码为51aspx,这可能是为了方便演示和...

    用plist保存账号密码

    Plist是一种便捷的数据存储方式,但处理敏感信息如账号密码时,必须采取适当的安全措施。在实际开发中,应优先考虑使用Keychain等专为安全设计的API,确保用户数据的安全。通过理解Plist的工作原理和安全实践,...

    易语言简单密码防查看

    密码通常不直接存储在明文中,而是经过哈希函数处理后保存。哈希函数将任意长度的输入转化为固定长度的输出,使得即使知道哈希值也无法轻易推算出原始密码。在验证过程中,用户输入的密码同样经过哈希运算,然后与...

    linux编写bash shell脚本文件.sh 自动输入密码.在脚本中使用sudo命令,将密码保存在脚本中,不需要手动输入密码

    通常,运行带有`sudo`的命令时,系统会提示用户输入密码。然而,为了实现自动化,我们不希望在脚本执行过程中手动输入密码。本文将详细介绍如何在Bash Shell脚本中使用`sudo`命令,并避免手动输入密码。 首先,理解...

    忘记交换机的超级用户密码怎么办

    当您忘记交换机的超级用户密码时,不必担心设备无法管理。通过交换机的BOOT ROM菜单,您可以绕过当前的配置文件,从而有机会重新设置密码。以下是一个详细步骤的指南,帮助您解决这个问题: 1. **重启交换机**:...

    TortoiseSVN 密码找回工具,简单实用

    不同版本的TortoiseSVN可能使用不同的密码存储方式,因此不兼容的工具可能无法正确显示密码。 3. 权限要求:为了读取和解析本地的SVN配置文件,TSvnPwd.exe可能需要管理员权限。如果在运行时遇到问题,尝试以管理员...

    自动化添加用户密码脚本.rar

    此外,为了确保脚本的安全性,密码通常不会明文存储,而是通过加密方式保存。在生产环境中,你可能需要结合其他工具,如htpasswd,或者使用更安全的方法来管理用户密码。 脚本还可能包含错误处理和日志记录功能,以...

    不知用户密码如何登陆oracle

    ### 不知用户密码如何登陆Oracle 在日常的数据库管理工作中,可能会遇到不知道某个Oracle用户的密码但又需要使用该用户身份进行操作的情况。此时,我们既不想更改用户的密码以免影响其他使用者,也不希望因为一个...

    最简单的用户登录与注册系统 spring mvc spring jdbc

    这个项目是一个基于Spring MVC和Spring JDBC的简单用户管理应用,旨在帮助初学者理解如何在实际开发中实现用户登录、注册以及信息修改功能。Spring MVC是Spring框架的一个模块,主要用于构建Web应用程序,而Spring ...

    验证密码C++代码

    - 用户输入的密码被存储在变量`a`中。 - 使用`if`语句检查用户输入的密码是否与预设的正确密码(本例中为“12345”)匹配。 - 如果密码不正确,则再次输出提示符并跳转到`loop:`标签处,重新开始输入过程。 - 如果...

    加密保存账号密码的好工具

    在Windows环境下,就有这么一些工具,它们不仅能够简单方便地帮助用户加密并保存各种账号密码,还以绿色无广告的纯净体验,赢得了用户们的青睐。这类工具通常设计得非常人性化,即便是对计算机知识不太了解的普通...

    简单的密码防盗技术

    在网络安全日益重要的今天,了解和应用简单的密码防盗技术至关重要。密码是个人隐私和信息安全的守护者,不恰当的密码管理可能会导致严重的后果。本话题将深入探讨几种基础但实用的密码防盗技巧,以帮助用户更好地...

    用Struts实现的最简单的用户登录

    这个"用Struts2实现的最简单的用户登录"示例旨在展示如何利用Struts2框架构建一个基本的用户登录系统。 首先,Struts2的核心是Action类,它是处理用户请求的中心。在这个例子中,我们需要创建一个名为`LoginAction`...

    android登陆界面保存账号密码

    这是最简单的数据存储方式,适用于保存少量、简单的数据。 - **SQLite数据库**: 对于更复杂的密码管理,可能需要使用SQLite数据库来存储用户信息,包括账号、加密后的密码等,提供更安全的数据存储和检索。 - **...

    用户管理密码验证函数

    对于用户密码的验证,可以采用创建自定义函数的方式来实现更为灵活且安全的密码策略。本文将详细介绍如何在Oracle数据库中利用自定义函数来实现密码验证功能,并通过具体示例加以说明。 #### Oracle数据库中的用户...

    一种简单51单片机电子密码锁设计.pdf

    软件的整体设计思路是构建一套完整的系统,通过软件逻辑控制硬件的工作流程,实现密码的输入、存储、比对和控制电磁锁开闭等功能。软件程序设计流程通常包括初始化设置、主循环控制、键盘扫描、密码比对、电磁锁控制...

    一个用于简单密码加密的类c#

    使用这样的类可以帮助开发者在存储和验证用户密码时增加一层额外的安全防护,防止密码被轻易破解。然而,对于实际应用,还需要考虑整个系统的安全性,包括传输层加密、身份验证机制等,以构建全方位的安全体系。

Global site tag (gtag.js) - Google Analytics