Python fernet generate key

Fernet system for symmetric encryption

This article is part of a series on the Python cryptography library.

Refer to the glossary of cryptography terms for definitions of any terms used in this chapter.

Overview of Fernet

Fernet is a system for symmetric encryption/decryption, using current best practices. It also authenticates the message, which measm that the recipient can tell if the message has been altered in any way from what was originally sent.

Fernet overcomes many of the problems obvious mistakes a naive developer might make when designing such a system by:

  • Providing a secure mechanism for generating keys (a key is similar to a password).
  • Selection a secure encryption algorithm (AES using CBS mode and PKCS7 padding)
  • Randomly allocating a secure «salt» value IV) to make the encryption more secure.
  • Timestamping the encrypted message.
  • Signing the message (using HMAC and SHA256) to detect any attempts to change it.

We will look at the hows and whys of these features later in this article.

Using Fernet

Fernet is included in the cryptography library.

To encrypt and decrypt data, we will need a secret key that must be shared between anyone who needs to encrypt or decrypt data. It must be kept secret from anyone else, because anyone who knows the key can read and create encrypted messages. This means we will need a secure mechanism to share the key. The same key can used multiple times.

Читайте также:  Где пишут php коды

Creating a key

We can create a key like this:

from cryptography.fernet import Fernet import base64 key = Fernet.generate_key() 

The key is a random value, and will be completely different each time you call the generate_key function.

Encrypting a message

To encrypt a message, we must first create a Fernet object using the key created previously. We than call the encrypt function, passing the data we wish to encrypt is the form of a bytes array:

cipher = Fernet(key) message = "Message to be encrypted".encode('utf-8') token = cipher.encrypt(message) 

Notice that we use the encode(‘uft-8’) method to convert our message string into a bytes array. If we want to encrypt an image or other data, we must load it into memory as a byte array.

The encrypted message is stored in token in the format described below.

Decrypting a message

To decrypt a message, we must again create a Fernet object using the same key that was used to encrypt the data. We than call the decrypt function, passing the data we wish to decrypt is the form of a bytes array. The function returns the decrypted original message.

cipher = Fernet(key) decoded = cipher.decrypt(token) 

decrypt will raise an exception if it cannot decode token for any reason. For example:

  • The token is malformed, most likely because it has an invalid length, see later.
  • The HMAC signature doesn’t match. This could because the key is incorrect or because the token has been modified after creation.
  • The token has expired.

Fernet tokens contain a timestamp which allows testing for an expired message. To do this you must add the a ttl (time to live) parameter to the decrypt function that specifies a maximum age (in seconds) of the token before it will be rejected. For example:

decoded = cipher.decrypt(token, 24*60*60) 

This will reject any messages that are more than 1 day old. If you do not set a ttl value (or set it to None ), the age of the token will not be checked at all.

Fernet key and token format

A fernet key as returned by the generate_key actually contains two 16-byte keys:

These two values are concatenated to form a 32 byte value:

This 32 byte key is then encoded using Base64 encoding. This encodes the binary quantity as string of ASCII characters. The variant of Base64 used is URL and filename safe, meaning that it doesn’t contain any characters that aren’t permitted in a URL or a valid filename in any major operating system.

If we print the key, the result is a 44 byte string representing the 32 byte bunary value.

print(key) # b'K7GVACyA63l--mNkBjQ5tbkDxO6yCJkmr9D-uV5T-wU=' 

A Fernet token contains the following fields:

  • Version, 1 byte — the only valid value currently is 128.
  • Timestamp 8 bytes — a 64 bit, unsigned, big-endian integer that indicates when the ciphertext was created. Time is represented as the number of seconds since the start of Jan 1, 1970, UTC.
  • IV 32 bytes — the 128 bit Initialization Vector used in AES encryption and decryption.
  • Ciphertext — the encrypted version of the plaintext message. This is encrypted using AES, in CBC mode, using the encryption key section of the Fernet key. The ciphertext is padded to be a multiple of 128 bits, which is the AES block size, using the PKCS7 padding algorithm. This menas that the ciphertest will always be a multiple of 16 bytes in length, but the padding will be automatically removed when the data is decrypted.
  • HMAC — a 256-bit HMAC of the concatenated Version, Timestamp, IV, and Ciphertext fields. The HMAC is signed using the signing key section o fteh Fernet key.

The entire token (including the HMAC) is encoded using Base64. The HMAC is calculated using the binary data of the Version, Timestamp, IV, and Ciphertext fields, before Base64 encoding is applied.

If you found this article useful, you might be interested in the book NumPy Recipes or other books by the same author.

Join the PythonInformer Newsletter

Sign up using this form to receive an email when new content is added:

Источник

Криптография в Python — пошаговая реализация

Хотите попробовать криптографию на Python? В детстве я любил читать книги о том, как зашифровать и расшифровать секретные сообщения. Итак, я предлагаю вам несколько интересных реализаций криптографии на Python. Давайте начнем.

