The cryptography package contains what is referred to as recipes
for symmetric encryption enhancement materials,
which are the low‑level primitives, but we will not get into that today.
The package also allows you to get your hands into the X.509 standard,
which we see a lot of in TLS certificates.
As usual,
I am providing you a few links with the full documentation in the library.
Cryptography is one of those fields you either get it or you don't,
and if you don't, I wouldn't suggest just figuring it out as you go.
Sit down with the documents provided and really
understand what the library is capable of.
Crypto is the last thing you want to try to roll on your own.
In this course,
we're going to talk about the fernet symmetric encryption
provided in the cryptography library,
which guarantees that a message encrypted using it cannot
be manipulated or read without the key.
And we'll talk about the scrypt key derivation function that can be
used for encrypting file and application passwords.
A scrypt is available as a primitive inside the cryptography library.
The fernet module contains a Fernet class,
and yes, capitalization is important here.
When we get into this demo, I will show you how this all relates.
The module also includes a key generator.
In symmetric encryption, the same key is used for both encrypting and decrypting,
so managing this key is important.
The Fernet class, when assigned to a variable using the generated key,
is then able to encrypt and decrypt a binary.
To visually understand this,
the fernet module has a Fernet class that can be assigned to
a variable by using the generate_key function built into the
class to set a unique key.
Once assigned,
you are able to encrypt or decrypt any binary set in
the parameter of the function.
Now scrypt, which comes from the same cryptography library,
is buried in the hazmat primitives under the key derivation functions.
Similar to fernet,
scrypt is a function under the scrypt module, and instead of
additional functions, this lists all of the parameters.
Scrypt is a little less complicated, but the Scrypt class does
require a few additional parameters to develop the key.
This is because it was built to be attack resistant.
Salt is a random string added to the password to prevent hashed passwords
from matching up in the event that two users set the same password. Length
is the desired length of the key that is derived from the function. N is the
CPU impact that slows the attack down.
This should be set to a power of 2.
R and p control the block size and parallelization accordingly and I read is
generally recommended to be set to 8 and 1, respectively.
All right, in this demo for cryptography, we're going to take a
look at both the implementation of fernet, which is an example of
symmetric encryption cryptography, and scrypt, which is a
password‑based key derivation function.
The cryptography library is a third‑party library which requires you to run the
pip install in cryptography, which will give you the ability to import the
Fernet class out of the cryptography.fernet package.
Class method, now available to you, is to generate_key, which
generates a fresh fernet key every time called.
You can then take this key,
drop it into the class, and assign that class to the variable.
Once the class is assigned, that variable now has two functions available to it,
encryption and decryption.
So I'm taking my message, encrypting it with the key generated,
and printing the result. And on the next line, I'm decrypting
that result using the variable that contains the key to get back
to the original message.
Taking a look at this in action, when I run it, you'll see
I now have printed the key generated,
displayed the scrambled message, and then back to
the original unencrypted message.
Now in the real world, you would want to pull out the generated key and store
that securely with the person you are trading messages with.
That will be the only key that can possibly be imported into fernet and used to
encrypt and decrypt the same message. Scrypt is a key derivation function
designed for password storage, which will slow down an attack by tuning the
memory. The class comes with a set of parameters.
Salt is used to extend the password. This way, if any two people happen to
set the same password, the resulting hash will not be identical. A salt
should be unique to the individual, but can be stored in plaintext, just
not something you want to necessarily share with the public. Length is the
desired length of the resulting key. N is the CPU or memory cost that will
be a power of 2.
R is the block size that is recommended to be set to 8. And p is the
parallelization and is recommended to be set to 1.
So once the class is assigned to the variable,
I will then derive the key of the password provided.
Once I store the key securely in my database,
I can then make a call later using the same parameter of the
Scrypt class, including the same salt, provide the password,
and verify the keys match.
The verify function is used to raise an exception.
If no exception is raised, it will simply return
none, meaning the passwords match.
So let's check this out.
So now that I've run this, I see the key that was derived.
I also see that there is no password exceptions.
That means my passwords match.
But what happens when they don't match?
Going back to the code, if the passwords do not match, for example I left
the exclamation point off the end here, I now run it again and I see the
Keys do not match exception has been raised.