0

0

Python cryptography.fernet 实现文件加密与解密教程

心靈之曲

心靈之曲

发布时间:2025-11-10 13:11:17

|

491人浏览过

|

来源于php中文网

原创

Python cryptography.fernet 实现文件加密与解密教程

本教程详细介绍了如何使用 pythoncryptography 库中的 fernet 模块实现文件的加密与解密操作。文章将涵盖 fernet 密钥的生成、管理与重用,以及如何在文件中安全地执行加密和解密过程,并强调密钥安全存储的重要性,确保数据机密性。

1. 引言:cryptography.fernet 简介

在信息安全日益重要的今天,对敏感数据进行加密是保护其机密性的基本手段。Python 的 cryptography 库提供了一套强大且易于使用的加密工具,其中 fernet 模块是实现对称加密的理想选择。Fernet 是一种基于 AES 算法的对称加密方案,它确保了消息的认证性、完整性和机密性,并且易于集成到应用程序中。

Fernet 的核心原理在于使用一个共享的密钥进行数据的加密和解密。这意味着,加密数据所使用的密钥必须与解密数据所使用的密钥完全一致。如果密钥丢失或泄露,数据将无法恢复或面临被未授权访问的风险。

2. 核心概念:密钥生成与 Fernet 实例

在使用 Fernet 进行文件加密和解密之前,我们需要理解其两个关键概念:密钥生成和 Fernet 实例的创建。

2.1 密钥生成

Fernet 密钥是一个32字节的 URL 安全的 Base64 编码字符串。它是对称加密的基础,必须严格保密。通过 Fernet.generate_key() 方法可以生成一个全新的密钥。

立即学习Python免费学习笔记(深入)”;

from cryptography.fernet import Fernet

# 生成一个 Fernet 密钥
key = Fernet.generate_key()
print(f"生成的 Fernet 密钥 (Base64编码): {key.decode()}")

重要提示: 每次调用 Fernet.generate_key() 都会生成一个全新且不同的密钥。对于需要持久化加密的数据,您必须将生成的密钥保存下来并在后续的解密操作中重用它。

2.2 Fernet 实例创建

拥有密钥后,您可以使用它来创建一个 Fernet 实例。这个实例将用于执行实际的加密和解密操作。

站长俱乐部购物系统
站长俱乐部购物系统

功能介绍:1、模块化的程序设计,使得前台页面设计与程序设计几乎完全分离。在前台页面采用过程调用方法。在修改页面设计时只需要在相应位置调用设计好的过程就可以了。另外,这些过程还提供了不同的调用参数,以实现不同的效果;2、阅读等级功能,可以加密产品,进行收费管理;3、可以完全可视化编辑文章内容,所见即所得;4、无组件上传文件,服务器无需安装任何上传组件,无需支持FSO,即可上传文件。可限制文件上传的类

下载
# 使用生成的密钥创建 Fernet 实例
cipher = Fernet(key)

3. 文件加密与解密操作

Fernet 实例提供了 encrypt() 和 decrypt() 方法来处理字节数据。对于文件操作,我们通常需要以二进制模式读取文件内容,进行加密或解密,然后再将处理后的内容写入文件。

3.1 原地加密与解密实现

以下代码示例展示了如何在一个函数中实现文件的原地(in-place)加密和解密。这意味着文件内容会被直接替换为加密或解密后的数据。

import os
from cryptography.fernet import Fernet
from cryptography.fernet import InvalidToken # 用于处理解密失败异常

