如何使用Python加密大文件?

2024-01-23

我正在尝试加密大于 1GB 的文件。我不想把所有内容都读到记忆中。我选择 Fernet (cryptography.fernet) 来完成此任务,因为它是最受推荐的(比非对称解决方案更快)。

我生成了密钥。然后我创建了一个脚本来加密:

    key = Fernet(read_key())

    with open(source, "rb") as src, open(destination, "wb") as dest:
        for chunk in iter(lambda: src.read(4096), b""):
            encrypted = key.encrypt(chunk)
            dest.write(encrypted)

以及解密:

    key = Fernet(read_key())

    with open(source, "rb") as src, open(destination, "wb") as dest:
        for chunk in iter(lambda: src.read(4096), b""):
            decrypted = key.decrypt(chunk)
            dest.write(decrypted)

加密可以工作——这并不奇怪,但解密却不行。 首先我以为它可能有效,但事实并非如此。我猜想加密时块大小会增加,然后当我读取 4096 字节时,它不是一个完整的加密块。我尝试解密时遇到错误:

Traceback (most recent call last):
  File "/redacted/path/venv/lib/python3.7/site-packages/cryptography/fernet.py", line 119, in _verify_signature
    h.verify(data[-32:])
  File "/redacted/path/venv/lib/python3.7/site-packages/cryptography/hazmat/primitives/hmac.py", line 74, in verify
    ctx.verify(signature)
  File "/redacted/path/venv/lib/python3.7/site-packages/cryptography/hazmat/backends/openssl/hmac.py", line 75, in verify
    raise InvalidSignature("Signature did not match digest.")
cryptography.exceptions.InvalidSignature: Signature did not match digest.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/redacted/path/main.py", line 63, in <module>
    decrypted = key.decrypt(chunk)
  File "/redacted/path/venv/lib/python3.7/site-packages/cryptography/fernet.py", line 80, in decrypt
    return self._decrypt_data(data, timestamp, time_info)
  File "/redacted/path/venv/lib/python3.7/site-packages/cryptography/fernet.py", line 137, in _decrypt_data
    self._verify_signature(data)
  File "/redacted/path/venv/lib/python3.7/site-packages/cryptography/fernet.py", line 121, in _verify_signature
    raise InvalidToken
cryptography.fernet.InvalidToken

有办法解决这个问题吗?也许有比 fernet 更好(更简单)的方法和不同的解决方案?


我刚刚遇到了同样的问题 - 我感受到你的痛苦兄弟。

Fernet 存在一些问题,使其与您的方法不兼容:

  1. Fernet 吐出 urlsafe_base64 编码的数据。这意味着每消耗 3 个字节的未加密数据,Fernet 就会吐出​​ 4 个字节的加密数据。

这可以防止您在加密和解密时使用相同的“块大小”,因为解密块大小必须更大。不幸的是,处理数据urlsafe_b64decode/urlsafe_b64encode也没有达到目的,因为:

  1. Fernet 似乎在加密数据中的某处添加了某种摘要/校验和/元数据。

可能有一种简单的方法可以计算出这个摘要有多大,并调整解密块大小以适应这一点 - 但我想避免使用“魔法常量”做一些事情,因为这感觉很恶心。

我最终选择的解决方案实际上非常优雅。其工作原理如下:

加密:

  1. Read n数据字节(raw_chunk)
  2. Encrypt nbytes 用 Fernet 创建一个m字节块(enc_chunk).
  3. Use len(enc_chunk).to_bytes(4, "big")将加密块的大小写入文件
  4. 将加密块写入文件
  5. 当我读到时中断b""

解密:

  1. Read 4数据字节(size)
  2. 如果数据是 a 则中断b""
  3. 使用以下命令将这 4 个字节转换为整数int.from_bytes(size, "big") (num_bytes)
  4. Read num_bytes加密数据的
  5. 使用 Fernet 毫无问题地解密此数据
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用Python加密大文件? 的相关文章

