28 Replies Latest reply on Oct 19, 2010 11:05 AM by Steve Sommers

    Encrypt / Decrypt help

    WolfShade Level 4
      Hello, all.

      In the past, I always used HASH to encrypt the password for users; all I needed to do was to check the HASHed value from login and compare to what is in the db - simple.

      Now I have a client that would like to add a password retrieval system to the site. I'm having difficulties with the values never being the same. Originally I tried encrypting with BLOWFISH, but that didn't work for decrypt. Here is the code I have, so far:
      APPLICATION.CFM:
      <cfset request.cryptAlgorithm = "DESEDE">
      <cfset request.cryptEncoding = "HEX">
      <cfset request.cryptKey = GenerateSecretKey(request.cryptAlgorithm)>
      <cfset request.cryptPhrase = "Eightcha">

      LOGINACTION.CFM
      <cfset session.user.password = URLEncodedFormat(Encrypt("#trim(form.password)#", request.cryptKey, request.cryptAlgorithm)) />
      <cfset session.user.SQLpassword = trim(replace(session.user.password,"'","''","all")) />
      <cfquery name="checkLogin" dbtype="odbc" datasource="#request.data_source#">
      EXEC check_login @un='#trim(session.user.username)#', @pw='#trim(session.user.SQLpassword)#'
      </cfquery>
      <cfdump var="#checkLogin#"><cfabort>

      I'm dumping the results of the query and aborting to view the values; the password is always changing. How can I keep the value always the same?

      Thanks,

      ^_^

        • 1. Re: Encrypt / Decrypt help
          dacf
          Have you tried it without the URLEncodedFormat around form,password?

          It doesn't seem necessary if the 'password' is coming from the form scope, and will actually change a string if the password contains certain characters, see the attached code (CF8).

          Also, is the database doing any sort of encrypt/decrypt functionality? If so, might want to check if the two match up in a kind of similar way to the code attached.

          • 2. Re: Encrypt / Decrypt help
            WolfShade Level 4
            I've tried it both with and without the URLEncodedFormat(); with and without defining the algorithm, the encoding; the same result every time - every click of the submit button dumps the query result (including the query, itself) and shows that the encrypted password value is never the same, twice. I'll include three results, here:

            #1
            EXEC check_login @un='administrator', @pw='0JD%2FDM%5C%3EH%25H%3AQ%20BI%5C%3CN3%3F%20P%20%20%0A'

            #2
            EXEC check_login @un='administrator', @pw='02M%3A%27NC%5BGH%3D75CSV%25VHF%2FBP%20%20%0A'

            #3
            EXEC check_login @un='administrator', @pw='0J%3D%2DDGS%3A%25%2C%21DR%3A%21%27O%2CWU4%3B%40%20%20%0A'

            Now without the URLEncodedFormat():

            #1
            EXEC check_login @un='administrator', @pw='0E Y,/@2L^K"^ZGA(W00W@@'

            #2
            EXEC check_login @un='administrator', @pw='0F@;IP0''7K<I6,1?*I,MS/@'

            #3
            EXEC check_login @un='administrator', @pw='0/%EVXY@T&Y0?Y_7O#@YXG@'

            If you are familiar with proper encrypt/decrypt usage, could you please post some sample code? I tried following the example in livedocs and that isn't working, either.

            Thanks,

            ^_^
            • 3. Encrypt / Decrypt help
              cf_dev2 Level 1
              <cfset request.cryptKey = GenerateSecretKey(request.cryptAlgorithm)>

              It looks like the secretKey is changing on every request. When the key changes, the encrypted value changes. To get the same encrypted value you must use the same key.
              • 4. Re: Encrypt / Decrypt help
                WolfShade Level 4
                quote:

                Originally posted by: cf_dev2
                <cfset request.cryptKey = GenerateSecretKey(request.cryptAlgorithm)>

                It looks like the secretKey is changing on every request. When the key changes, the encrypted value changes. To get the same encrypted value you must use the same key.

                That's what I thought. Originally I had used
                quote:

                Encrypt("#form.password#","8charkey","BLOWFISH")
                to encrypt, but couldn't get it to DEcrypt from that. Kept getting an error that the input and output do not match. Do you know how to decrypt from the above encrypt?

                ^_^
                • 5. Re: Encrypt / Decrypt help
                  cf_dev2 Level 1
                  Same concept. But again decrypt won't work if you're not using the same key that was used to encrypt the string.

                  <cfset cryptAlgorithm = "BLOWFISH">
                  <cfset cryptKey = GenerateSecretKey(cryptAlgorithm)>
                  <cfset form.password = "mypassword">

                  <cfset encryptedPassword = Encrypt(form.password, cryptKey, cryptAlgorithm)>
                  <cfset decryptedPassword = Decrypt(encryptedPassword, cryptKey, cryptAlgorithm)>

                  <cfoutput>
                  Form.Password = #form.password#<hr>
                  Encrypted = #encryptedPassword#<hr>
                  Decrypted = #decryptedPassword#<hr>
                  </cfoutput>
                  • 6. Encrypt / Decrypt help
                    WolfShade Level 4
                    Could it be server related? MS Windows Server 2003 and CF8.

                    OR could trim() be affecting this?

                    application.cfm

                    <cfset request.cryptAlgorithm = "BLOWFISH">
                    <cfset request.cryptKey = GenerateSecretKey(request.cryptAlgorithm)>


                    loginaction.cfm

                    <cfset session.user.username = trim(form.username) />
                    <cfset session.user.password = Encrypt(trim(form.password), request.cryptKey, request.cryptAlgorithm) />
                    <cfset session.user.SQLpassword = session.user.password />
                    <cfquery name="checkLogin" dbtype="odbc" datasource="#request.data_source#">
                    EXEC check_login @un='#session.user.username#', @pw='#trim(session.user.SQLpassword)#'
                    </cfquery>
                    <cfdump var="#checkLogin#"><cfabort>

                    I'm still getting the same result; different output each time.

                    @pw='08!4[BP%=M!</[JW)/TF! P'

                    @pw='0C4X\TE.DZKG62]?''F-7ZD@'

                    @pw='0P8%&LU##?L:%Q("7Q4M2.@'

                    ?
                    ^_^
                    • 7. Re: Encrypt / Decrypt help
                      cf_dev2 Level 1
                      > I'm still getting the same result; different output each time.

                      You're still changing the secretKey on every request. Different key == different encrypted string.

                      • 8. Re: Encrypt / Decrypt help
                        cf_dev2 Level 1
                        Btw, I have no idea what your stored procedure is doing :)
                        • 9. Encrypt / Decrypt help
                          WolfShade Level 4
                          So GenerateSecretKey() gives a different output each time it's run. Do I *have* to use GenerateSecretKey() in order to decrypt?

                          I get the following when trying to decrypt:
                          An error occurred while trying to encrypt or decrypt your input string: The input and output encodings are not same..

                          ^_^
                          • 10. Encrypt / Decrypt help
                            cf_dev2 Level 1
                            > So GenerateSecretKey() gives a different output each time it's run.

                            Yes

                            > Do I *have* to use GenerateSecretKey() in order to decrypt?

                            When you a key to Encrypt(), then yes you must use that same key to Decrypt(). Note, that doesn't mean calling GenerateSecretKey() inside Decrypt(). It means saving the key value and passing the saved key to Decrypt().
                            • 11. Re: Encrypt / Decrypt help
                              cf_dev2 Level 1
                              > You don't have to use a key at all.

                              Scratch that. If you don't use a key I think it will default to CFMX_COMPAT, which is not what you want.
                              • 12. Re: Encrypt / Decrypt help
                                WolfShade Level 4
                                I have NO idea what just happened. The first time I tried encrypting and decrypting without using GenerateSecretKey() it errored. Now it's not.

                                %^/

                                I'm not going to question it. I'm just going to accept it. I will keep telling myself, "It doesn't matter, it works. It doesn't matter, it works."

                                Thanks for your help. Feel bad about wasting your time, like that.

                                ^_^
                                • 13. Encrypt / Decrypt help
                                  cf_dev2 Level 1
                                  No. See my last comment. If you don't use a key I think CF uses CFMX_COMPAT which is not the same as BLOWFISH.
                                  • 14. Re: Encrypt / Decrypt help
                                    WolfShade Level 4
                                    That's just it. I am using a key, and using BLOWFISH. Why it's working, now, I don't know; but it wasn't, before.

                                    application.cfm
                                    <cfset request.cryptAlgorithm = "BLOWFISH" />
                                    <cfset request.cryptKey = "16characterskey1" />

                                    loginaction.cfm
                                    <cfset session.user.username = trim(form.username) />
                                    <cfset session.user.password = Encrypt(trim(form.password), request.cryptKey, request.cryptAlgorithm) />
                                    <cfset session.user.SQLpassword = session.user.password />
                                    <cfquery name="checkLogin" dbtype="odbc" datasource="#request.data_source#">
                                    EXEC check_login @un='#session.user.username#', @pw='#trim(session.user.SQLpassword)#'
                                    </cfquery>
                                    <cfoutput>password is #Decrypt(session.user.SQLpassword, request.cryptKey, request.cryptAlgorithm)#</cfoutput>
                                    <cfdump var="#checkLogin#"><cfabort>

                                    I'm stumped, but not questioning it. It is working, now. (shrug) Without GenerateSecretKey().

                                    Thanks,

                                    ^_^
                                    • 15. Encrypt / Decrypt help
                                      WolfShade Level 4
                                      Okay.. I spoke too soon. It works ON THAT PAGE. As soon as I attempt to decrypt on another page after pulling the password from the database, it errors.

                                      An error occurred while trying to encrypt or decrypt your input string: The input and output encodings are not same..

                                      <cfoutput>Password for this account is #Decrypt(getAdmin.userPW, request.cryptKey, request.cryptAlgorithm)#</cfoutput>

                                      AFAIK, the database isn't changing anything and the datatype is nvarchar(100). Any idea as to what I'm missing, this time?

                                      ^_^

                                      PS. This is CF8. I don't need to escape the apostrophe for a stored procedure, anymore, do I? Could that be it?

                                      Nope.. that's not it.. I forgot I already removed that from the code.
                                      • 16. Re: Encrypt / Decrypt help
                                        cf_dev2 Level 1
                                        First I would recommend creating an example that strips the code to its simplest form (ie. no trim(), urlencodedformat(), etc.) Just to ensure you haven't inadvertently changed the values somehow.

                                        Next, what about dacf's suggestion? Did you output the two values and see if they're different? ie. output the encrypted CF string and the string from your database query.

                                        • 17. Re: Encrypt / Decrypt help
                                          WolfShade Level 4
                                          Okay.. here's what I've got, currently:
                                          STORED PROCEDURE:
                                          CREATE PROCEDURE dbo.check_login
                                          @un nvarchar(50),
                                          @pw nvarchar(100)
                                          AS

                                          DECLARE @statusCode int
                                          SET @statusCode='0'
                                          IF EXISTS (
                                          SELECT [adminID]
                                          FROM [cpwr_org_01].[dbo].[cpwr_admin_users]
                                          WHERE [userName] = @un AND [userPW] = @pw
                                          )
                                          BEGIN
                                          SET @statusCode='1'

                                          SELECT [adminID], [firstName], [lastName], [userName], [userLevel], [datecreated], [lastLogin], [isActive], @statusCode as statusCode, [userPW]
                                          FROM [cpwr_org_01].[dbo].[cpwr_admin_users]
                                          WHERE [userName] = @un AND [userPW] = @pw AND [isActive] = 1
                                          END
                                          ELSE
                                          BEGIN
                                          SELECT @statusCode as statusCode
                                          END

                                          IF (@statusCode = '1')
                                          BEGIN

                                          UPDATE [cpwr_org_01].[dbo].[cpwr_admin_users]
                                          SET [lastLogin] = getdate()
                                          WHERE [userName] = @un AND [userPW] = @pw

                                          END
                                          GO

                                          APPLICATION.CFM
                                          <cfset request.cryptAlgorithm = "BLOWFISH" />
                                          <cfset request.cryptKey = "8charkey" />

                                          LOGINACTION.CFM
                                          <cfset session.user.username = trim(form.username) />
                                          <cfset session.user.password = Encrypt(trim(form.password), request.cryptKey, request.cryptAlgorithm) />
                                          <cfset session.user.SQLpassword = session.user.password />
                                          <cfquery name="checkLogin" dbtype="odbc" datasource="#request.data_source#">
                                          EXEC cpwr_adm_check_login @un='#session.user.username#', @pw='#trim(session.user.SQLpassword)#'
                                          </cfquery>
                                          direct encrypted pw is <cfdump var="#session.user.SQLpassword#"><br>
                                          db retrieved pw is <cfdump var="#checkLogin.userPW#">

                                          This is what displays when I run the page:
                                          direct encrypted pw is 0L42&E!R11!?XN3Z#X#$J;
                                          db retrieved pw is 0L42&E!R11!?XN3Z#X#$J;

                                          According to this, they are identical. But when I run the other page that attempts to decrypt, I get this:
                                          An error occurred while trying to encrypt or decrypt your input string: The input and output encodings are not same..
                                          72: Password for this account is #Decrypt(getAdmin.userPW, request.cryptKey, request.cryptAlgorithm)#

                                          STORED PROCEDURE:
                                          CREATE PROCEDURE dbo.get_admin_edit
                                          @adminID int
                                          AS

                                          SELECT [adminID], [firstName], [lastName], [userName], [userPW], [userLevel], [datecreated], [lastLogin], [isActive], [userEmail]
                                          FROM [cpwr_org_01].[dbo].[cpwr_admin_users]
                                          WHERE adminID = @adminID
                                          GO

                                          EDIT PAGE:
                                          Password for this account is #Decrypt(getAdmin.userPW, request.cryptKey, request.cryptAlgorithm)#

                                          ^_^
                                          • 18. Encrypt / Decrypt help
                                            cf_dev2 Level 1
                                            > strips the code to its simplest form (ie. no trim(), urlencodedformat(), etc
                                            > @pw='#trim(session.user.SQLpassword)#'

                                            It looks like you've still got some excess code in there (ie trim() calls) and I think that's what's messing you up. Try removing the trim() calls.

                                            Generally speaking, once you encrypt the value, you don't want to change the encrypted string in any way because encrypt/decrypt are extremely sensitive.

                                            > According to this, they are identical.
                                            Looks can be deceiving ;) You can always use compare() to verify that two strings actually are identical.

                                            Btw, why are you using CFQUERY to run your stored procedures instead of CFSTOREDPROC?
                                            • 19. Encrypt / Decrypt help
                                              WolfShade Level 4
                                              CFQ vs CFSP - (shrug) Habit, really, I guess. When I first started learning CF in 2000, I just used CFQ and never got around to using CFSP.

                                              I'll remove the trim(), but I'm paranoid about that. I've always trimmed the strings prior to db insert; and I always use trim() when displaying. I've had too many times where a comparison didn't match because of a lack of trim().

                                              I'll also try the compare to see if there is any difference. Thanks for the idea.

                                              WITHOUT the trim, the query is adding a space to the end of the encrypted string. I didn't think blank spaces were valid encryption code.
                                              • 20. Re: Encrypt / Decrypt help
                                                cf_dev2 Level 1
                                                Ah, okay.

                                                Yes, I agree with you that values should be trimmed. But assuming you've used Encrypt(trim(form.password),...) there's no need to use trim() again on the encrypted string. Its probably changing the value.

                                                • 21. Re: Encrypt / Decrypt help
                                                  WolfShade Level 4
                                                  Without trim(), it's throwing a blank space on the end of the encrypted password being submitted by the form. Even if I add the " " to the end of the password in the database, it still comes back as user doesn't exist. Since the user doesn't exist, it's not returning the password for compare() to check. :(

                                                  ^_^
                                                  • 22. Re: Encrypt / Decrypt help
                                                    cf_dev2 Level 1
                                                    I don't know if its a literal space but if that's how the value is encrypted, its fine. Just leave the string as is. Decrypt will handle it. In other words, once you've called encrypt() don't change the value in any way. I tried a quick test and it worked fine for me, so I suspect trim() might be the source of the problem.

                                                    • 23. Re: Encrypt / Decrypt help
                                                      WolfShade Level 4
                                                      But I have removed the trim() from anywhere outside the Encrypt() tag for password.

                                                      <cfset session.user.username = trim(form.username) />
                                                      <cfset session.user.password = Encrypt(trim(form.password), request.cryptKey, request.cryptAlgorithm) />
                                                      <cfset session.user.SQLpassword = session.user.password />
                                                      <cfquery name="checkLogin" dbtype="odbc" datasource="#request.data_source#">
                                                      EXEC cpwr_adm_check_login @un='#session.user.username#', @pw='#session.user.password#'
                                                      </cfquery>
                                                      <cfdump var="#checkLogin#">
                                                      direct encrypted pw is <cfdump var="#session.user.SQLpassword#"><br>
                                                      db retrieved pw is <cfdump var="#checkLogin.userPW#"> <-- Error here, no records returned because no match
                                                      <cfoutput>
                                                      direct password is #Decrypt(session.user.SQLpassword, request.cryptKey, request.cryptAlgorithm)#
                                                      database password is #Decrypt(checkLogin.userPW, request.cryptKey, request.cryptAlgorithm)#
                                                      Comparison = #compare(session.user.SQLpassword,checkLogin.userPW)#

                                                      ^_^
                                                      • 24. Re: Encrypt / Decrypt help
                                                        cf_dev2 Level 1
                                                        What about when the password is first inserted? Try it with a completely new password.

                                                        In my tests it seems to be working fine every time. So maybe the existing values were stored incorrectly?

                                                        • 25. Re: Encrypt / Decrypt help
                                                          WolfShade Level 4
                                                          Och. That will take some time. I haven't created the user add/edit form, yet. :( And I've got other things that have to be finished by tomorrow morning.

                                                          I'll get that done ASAP afterwards, though, and let you know if that made any difference.

                                                          Thanks, again, for your thoughts and advice.

                                                          ^_^
                                                          • 26. Encrypt / Decrypt help
                                                            cf_dev2 Level 1
                                                            Okay. I'll check back later on to see how you made out.

                                                            Good luck! :)
                                                            • 27. Re: Encrypt / Decrypt help
                                                              mowebdev2

                                                              I came across this error in trying to use encrypt with the BLOWFISH alg using a static key of something like:

                                                               

                                                              <cfset thekey = "mysecretkey"> - this does not work.

                                                               

                                                              <cfset thekey = "mysecretkey2010s"> - this works at a length of 16 characters.  Anything less than 16 did not work.  Neither did 17, 18, or 19.  20 did.

                                                               

                                                              Hope this is helpful to some in the future.

                                                              • 28. Re: Encrypt / Decrypt help
                                                                Steve Sommers Level 4

                                                                I'm fairly certain that "theKey" is interpreted as a base-64 encoded binary value and that is why it must have a length evenly divisable by 4.