深入探究Python中的Fernet模块

3,197 阅读6分钟

Fernet是Cryptography包下的一个Python模块,它使用一个独特的密钥来加密和解密数据。在这篇文章中,我们将通过Python代码实例了解什么是fernet以及如何使用fernet模块。

什么是密码学包?

在深入研究Fernet之前,我们需要了解Python中的密码学包。它是一个模块的集合,可以在你程序的各个部分实现。它有两个层次--低层次和高层次。

  • 低级--它是一个被称为密码基元的构件的集合,需要以精确的方式排序以达到所需的安全级别。
  • 高层次 - 这个层次不需要很多实现,可以直接应用,这导致了一个更安全的过程。

在这篇文章中,我们将详细介绍fernet模块的组件和工作。让我们直接进入fernet教程。

费尔内特模块的组件

Fernet实现了对称密钥加密技术,因为没有密钥就无法读取/修改数据。下面列出了Fernet模块中使用的各种元素。

  • 输入
  • 带有CBC模式的128位AES
  • 填充
  • 带有SHA256的HMAC
  • 费尔内特令牌

让我们来详细了解一下这些。

1.输入

它需要一组输入并产生一个费尔内特令牌。与初始化向量一起的三个输入是:。

  • Plain_text (需要加密的数据)
  • 密钥(用于解密数据的唯一密钥)
  • 时间戳。

2.128位AES与CBC模式

AES(高级加密标准)是用于加密数据的快速对称密钥加密法。大小为128位的区块被用来处理数据的加密和解密。块是被划分为固定长度的字符串的数据部分。

AES算法一次只能对一个块进行加密。因此,各种模式,如CBC(Cipher Block Chaining)被用来在同一迭代中加密多个数据块。在这种模式下,一个随机选择的初始化向量(IV)被用来初始化每个标记的第一个块。

3.填充

填充是添加额外数据的过程,以确保输入符合要求的大小。在128位的AES密码块中,填充适用于较小和较大的数据大小。填充方案被证明是通过隐藏加密数据的长度来提高安全水平的关键。Fernet实现了PKCS #7的填充。

4.带有SHA256的HMAC

HMAC(基于哈希的消息验证码)是一种消息验证码,它使用一个加密密钥和一个哈希函数。它为服务器和客户端提供了一个独特的私钥。Fernet通过使用SHA256散列算法的HMAC实现了认证。

5.5.Fernet令牌

Fernet令牌是输入文本的加密数据,以及密钥和时间戳。这个令牌为输入的文本提供必要的完整性和认证。

费尔内特令牌的字段

fernet中的所有令牌都根据base64url规范进行编码,这是一个二进制到文本的编码方案,对文件的命名很安全。

一个fernet令牌是以下所有内容的汇编。

费尔内特令牌字段描述
版本它指定了将被使用的fernet版本。目前,只有一个定义的版本,其值为128位小数或十六进制的0x80。
时间戳从1970年1月1日(UTC)到令牌创建日期的秒数。它是一个65位无符号的大-endian整数。
初始化向量(IV)在数据加密和解密过程中,一个独特的128位初始化向量被添加到AES中每个令牌的第一个块中。这些数字是使用*os.urandom()*函数随机生成的。
密码文本不同长度的密码文本将被填充到128位大小的块中。
HMAC所有上述字段将用HMAC进行验证,并通过SHA256散列算法运行。因此,它提供了数据的完整性和真实性。

描述Fernet令牌字段的表格

令牌的加密和认证

以下是加密文本和创建费尔内特令牌的步骤。

  • 记录当前的时间戳。
  • 使用os.urandom()函数生成一个唯一的IV。
  • 构建密码文本。使用PKCS #7技术将纯文本填充到128位。使用用户定义的密钥和生成的IV,在CBC模式下用128AES对填充的数据进行加密。
  • 计算版本、时间戳、IV和纯文本的HMAC,并将它们作为一个整体连接起来。
  • 用base64url规范对整个令牌进行编码。

令牌的验证和解密

以下是验证和解密令牌的步骤,如果他们拥有秘密密钥。

  • 使用base64url规范对令牌进行解码。
  • 确保令牌的第一个字节是0x80,如果指定了最大年龄,则确保令牌没有过期。
  • 重新计算版本、时间戳、IV和纯文本的HMAC,并验证它是否与已经存储在令牌中的HMAC相匹配。
  • 使用IV和密钥解密AES-CBC的密码文本。
  • 解除密码并显示纯文本。

费奈特中的密码

为了安全起见,密码也可以在fernet中使用。密码需要通过bcrypt、Scrypt或PBKDF2HMAC等密钥推导运行,并应加盐。盐化是在密码中加入指定长度的随机字符,以提高哈希密码的安全性。

使用Fernet实现密码学:一个例子

让我们考虑一个使用密码对用户输入的纯文本进行加密和解密的例子。

首先,如果你还没有安装密码学包,请安装。

pip install cryptography

导入所有必要的模块。

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

让我们读取一个密码作为用户输入。一旦用户输入了密码,就会生成16个字符的随机盐,与密码连接起来。

password = input("Enter the password: ").encode()
salt = os.urandom(16)

PBKDF2(基于密码的密钥派生函数2)用于从密码派生密钥,也用于存储密钥。这里,包含密钥的kdf使用SHA256进行散列,它可以处理32字节的数据。迭代次数被设置为系统/服务器能够处理的最大极限。

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

现在,密钥使用base64url进行编码,并放在变量f中。

key = base64.urlsafe_b64encode(kdf.derive(password))
f = Fernet(key)

纯文本被输入,加密为密码文本令牌,并显示。

Plain_text = input("Enter the text to be encrypted: ").encode()
token = f.encrypt(Plain_text)
print("Encrypted data: ",token)

让我们来解密密码文本并打印它。

print("Decrypted data: ",f.decrypt(token).decode())

下面是使用Fernet模块实现密码学的完整Python代码。

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

password = input("Enter the password: ").encode()
salt = os.urandom(16)

kdf = PBKDF2HMAC(
    algorithm=hashes.SHA256(),
    length=32,
    salt=salt,
    iterations=390000,
)
key = base64.urlsafe_b64encode(kdf.derive(password))
f = Fernet(key)

Plain_text = input("Enter the text to be encrypted: ").encode()
token = f.encrypt(Plain_text)
print("Encrypted data: ",token)

print("Decrypted data: ",f.decrypt(token).decode())

输出

Example of cryptography using Fernet module in Python

最后的思考

Fernet模块是初学者加密和解密数据的最安全和理想的方法之一。它最适合于保护较小的数据,因为较大的数据如果不适合在内存中,就不能被加密。

我希望这个fernet教程能够帮助你理解Python中fernet模块的工作。再见,祝你在密码学领域的未来事业一帆风顺!