password_key¶
-
static
EncryptHelper.
password_key
(password, salt=None, kdf: Type[cryptography.hazmat.primitives.kdf.KeyDerivationFunction] = <class 'cryptography.hazmat.primitives.kdf.pbkdf2.PBKDF2HMAC'>, **kwargs) → Tuple[str, dict][source]¶ Generate a
cryptography.fernet.Fernet
key based on a password and salt. Key derivation is customisable.- Parameters
password – A password to generate the key from, as
str
orbytes
salt – The salt to use when generating the key, as
str
orbytes
Ifsalt
is a string, it can also be passed in base64 format.
Standard Usage with manual salt:
Call
password_key
with a password of your choice, and a salt of your choice (ideally at least 16 chars), and a tuple containing the Fernet key (base64 encoded), and key derivative configuration will be returned.>>> ek = EncryptHelper >>> key, kd = ek.password_key('MySecurePass', salt=b'Sup3rseCr3tsalt') >>> key 'rJ_g-lBT7pxeu4MVrhfi5rAv9yLbX5pTm6vkJj_Mezc=' >>> kd {'length': 32, 'salt': 'U3VwM3JzZUNyM3RzYWx0', 'backend': <...Backend object at 0x7fd1c0220eb8>, 'algorithm': <...SHA256 object at 0x7fd1b0232278>, 'iterations': 100000, 'kdf': <class '...PBKDF2HMAC'>}
You can see when we call the method a second time with the same password and salt, we get the same Fernet key.
>>> key, kd = ek.password_key('MySecurePass', salt=b'Sup3rseCr3tsalt') >>> key 'rJ_g-lBT7pxeu4MVrhfi5rAv9yLbX5pTm6vkJj_Mezc='
Now we can simply initialise the class with this key, and start encrypting/decrypting data:
>>> enc = EncryptHelper(key) >>> mydata = enc.encrypt_str('hello') >>> mydata 'gAAAAABdsJrpZvQAhAEwAGk2GPeJMUjUdp1FHAg42ncArvvQjqGztLslgexF7dKWbJ8bhYNt9MBzzT0WR_XEvl1j5Q95UOVTsQ==' >>> enc.decrypt_str(mydata) 'hello'
Automatic salt generation:
While it’s strongly recommend that you pass your own
salt
(at least 16 bytes recommended), for convenience this method will automatically generate a 16 byte salt and return it as part of the dict (second tuple item) returned.First, we generate a key from the password
helloworld
>>> ek = EncryptHelper >>> key, kd = ek.password_key('helloworld') >>> key '6asAQ0qTQtmjw54RBR_RVmwsyv6EgTY_lcnVgJAVKCQ=' >>> kd {'length': 32, 'salt': 'bDU5MzJaaEhnZ1htSmlQeg==', 'backend': <...Backend object at 0x7ff968053860>, 'algorithm': <...SHA256 object at 0x7ff9685f6160>, 'iterations': 100000, 'kdf': <class '...PBKDF2HMAC'>}
If we call password_key again with
helloworld
, you’ll notice it outputs a completely different key. This is because no salt was specified, so it simply generated yet another salt.>>> ek.password_key('helloworld')[0] 'BfesIzfEPodtHSyPrpnkK0iDipHikaE7T1uuFFPnqmc='
To actually get the same Fernet key back, we have to either:
Pass the entire
kd
dictionary as kwargs (safest option, contains all params used for generation)>>> ek.password_key('helloworld', **kd)[0] '6asAQ0qTQtmjw54RBR_RVmwsyv6EgTY_lcnVgJAVKCQ='
Pass the generated salt from the
kd
object, alongside our password.>>> ek.password_key('helloworld', salt=kd['salt'])[0] '6asAQ0qTQtmjw54RBR_RVmwsyv6EgTY_lcnVgJAVKCQ='