python-3.xencryptionpython-cryptographyfernet

Which encryption password does cryptography.fernet uses?


I am making a program which encrypts and decrypts texts. I am using Python 3.7 and cryptography.fernet library. I want to enter some information about my program's encryption standard to the GitHub page but I didn't understand which encryption does Fernet uses.

Here is my sample code which I am used in my project. I want to encrypt with 256-bit (AES-256) key but the key which this code generates is longer than 32 characters. It's 44 characters. But in official web site of cryptography library it says this code generates 128-bit key. What is the name of this 44 character (352-bit) key? Or is there any way for 256-bit symmetric encryption without PyCrypto?

from cryptography.fernet import Fernet
import base64
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC

textEncrypt = "Secret Data"
password = "Password"
salt = os.urandom(16)
kdf = PBKDF2HMAC(algorithm=hashes.SHA256(),length=32,salt=salt,iterations=100000)
key = base64.urlsafe_b64encode(kdf.derive(password))
fernet = Fernet(key)
encryptedText = fernet.encrypt(textEncrypt.encode())

Here is the key which this code generates: aAT_LESBw_ZGlPA52cj4zQd6jBdx6gk5RmQWbpLY7e0=


Solution

  • It is well written in the documentation;

    Implementation

    Fernet is built on top of a number of standard cryptographic primitives. Specifically it uses:

    • AES in CBC mode with a 128-bit key for encryption; using PKCS7 padding.
    • HMAC using SHA256 for authentication.
    • Initialization vectors are generated using os.urandom().

    For complete details consult the specification.

    Therefore you cannot use AES-256 with Fernet

    PyCrypto can use a wide range of mode of operations for AES-256 including CBC, CTR, GCM, SIV, and OCB


    Not clear how you get 44 bytes, here is the way to get the 32-bytes;

    from cryptography.fernet import Fernet
    from cryptography.hazmat.primitives import hashes
    from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
    import base64
    import os
    
    
    textEncrypt = "Secret Data"
    password = "Password"
    salt = os.urandom(16)
    kdf = PBKDF2HMAC(algorithm=hashes.SHA256(),length=32,salt=salt,iterations=100000)
    
    key = kdf.derive(str.encode(password))
    print(len(key))
    print(key)
    

    and outputs

    32
    b'K\xf6\x10a\xd6B`\x8a\x83\x13\xc2\xcfOJ\xcb\x02k$~\xf7v\x01\x80\xd0\xda\x93!\xaf\xa9B\x94\xfe'