Что такое криптография?

Криптография защищает данные и переписку с помощью кодов. Таким образом, она может быть интерпретирована и доступна только определенным лицам, которым предназначена информация.

Механизмы шифрования знаний берут свое начало в математических принципах криптографии. И ряд основанных на правилах формул в качестве алгоритмов преобразования сообщений таким образом, чтобы их невозможно было расшифровать.

Эти алгоритмы генерируют криптографические ключи, цифровую подпись, аутентификацию для защиты данных, просмотр веб-страниц в Интернете и конфиденциальные транзакции, такие как транзакции по кредитным и дебетовым картам.

Каковы особенности хороших алгоритмов криптографии?

  1. Конфиденциальность: информация доступна только предполагаемому пользователю и никому другому.
  2. Полнота: информация не может быть изменена между отправителем и предполагаемым получателем при хранении или передаче без какого-либо дополнения к обнаруживаемой информации.
  3. Не отклонение: в более поздний момент создатель / отправитель данных не отклоняет свое намерение отправить информацию.
  4. Аутентификация: подтверждает личность отправителя и получателя. Детали проверяются, а также место назначения / происхождения.

Типы криптографии

  1. Симметричный ключ: это схема шифрования, в которой отправитель и получатель сообщений используют один универсальный ключ для шифрования и дешифрования сообщений. Схемы с симметричным ключом быстрее и проще, но проблема в том, что для безопасного использования отправитель и получатель должны где-то поменять местами ключ. Метод шифрования данных (DE) — наиболее распространенная система шифрования с симметричным ключом.
  2. Функции хеширования: в этом алгоритме не используются никакие ключи. Хеш-значение фиксированной длины вычисляется в соответствии с обычным текстом, что затрудняет получение текстового содержимого. Хеш-функции используются многими операционными системами для шифрования паролей.
  3. Асимметричный ключ: информация зашифровывается и дешифруется с помощью пары ключей. Для шифрования используется открытый ключ, а для дешифрования — закрытый. Закрытый ключ и открытый ключ разделены. И если кто-то знает открытый ключ, предполагаемый получатель расшифрует его только потому, что он сам знает закрытый ключ.

Реализация криптографии на Python с FERNET

Фреймворк, который я впервые представлю сегодня, называется Fernet. Это метод шифрования с симметричным ключом.

1. Установите FERNET

Мы можем просто использовать Python pip для установки модуля FERNET в нашей системе:

from cryptography.fernet import Fernet 

2. Создайте ключи шифрования.

Мы можем использовать функцию Фернет напрямую:

Мы также можем создать свой собственный ключ, используя функцию random

import base64 import os base64.urlsafe_b64encode(os.urandom(32)) 

А затем мы вызовем функцию FERNET с нашим key:

3. Шифрование ваших данных

Теперь мы готовы зашифровать наши данные:

token = f.encrypt(b"Meet me at 9pm. The bus stop. Bring the case.") print(token) 

Как видно из полученного токена:

b'gAAAAABfw08v4HVeS3X4WzIEU3NcIfGUCoFQ82XTNPSipSj0UGlYK8mljcDHzubXPN4yhyF3gAANzB5829rQ955GX-t52pg97DLnfhofJKLWvuGIAnUFRVKOfvQggn7VQPbaaciVkS1R' 

Без ключа приведенные выше данные полностью неразборчивы. Таким образом, злоумышленник, пытающийся получить информацию, застрянет без ключа.

4. Использование паролей для криптографии в Python

Мы также можем использовать определенные пароли вместо сохранения случайно сгенерированных токенов.

Итак, для этого нам нужно углубиться в примитивы, что немного опасно и может использоваться неправильно.

Они требуют принятия решений и глубокого знания действующих криптографических концепций.

Но следуйте приведенному ниже коду, и все будет в порядке:

from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC 

Теперь мы указываем пароль и генерируем случайную последовательность байтов:

password = b"journaldev" salt = os.urandom(16) print(salt) 
b'\x12\x03\xb4\xeaN\xb0\x19\x98\x83\xb42\xe0\xa71\xfb\xd5' 

Затем мы используем kdf для итерации 100k раз с использованием алгоритма хеширования, такого как SHA256, для получения ключа:

kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=salt, iterations=100000, ) 

Нам нужно использовать этот ключ для шифрования и дешифрования.

key = base64.urlsafe_b64encode(kdf.derive(password)) print(key) 
b'hjguwTLr2E2zIRHrI8a0dDXBSRel3YoKSx2uP5ruzX0=' 

5. Расшифровка текста

Как только получатель получит сообщение, расшифровать текст будет несложно. Итак, вы начинаете с ввода ключа в объект Fernet и используете функцию decrypt(), как показано ниже:

f = Fernet(#enter your key here) f.decrypt(token) 

Источник

Оцените статью