I've read a post here about password encoder, and saw this syntax:
passwordEncoder.isPasswordValid(user.password, params.password, null)
I already used this in my grails project which has bcrypt password encryption plug-in and it works well.
I'm just curious what's the third parameter for which has a null value?
thank you for sharing.
That's for passing in a salt if you use one.
Related
I am facing issue while creating/updating password in grails 3.x.x Application. Whenever i try to enter any special case lets say "#" it encodes only this special character in password field.
Password value is coming from request body.
Example:
Real password : abc#555
Auto Encoded password : abc%40555
Grails by default uses a plugin that uses bcrypt algorithm to hash passwords for security.There are some configurable password hashing attributes. You can customize the password plugin with the grails.plugin.springsecurity.password.algorithm attribute.
This is in the view
<g:passwordField name="password" required="" value="${usuarioInstance?.password}"/>
This would be a part of the controller
pass = params.password.encodeAsSHA1()
This will be returned into the view again
${pass.password}
the ${pass.password} needs to change to text or decode the SHA1()
My advice:
don't use sha-1, it's insecure
don't unencrypt a password and display it in a form field. Make the user type it in if they want to change it, if they haven't entered anything then don't update that property
use spring security which by default manages all the headaches of web security and uses Bcrypt out of the box.
Security is something every dev needs to take seriously and if the client insists on unsecure practices then they need to be educated.
Edit: #zaph makes a good point below so I should add it - don't encrypt passwords. A password should never be able to be translated back into plain text. Always hash (and salt) them and compare the user input hash to the stored hash. If you choose not to use Spring Security, you can use Bcrypt standalone and use the static Bcrypt.checkpw(userInputPw, hashedPw) method to check it.
Final Edit: To avoid any confusion (since #zaph seems confused in the comments) my recommendation is to use Bcrypt - specifically, use Spring Security.
In all of the reference pages I've found with regards to encrypting the ViewState, the only comment on the password is "your password here".
Are there any recommendations regarding the length / complexity of the password that we should use?
Depends on Mojarra version. It had several flaws/fails in earlier versions.
In Mojarra 1.2.x - 2.1.18, it was never actually used. The JNDI entry name was namely incorrectly documented. It was documented as com.sun.faces.ClientStateSavingPassword (with same prefix as Mojarra's other web.xml context parameters), but the code actually checks for ClientStateSavingPassword. You should then register it on that name instead.
<env-entry>
<env-entry-name>ClientStateSavingPassword</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>[Your Password]</env-entry-value>
</env-entry>
Otherwise, the client state is actually not encrypted.
In Mojarra 1.2.x - 2.0.3, the password will be used as a SecureRandom seed to generate a DES algorithm key. So, generally, the same rules apply as to "real world" passwords. Only, this can be easily compromised if the password is "too easy" and the attacker successfully guesses/bruteforces/figures the password.
In Mojarra 2.0.4 - 2.1.x, they changed the algorithm from DES to AES and the code now don't actually use the provided password anymore to generate the key (to prevent potential comprisions). Instead, a completely random key is generated, which is more safe. The JNDI entry now basically controls whether the client state should be encrypted or not. In other words, it behaves now like a boolean configuration entry. It thus absolutely doesn't matter anymore which password you use.
<env-entry>
<env-entry-name>ClientStateSavingPassword</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>[Any value is interpreted as boolean=true to enable encryption]</env-entry-value>
</env-entry>
In Mojarra 2.1.19 - 2.1.x, they fixed the code to align the documentation on JNDI entry name. So you could use the documented JNDI entry name:
<env-entry>
<env-entry-name>com.sun.faces.ClientStateSavingPassword</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>[Any value is interpreted as boolean=true to enable encryption]</env-entry-value>
</env-entry>
However, this still doesn't affect the AES key, which was changed since 2.0.4, it still basically only enables/disables the encryption.
In Mojarra 2.2.0 - 2.3.x, as part of JSF 2.2 specification (chapter 7.8.2), client side state is now by default always encrypted. It will only be disabled when web.xml context parameter com.sun.faces.disableClientStateEncryption is set with value true. It still uses AES algorithm with a completely random key. The JNDI entry com.sun.faces.ClientStateSavingPassword is now not used anymore.
In Mojarra 2.2.6 - 2.3.x, they added as per issue 3087 a new JNDI entry which allows you to specify the AES key in Base64 encoded format, the jsf/ClientSideSecretKey. This is part of the bugfix on failing client side state when a JSF webapp is used in cluster environment, because each server used a different AES key which would only cause a ERROR: MAC did not verify! when state is restored in a different server than the one which saved the state, as described in issue 2557.
<env-entry>
<env-entry-name>jsf/ClientSideSecretKey</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>[AES key in Base64 format]</env-entry-value>
</env-entry>
You can use this AES key generator to generate one (refresh the page to regenerate), or use below snippet to generate your own Base64-encoded AES256 key:
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256); // Use 128 for AES128 (when server don't have JCE installed).
String key = Base64.getEncoder().encodeToString(keyGen.generateKey().getEncoded());
System.out.println(key); // Prints AES key in Base64 format.
I use the excellent JASYPT plugin to encrypt and decrypt certain database columns. Works great. But I have a usecase for encryption/decryption for simple Strings that are not going to the database and I'd love to use my already set up Jasypt configuration with my secret and the digest to do it rather than bring in another plugin or crypto configuration, but it seems the documentation only show how use it for GORM and domain classes.
https://bitbucket.org/tednaleid/grails-jasypt/wiki/Home
Ideally I'd keep things really simple like this
String encrypted = myJasyptConfig().encrypt(myString)
//then later
String decrypted = myJasyptConfig().decrypt(encrypted)
Possible?
The plugin has jasypt dependencies and they are exported to app (plugin dependencies are transitively available to the app by default).
I think you can use the StandardPBEStringEncryptor as is based on your config.
Add the below method as an action in a sample controller (inject grailsApplication) of your app and hit it.
def standard(){
def jasyptConfig = grailsApplication.config.jasypt
org.jasypt.encryption.pbe.StandardPBEStringEncryptor stringEncryptor =
new org.jasypt.encryption.pbe.StandardPBEStringEncryptor(jasyptConfig)
def encrypted = stringEncryptor.encrypt("Hello World")
def decrypted = stringEncryptor.decrypt(encrypted)
render([encrypted: encrypted, decrypted: decrypted] as JSON)
}
or just run the above method in grails console.
I am wanting to validate a password in my own controller.
Is there any way I can sent the password to spring security UI and get a return if the password validates?
You are looking for:
springSecurityService.encodePassword
If you have configured your system with salt you will need that as well. Just encode the String, and read the encoded String from your user object, and compare the two
Docs:
http://grails-plugins.github.com/grails-spring-security-core/docs/manual/guide/single.html#6.2%20SpringSecurityService