【问题标题】:Best practice to store password in xml security-context.xml or database?将密码存储在 xml security-context.xml 或数据库中的最佳实践?
【发布时间】:2013-07-30 13:19:39
【问题描述】:

开发者们好日子。 我有问题。在我的 Web 应用程序中,我使用 Spring Security。我有 2 个简单的角色:用户、管理员。对于这些规则中的每一个,我都有自己的密码,因为它们对我的网络应用程序的访问权限不同。所以我现在将所有密码存储在 security.xml 中,采用 sha-256 哈希编码:

    <security:http pattern="/search" security="none" />

    <security:http auto-config="true" >

    <security:session-management session-fixation-protection="migrateSession"/>

    <security:intercept-url pattern="/input" access="ROLE_ADMIN, ROLE_USER"/>
    <security:intercept-url pattern="/delete" access="ROLE_ADMIN"/> 

    <security:form-login login-page="/login" 
                         authentication-failure-url="/loginfail"
                         default-target-url="/input" 
                         always-use-default-target="true" 
                         username-parameter="j_username"
                         password-parameter="j_password" />

    <security:logout logout-success-url="/logout"/>

        <security:session-management>
            <security:concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
        </security:session-management>

    </security:http>


    <security:authentication-manager>
    <security:authentication-provider>
    <security:password-encoder hash="sha-256"/>
    <security:user-service>
    <security:user name="user" password="04f8996da763b7a969b1028ee3007569eaf3a635486ddab211d512c85b9df8fb" authorities="ROLE_USER"/>
    <security:user name="admin" password="8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918" authorities="ROLE_ADMIN"/>
    </security:user-service>
    </security:authentication-provider>
    </security:authentication-manager>

这真的是个好主意吗?也许需要将它们仅存储在 DB(例如 H2)中以获得更多保护。

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!-- Using and configuring C3P0 proxy -->
        <property name="driverClass"><value>org.h2.Driver</value></property>
        <property name="jdbcUrl"><value>jdbc:h2:/home/vadim/workspace-sts-3.1.0.RELEASE/h2/EDUCATION</value></property>
        <property name="user"><value>sa</value></property>
        <property name="password" ><value></value></property>
        <property name="initialPoolSize"><value>3</value></property> <!-- Number of Connections a pool will try to acquire upon startup -->
        <property name="minPoolSize"><value>1</value></property> <!-- Minimum connection pool size -->
        <property name="maxPoolSize"><value>20</value></property> <!-- Max connection pool size -->
        <property name="maxConnectionAge"><value>3600</value></property> <!-- Set max connection age to 1 hour, after it will release -->
        <property name="maxIdleTime"><value>600</value></property> <!-- 10 minutes connection can stay unused before be discarded -->
        <property name="checkoutTimeout"><value>200000</value></property> <!-- Each what time check for unused connections -->
        </bean>

现在我的密码是空白的,但我应该有一个。如何保护它??

谢谢。

【问题讨论】:

  • 您最好的保护是保护您的数据存储。无论是数据库、平面文件还是其他任何东西都无关紧要。如果这种情况暴露出来,那么开始找到密码只是时间问题。
  • 好的,我在我的 app-config.xml 中使用数据库,我在其中配置数据源,但我真的不知道如何隐藏它。根据您的回复,我该如何保护它。为了获得更多理解,我将添加我的 app-config.xml。谢谢科林。

标签: java database spring spring-security hashcode


【解决方案1】:

使用新的 BCryptPasswordEncoder:

http://static.springsource.org/spring-security/site/docs/3.1.x/apidocs/org/springframework/security/crypto/bcrypt/BCryptPasswordEncoder.html

它会自动为您的密码加盐。

我推荐 BCrypt,因为它很强大,速度很慢,并且没有已知的弱点。 “慢”实际上是哈希算法中你想要的一个特性,因为这意味着如果有人窃取了你的密码,它需要更长的时间来破解。

SHA 256 是weakened。 MD5肯定坏了。

在 xml 文件中存储用户/散列密码的优点是简单。但是,您需要重新启动应用程序才能进行更改。此外,没有用户自我管理。