随机推荐

  • 无法将 Firebase 存储图像快速显示到 CollectionView 中

    我需要一些帮助 我一直在互联网上寻找帮助 以在 CollectionView 中显示我的 firebase 存储图像 我正在使用 UIImagepicker 将图像上传到 firebase 但它们没有显示在我的 CollectionView
  • 从 Swift 类调用 Objective-C 导致链接器错误

    我正在尝试在 Swift 中使用 RFDuino Objective C 库 这一切听起来很简单 我以前从 Swift 类调用过 Objective C 没问题 然而这一次我碰壁了 创建的头文件 向其中添加了头文件 Swift 可以看到类没
  • DrawingManager.setDrawingMode(null) 导致过多的递归

    请看看这个小提琴 http jsfiddle net HoffZ Zu55b http jsfiddle net HoffZ Zu55b 为什么它会导致错误 太多递归 drawMan setDrawingMode null drawMan
  • LocationManager 每分钟更新一次,消​​耗大量电池电量

    我有一些类似于以下的代码 LocationManager m LocationManager context getSystemService Context LOCATION SERVICE Criteria c new Criteria
  • 简单的html dom:如何获取没有特定属性的标签

    我想获取 class 属性等于 someclass 的标签 但仅获取那些未定义属性 id 的标签 I tried以下 基于此答案 但不起作用 html gt find someclass id Note 我在用着简单的 HTML DOM 类
  • 如何比较两个数组的所有元素?

    我有两个大约 1000 行和 1000 列的大数组 我需要比较这些数组的每个元素 如果相应的元素相等 则将 1 存储在另一个数组中 我可以用 for 循环来做到这一点 但这需要很长时间 我怎样才能更快地做到这一点 给出的答案都是正确的 我只
  • WCF 服务合同中使用soapAction="" 进行多项操作?

    我需要创建一项将由第三方 回调 的服务 因此 我需要遵守他们的 WSDL 他们的 WSDL 定义了所有操作soapAction 所以我的服务也需要做同样的事情 不幸的是 我收到错误 操作A和 乙有 相同的动作 每一次操作 必须具有独特的行动
  • Keras 简单 RNN 实现

    我在尝试编译具有一个循环层的网络时发现了问题 第一层的维度似乎存在一些问题 因此我对 RNN 层在 Keras 中如何工作的理解存在一些问题 我的代码示例是 model add Dense 8 input dim 2 activation
  • 使用 rspec 和 devise sign_in env 进行集成测试

    我正在使用配置为使用omniauth facebook登录集成的设备 当拨打电话时sign in方法来自我的spec request我得到的测试 undefined method env for nil NilClass spec desc
  • Android 免费和付费,具有不同的功能

    我知道开发应用程序的免费和付费版本的最佳方法是拥有一个包含程序主要部分的库项目 然后 免费和付费项目将使用该库项目 这使得免费和付费项目拥有不同的资源 但是 我的问题是我们如何限制免费应用程序中的功能 或将其扩展为付费应用程序 例如 我的免
  • Python 2 与 3。相同的输入,不同的结果。 MD5 哈希值

    Python 3 代码 def md5hex data return hex string of md5 of the given string h MD5 new h update data encode utf 8 return b2a
  • Scala Spark - 处理层次结构数据表

    我有带有树结构的层次结构数据模型的数据表 例如 这是一个示例数据行 Id name parentId path depth 55 Canada null null 0 77 Ontario 55 55 1 100 Toronto 77 55
  • JDBC Hibernate - Mysql 连接错误

    我的 Ubuntu 11 10 桌面上有一个本地 mysql 服务器 主机名 本地主机 用户名 根 密码 root 数据库名称 CBS 我真的很困惑 因为当我使用 访问 mysql 时terminal mysql administrator
  • Highcharts:添加自定义图像按钮

    我想在高图表上添加图像按钮 到目前为止 我已经成功创建了一个图像按钮并在其上附加了一个单击事件 但问题是 图像 sun png 位于图表的左侧 图像按钮右对齐 工具栏的默认位置 有什么解决办法吗 exporting buttons popU
  • 就地处理(无重定向)401 未经授权?

    QUESTION 有什么简单的方法可以直接返回 401 并登录页面 避免 302 重定向 当IAuthorizationFilter我的 IIS 7 0 上的 ASP NET MVC 5 应用程序失败 我必须实现什么基础设施才能使其正常工作
  • 如何判断任务是否已被“观察”?

    这是后续这个问题 https stackoverflow com q 33086371 2674222 我还读过斯蒂芬 托布的 任务和未处理的异常 http blogs msdn com b pfxteam archive 2009 05
  • 在SQL中插入空白行数

    使用 SQL 查询 我需要在结果中包含空白行以使每组 family id 等于 4 行 SELECT ROW NUMBER OVER PARTITION BY family id ORDER BY family id AS rowNum f
  • 使用 jQuery 更改单击的表格行的颜色

    我需要你的帮助 我怎样才能使用 jQuery 更改表中所选行的背景颜色 对于本例 我们使用 css 类 highlighted 如果再次单击同一行 请将其更改回默认颜色 白色 选择 css 类 nonhighlighted table bo
  • unixODBC (DB2) + PHP + CentOS 的段错误

    经过两天的战斗 我尝试在这里寻求帮助 我正在使用 unixODBC 2 2 11 在 CentOS 5 4 服务器上使用 DB2 iSeries 和 PHP 5 3 我猜是因为 PHP 从 5 1 升级到 5 3 我让 PHP 在某些查询上
  • 如何使用Python加密大文件?

    我正在尝试加密大于 1GB 的文件 我不想把所有内容都读到记忆中 我选择 Fernet cryptography fernet 来完成此任务 因为它是最受推荐的 比非对称解决方案更快 我生成了密钥 然后我创建了一个脚本来加密 key Fer