def process_file_in_place(filename: str, cipher: Fernet, action: str, debug: bool = False):
    """
    对文件内容进行原地加密或解密。

    Args:
        filename (str): 要处理的文件路径。
        cipher (Fernet): Fernet 加密实例。
        action (str): 操作类型,可以是 "encrypt" 或 "decrypt"。
        debug (bool): 是否在加密后打印加密内容。
    """
    # 以二进制读写模式打开文件 (rb+ 允许读写,文件指针初始在开头)
    with open(filename, "rb+") as data_file:
        content = data_file.read() # 读取文件所有内容

        # 根据指定操作执行加密或解密
        processed_content = b""
        if action == "encrypt":
            processed_content = cipher.encrypt(content)
            if debug:
                print(f"加密后的内容 (bytes): {processed_content}")
        elif action == "decrypt":
            try:
                processed_content = cipher.decrypt(content)
                if debug:
                    print(f"解密后的内容 (bytes): {processed_content}")
            except InvalidToken:
                print(f"错误: 无法解密文件 '{filename}'。可能是密钥不匹配或数据已损坏。")
                return # 解密失败,退出函数
        else:
            raise ValueError("操作类型必须是 'encrypt' 或 'decrypt'")

        # 将文件指针移到文件开头
        data_file.seek(0)
        # 写入处理后的内容
        data_file.write(processed_content)
        # 如果新内容比旧内容短,则截断文件,确保文件大小正确
        data_file.truncate()

if __name__ == "__main__":
    test_filename = "example_data.txt"
    original_text = "Hello, world! This is a secret message that needs to be protected."

    # 1. 创建一个原始的明文文件
    with open(test_filename, "w", encoding="utf-8") as f:
        f.write(original_text)
    print(f"原始文件 '{test_filename}' 内容: {original_text}")

    # 2. 生成一个 Fernet 密钥并创建实例
    # 注意:此密钥仅用于本次运行,实际应用中需要持久化存储
    key_for_example = Fernet.generate_key()
    cipher_for_example = Fernet(key_for_example)
    print(f"生成的 Fernet 密钥 (Base64编码): {key_for_example.decode()}")

    # 3. 加密文件
    print("\n--- 执行加密 ---")
    process_file_in_place(test_filename, cipher_for_example, "encrypt", debug=True)
    with open(test_filename, "rb") as f:
        print(f"加密后文件 '{test_filename}' 的二进制内容 (部分): {f.read()[:50]}...") # 只打印前50字节

    # 4. 解密文件
    print("\n--- 执行解密 ---")
    process_file_in_place(test_filename, cipher_for_example, "decrypt")
    with open(test_filename, "r", encoding="utf-8") as f: # 解密后内容可按文本读取
        decrypted_text = f.read()
    print(f"解密后文件 '{test_filename}' 内容: {decrypted_text}")

    # 5. 验证解密内容是否与原始内容匹配
    assert decrypted_text == original_text
    print("\n验证成功:解密内容与原始内容一致。")

    # 清理测试文件
    if os.path.exists(test_filename):
        os.remove(test_filename)

代码解析:

  • open(filename, "rb+"):以二进制读写模式打开文件。r 表示读,b 表示二进制,+ 表示同时允许写操作。文件指针初始位于文件开头。
  • data_file.read():读取文件的全部内容。对于大文件,可能需要分块读取和处理。
  • cipher.encrypt(content) / cipher.decrypt(content):执行加密或解密操作。这些方法接受并返回字节串(bytes)。
  • data_file.seek(0):将文件指针重新定位到文件开头,以便从头开始写入新内容。
  • data_file.write(processed_content):将加密或解密后的内容写入文件。
  • data_file.truncate():非常重要! 如果新写入的内容比原始内容短,文件末尾可能会保留旧数据。truncate() 方法会将文件截断到当前文件指针位置,从而清除多余的旧数据。

4. 密钥管理:持久化与重用

在实际应用中,每次运行程序都生成新密钥是不可行的。为了能够在不同时间点或不同程序实例之间加密和解密数据,密钥必须被持久化存储并重用。

4.1 正确的密钥持久化方法

正确的密钥持久化

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

298

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1500

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

623

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

613

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

588

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

170

2025.07.29

c++字符串相关教程
c++字符串相关教程

本专题整合了c++字符串相关教程,阅读专题下面的文章了解更多详细内容。

83

2025.08.07

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

10

2026.01.27

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.3万人学习

Django 教程
Django 教程

共28课时 | 3.6万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号