BCryptPasswordEncoder 上有一个 encode 方法,可让您对密码进行编码以存储在 xml 或数据库中。

【讨论】:

  • 先生,请问您。例如,我必须像“用户”一样对我的普通密码进行 BCrypt,然后在创建 bean BCryptPasswordEncoder 以在用户将密码输入为纯文本时识别我的密码。对吧??
  • 您链接的文章解决了由于冲突而使用哈希作为地址的弱点。散列密码是一个完全不同的球游戏。
【解决方案2】:

不要将两个用户硬编码为两个角色。使用该应用程序的每个人都应该是拥有自己的用户名和密码的个人用户。各个用户将拥有一个或两个角色。

考虑到这一点,很明显您需要将用户数据存储在数据库中。您的用户表应该包含用户名、散列密码、盐和您需要的任何其他字段。

您应该有另一个包含角色的表,以及另一个将用户映射到角色的表。

创建用户后,您应该使用密码随机生成器(例如SecureRandom)生成盐。散列密码是使用散列算法创建的,salt, spring security 有一个ShaPasswordEncoder 可以做到这一点(它还支持多个散列迭代)。

我建议阅读 spring 安全文档,特别是 http://static.springsource.org/spring-security/site/docs/3.1.x/reference/ns-config.html#ns-auth-providers

【讨论】:

  • 谢谢您的回复先生。我的应用程序将从一个地方控制,比如这个地方负责将数据放入数据库并删除它们。此搜索页面女巫的应用程序的其他部分将没有安全性。它负责搜索存储在该位置的数据库中的数据。我只保护了管理员的删除页面 jsp 访问权限,并输入了页面 jsp 用户角色和管理员角色。如何为我在 security.xml 中声明的用户和管理员的永久密码绑定 salt + HASH。无法理解。
【解决方案3】:

当您存储密码时,您必须至少对其进行散列(多次,例如 1000)并对其进行加盐。

多次散列是必不可少的,因为如果有人试图破解密码,他还需要像你一样多次对输入进行散列:这会让黑客失去时间。

加盐可防止黑客使用哈希密码的反向表。

您还应该为每个用户使用不同的盐。

这里,你的密码在配置文件中加密,没有加盐,我只是用逆向表来找到对应的密码。

编辑:实际上,我试过了。您的第一个密码是“user”。您的第二个密码是“admin”。我让他们使用这个简单的公开可用的reverse table

【讨论】:

  • 首先,您根本不应该加密密码,您应该对它们进行散列。加密是可逆的,散列不是。其次,你不应该只是“重复几次”。如果您愿意,您可以md5 密码 2000 次,它不会比一次更安全。黑客不必对它进行 2000 次散列,(s)他只需要在md5'd 时找到另一个生成相同散列的输入。您应该使用多轮加密安全算法,例如河豚
  • 但是如果我只是在我的 security.xml 中预装了密码,它应该如何工作(加盐和加密)?我以为我不能使用盐渍,因为它会在我为愿意使用我的网络应用程序的用户注册系统时生成密码。在输入的密码中添加随机字符??我错过了什么吗?而加密,那又如何呢?哈希还不够?据我所知,这是隐藏密码的一种方式,并且很难将其恢复为纯文本?
  • @Colin 好的哈希,我编辑了。对于第二部分,我不同意。破解密码的目的是为了能够用它来登录系统。您输入的登录名将被系统哈希 2000 次,因此您需要哈希 2000 次以确保哈希密码对应。顺便说一句,我从www.owasp.org 那里得到这个建议。
  • @USER_JVM :我不知道 spring security 提供的选项,但如果你使用这个配置,它显然是不安全的,因为我花了 30 多岁才找到你的密码。您可能更喜欢 Apache Shiro 来处理您的安全问题。
  • @ArnaudDenoyelle 没错。对不起,我说的是不同的东西。第 2000 次并不比第一次更密码学安全,但你说得对,暴力破解需要更长的时间。
猜你喜欢
  • 2012-04-28
  • 2018-07-27
  • 2014-12-18
  • 2010-11-25
  • 2013-10-09
  • 1970-01-01
  • 2012-05-10
  • 1970-01-01
  • 2018-08-13
相关资源
最近更新 更多