Masonite comes with bcrypt out of the box but leaves it up to the developer to actually encrypt things like passwords. You can opt to use any other hashing library but bcrypt is the standard of a lot of libraries and comes with some one way hashing algorithms with no known vulnerabilities. Many of hashing algorithms like SHA-1 and MD5 are not secure and you should not use them in your application.
Other frameworks use cryptographic signing which attaches a special key to your cookies that prevents manipulation. This does't make sense as a major part of XSS protection is preventing third parties from reading cookies. It doesn't make sense to attach a digital signature to a plaintext cookie if you don't want third parties to see the cookie (such as a session id). Masonite takes this one step further and encrypts the entire string and can only be decrypted using your secret key (so make sure you keep it secret!).
.env file, you will find a setting called
KEY=your-secret-key. This is the SALT that is used to encrypt and decrypt your cookies. It is important to change this key sometime before development. You can generate new secret keys by running:
$ python craft key
This will generate a new key in your terminal which you can copy and paste into your
.env file. Your
config/application.py file uses this environment variable to set the
KEY configuration setting.
Additionally you can pass the
--store flag which will automatically set the
KEY= value in your
.env file for you:
$ python craft key --store
You can use the same cryptographic signing that Masonite uses to encrypt cookies on any data you want. Just import the
masonite.sign.Sign class. A complete signing will look something like:
from masonite.auth import Signsign = Sign()signed = sign.sign('value') # PSJDUudbs87SB....sign.unsign(signed) # 'value'
Sign() uses the encryption key in your
config/application.py file but you could also pass in your own key.
from masonite.auth import Signencryption_key = b'SJS(839dhs...'sign = Sign(encryption_key)signed = sign.sign('value') # PSJDUudbs87SB....sign.unsign(signed) # 'value'
This feature uses pyca/cryptography for this kind of encryption. Because of this, we can generate keys using Fernet.
from masonite.auth import Signfrom cryptography.fernet import Fernetencryption_key = Fernet.generate_key()sign = Sign(encryption_key)signed = sign.sign('value') # PSJDUudbs87SB....sign.unsign(signed) # 'value'
Just remember to store the key you generated or you will not be able to decrypt any values that you encrypted in the first place.
Bcrypt is very easy to use and basically consists of a 1 way hash, and then a check to verify if that 1 way hash matches an input given to it.
Again, all values passed into bcrypt need to be in bytes so we can pass in a password using the password helper function:
from masonite.helpers import passwordencrypted_password = password('secret')
Notice that the value passed in from the request was converted into bytes using the
bytes() Python function.
Once the password is hashed, we can just safely store it into our database
In order to check if a password matches it's hashed form, such as trying to login a user, we can use the
bcrypt.checkpw(bytes('password', 'utf-8'), bytes(model.password, 'utf-8'))
This will return true if the string
'password' is equal to the models password.
More information on bcrypt can be found by reading it's documentation.