Announcement Announcement Module
Collapse
No announcement yet.
Spring Security - encrypt password before authenticating Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring Security - encrypt password before authenticating

    Hello,

    I would like to know if anybody has tried encrypting the password entered by the user from the login page before actually passed to authentication using Spring security against LDAP.

    I am using a one way encrypting the password before it is stored in LDAP. Therefore when I login I need to do a one way encryption again before Spring security can authenticate it against LDAP.

    Is there a way to encrypt the password before being handed to Spring security before authentication. My config looks like this. Greatly appreciate your replies.

    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schem...-beans-2.5.xsd
    http://www.springframework.org/schema/security http://www.springframework.org/schem...rity-2.0.1.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-2.5.xsd">

    <http>
    <!--
    <intercept-url pattern="/flow.html" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/homePage.html" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    -->
    <intercept-url pattern="/mainMenu.html" access="ROLE_INVESTORPORTALUSER"/>
    <intercept-url pattern="/update/*" access="ROLE_INVESTORPORTALUSER"/>
    <intercept-url pattern="/product/*" access="ROLE_INVESTORPORTALUSER"/>

    <form-login login-page="/login.html"
    default-target-url="/mainMenu.html"
    authentication-failure-url="/login.html?login_error=1"/>
    <logout logout-success-url="/"/>
    </http>

    <beans:bean id="contextSource" class="org.springframework.security.ldap.DefaultSp ringSecurityContextSource">
    <beans:constructor-arg value="${ldap.host}"/>
    <beansroperty name="userDn" value="${ldap.username}"/>
    <beansroperty name="password" value="${ldap.password}"/>
    </beans:bean>

    <beans:bean id="ldapAuthProvider" class="org.springframework.security.providers.ldap .LdapAuthenticationProvider">
    <custom-authentication-provider />
    <beans:constructor-arg>
    <beans:bean class="org.springframework.security.providers.ldap .authenticator.BindAuthenticator">
    <beans:constructor-arg ref="contextSource"/>
    <beansroperty name="userDnPatterns">
    <beans:list>
    <beans:value>${ldap.userDn}</beans:value>
    </beans:list>
    </beansroperty>
    </beans:bean>
    </beans:constructor-arg>
    <beans:constructor-arg>
    <beans:bean class="org.springframework.security.ldap.populator .DefaultLdapAuthoritiesPopulator">
    <beans:constructor-arg ref="contextSource"/>
    <beans:constructor-arg value="${ldap.groupDn}"/>
    <beansroperty name="groupSearchFilter" value="(uniquemember=cn={1}*)"/>
    </beans:bean>
    </beans:constructor-arg>
    </beans:bean>

    </beans:beans>

  • #2
    Your LDAP server should be able to handle the password hashing transparently (it should support hashing itself). It's not something you should need to worry about with bind authentication.

    Comment


    • #3
      We too are looking to make the password less visible. Specifically, something like
      Code:
      <password-encoder hash="md5"/>
      In the below bean
      Code:
          <s:ldap-server
              id="ldapServer" 
              url="ldap://192.168.3.1:389"
              root="dc=myCo,dc=com"
              manager-dn="[email protected]"
              manager-password="somemd5hasString"
           >
           <password-encoder hash="md5"/>
           </s:ldap-server>
      Last edited by lessismore; Oct 2nd, 2008, 06:02 PM. Reason: changed code

      Comment


      • #4
        This doesn't make sense - if you hash the password before authenticating (and sending the password to the server), then the server won't know if you are using the correct password.

        Comment


        • #5
          Originally posted by Luke Taylor View Post
          This doesn't make sense - if you hash the password before authenticating (and sending the password to the server), then the server won't know if you are using the correct password.
          I am looking at doing something similar (I think) - feel free to correct me if I am wrong. The process as I envision implementing it:

          a) The client (a browser), hashes the password via JS (with a global salt value it knows). The password is then sent to the server.

          b) The server again hashes the password with a global salt it knows.

          c) Spring hashes the password with a reflection based salt before it persists the user or compares to a user retrieved from the datastore (in my case, a database).

          As long as the same steps are taken each time and the reflection based salt is not changed, then the hash for the password should be the same at the point of authentication (at least for Spring and a database)?

          Comment


          • #6
            What's the perceived value of hashing the password multiple times?

            Comment


            • #7
              Originally posted by Luke Taylor View Post
              What's the perceived value of hashing the password multiple times?
              Let's say you aren't using HTTPS, so you hash the password in the browser so that anybody listening between the browser and the server will have a harder time figuring out what the password is (although, if they are listening, they could learn the key when the page and hash logic with salt is sent to the browser - unless that is cached beforehand).

              So now when the password (hashed or not) gets to the server it is hashed again and then sent to the persistence layer which hashes it yet again with some unique value for the user (should be something that doesn't change - you could use a GUID stored in the user record).

              With known salts for the hash, the password is susceptible to discovery because you could compute the hash for a dictionary of words and then match it up with the hash. The more times you hash the password the more difficult it is to do this.

              With a password that is hashed in the client, then hashed in the servlet code, then hashed using some unique database value, an attacker either has to have access to all three salts, or their job is much harder. So if someone somehow compromises the database they still will have a hard time computing the password because there are two other salts for the hash - maybe even computed with different logic (say MD5 on the client and SHA on the server). The attacker has to compromise the database, the server code and the client - it just makes their job harder.

              I have seen some people suggest hashing the password multiple times in a loop with the previous hash value as the salt for the next hash. Not sure how valid that is though.

              Comment


              • #8
                Encrypting manager-password for ldap server config?

                Has anyone figured this out? We want to hash the manager-password in our configurations so that developers don't have access to the plaintext password. It's more of an internal audit issue than anything else.

                We do this with our datasource passwords in jboss and need the same functionality from within spring. I'm guessing that jboss does some sort of symmetric key encryption/decryption.

                Thanks,

                John

                Comment


                • #9
                  Originally posted by jp4 View Post
                  Has anyone figured this out? We want to hash the manager-password in our configurations so that developers don't have access to the plaintext password. It's more of an internal audit issue than anything else.

                  We do this with our datasource passwords in jboss and need the same functionality from within spring. I'm guessing that jboss does some sort of symmetric key encryption/decryption.

                  Thanks,

                  John
                  If you hash it in the client then nobody but the client sees the plaintext password.

                  Of course, devs, having access to the code, could add code somewhere along the line to store the hashed password after it is entered and then run a rainbow table lookup on it because they would know what the salt key is. Even if you hash it multiple places the developer would have access to those keys. They aren't going to see the plaintext password without running such an attack though, and at a certain point even someone with access to the code will have difficulty in retrieving a password without putting in an obvious hook into the password entry code in the client.

                  Security is best applied in layers.

                  At my last job even the devs didn't have access to certain 'keys' for the app. They put in replacement placeholders in config files that came from an 'escrow' that only operations (the people in charge of deployment and the data center) had access to, and only a few of them. When the app was deployed then those 'keys' were applied by the deployer. Another level of security.

                  Comment


                  • #10
                    Same issue here. I use the following context source:

                    Code:
                    	<beans:bean id="contextSource"
                    		class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
                    		<beans:constructor-arg
                    			value="ldap://server:389/something?sAMAccountName?sub?(objectClass=*)" />
                    		<beans:property name="userDn" value="username" />
                    		<beans:property name="password" value="plaintextpw" />
                    	</beans:bean>
                    and it would be absolutely necessary to add something to tell Spring and LDAP, that the password comes encrypted, so that I could change that line to something like:

                    Code:
                    <beans:property name="password" value="some_md5hashed_pw" />
                    Any help is highly appreciated. It shouldn't be necessary to put a plaintext passwords in the config file.

                    Thanks!

                    Comment


                    • #11
                      I already explained that this doesn't make sense.

                      Hashes like MD5 are irreversible - it is impossible to obtain the original value from the hash. Once you hash something the original information is lost. Therefore you cannot use a hash to authenticate to something which is expecting you to send the password (as in binding to an LDAP server). Spring Security (or anything else on the client side) has no way of obtaining the password from the hash.

                      If you want to hide configuration data in files, then you need to use *reversible* encryption (with a key). See this blog article for a description of Jasypt's support.

                      http://blog.jayway.com/2008/12/09/en...s-with-jasypt/

                      Comment


                      • #12
                        Originally posted by Luke Taylor View Post
                        I already explained that this doesn't make sense.

                        Hashes like MD5 are irreversible - it is impossible to obtain the original value from the hash. Once you hash something the original information is lost. Therefore you cannot use a hash to authenticate to something which is expecting you to send the password (as in binding to an LDAP server). Spring Security (or anything else on the client side) has no way of obtaining the password from the hash.

                        If you want to hide configuration data in files, then you need to use *reversible* encryption (with a key). See this blog article for a description of Jasypt's support.

                        http://blog.jayway.com/2008/12/09/en...s-with-jasypt/
                        I'm surprised by this.

                        Say you're storing user attributes in a database. You don't want to store a plain text password (or even reversible encryption)--anyone who gets access to that database table could then obtain every user's password. A more secure way to store passwords is to use a salted hash.

                        So to increase security in this scenario you can hash the password before authentication as discussed in this thread. This works by storing the hash *result* of the password in the database, rather than the plain text password-- thus no passwords are stored anywhere. For authentication the password given by the user goes through the hashing algorithm, and then is compared to the previously hashed value stored in the database. Since the algorithm always returns the same result given the same input, the patterns will match if the password is correct.

                        As a side note:
                        Whenever you visit a website and it is able to send you your password (as if a plain text password over non-encrypted email isn't bad enough...), it's cause for concern. The reason most secure websites require you to reset your password (cannot send you the actual pass) is probably because they are not storing your password at all, but a hash (not possible to verify for certain). But if you get a plain text password back in email--it's obvious they're storing the real password in some form and it's possible to retrieve it. (Reversible encryption could help here but still isn't as good.)


                        So anyway, is there a way of enabling this within Spring Security? We'd just need some way to pre-process the password before it's compared to the stored hash. Sorry to bring back an old thread but this is what I found when I looked...

                        Comment


                        • #13
                          Since this thread has gone all over the place with regards to topic, can you please clarify what you mean by "enabling this" - what do you mean by "this"?

                          Comment


                          • #14
                            "This" meaning the case I described above of storing password hashes. It may already be possible but I'm assuming not since nobody has said otherwise yet.

                            Instead of storing a recoverable password, we store (say) an MD5 hash of the password. To authenticate, re-hash the password provided by the user at the time of authentication (this is the part those in the thread seem to be having trouble with), comparing the original stored hash with the newly generated one.

                            Comment


                            • #15
                              I do notice a thread around now called "preAuthenticationProcessingFilter" - perhaps that's how to do this? (I'd imagine this is already possible, but just want to confirm and hear how.)

                              Comment

                              Working...
                              X