【问题标题】:Python pycrypto AES File block encryption failsPython pycrypto AES 文件块加密失败
【发布时间】:2013-12-06 10:30:12
【问题描述】:

我正在从生成的文本文件“generated.txt”中读取 64kb 并将数据写入 txt 文件 在每个写入的txt文件的开头都有奇怪的数据,除了第一个写入的文件。

The generated test file

Script to generate the file

如果我使用:

with open('generated.txt', 'rb') as f:

代替:

f = open('generated.txt', 'rb')

我在第一个文件中得到了同样奇怪的数据。

以十六进制表示的原始文件的第二个 64k 块的开头:

0a31303935300d0a31303935310d0a31

“奇怪”的数据来自第二个十六进制的txt文件:

e7fadb0930588fb74d1aba3fd3bafc84

第二个文件加密的十六进制开头:

bde07ad1e305193105655a42998a1fc9

可惜不一样

完整代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2
from Crypto import Random

key_size = 32
iterations = 10000
key = 'password'

salt = Random.new().read(key_size)
iv = Random.new().read(AES.block_size)
derived_key = PBKDF2(key, salt, key_size, iterations)
cipher = AES.new(derived_key, AES.MODE_CFB, iv)

i = 1
f = open('generated.txt', 'rb')


while True:

    data = f.read(65536)

    if not data:
        break

    encodedtext = iv + cipher.encrypt(data)
    decodedtext = str(cipher.decrypt(encodedtext))[16:]
    print 'Writing ' + str(i) 

    g = open('LOG_' + str(i) + '.txt', 'wb')
    g.write(decodedtext)
    g.close()

    d = open('LOG_' + str(i) + '_ENC.txt', 'wb')
    d.write(encodedtext)
    d.close()
    i = i+1

f.close()

感谢您的帮助:)

【问题讨论】:

  • txt 文件的链接已损坏。如果内容不大,可以放到post body或者使用pastebin.org之类的东西,避免依赖任何基于账户的存储服务。
  • 你用的是linux吗?如果没有,我会厌倦以“二进制”模式打开 ascii 文件。
  • 如果使用“w”和“r”而不是“wb”和“rb”,则没有变化。我想稍后加密其他文件,例如图像或视频文件;)
  • 能否显示加密文本的开头,包括“奇怪的数据”?请注意,加密结果不是文本
  • 好的,你能用十六进制给出输入和输出的前32个字节吗?将二进制打印为字符串并没有多大帮助。

标签: python encryption io aes pycrypto


【解决方案1】:

请确保您了解

字符编码定义了将文本表示为字节时的外观。有许多编码标准,但最常见的包括 ASCII、Windows-1252、UTF-8 和 UTF-16。第一个是有限的单个(7 位)集,Windows-1252 主要包含欧洲/拉丁字符,后两个是用于 Unicode 文本的编码。如果以错误的编码查看文件,那么它可能会显得毫无意义——但现在大多数文本编辑器都可以很好地猜出文本编码。

请注意,在大多数编码中,并非所有(有时甚至是很多)字节都可以解释为文本。字节可能根本不代表一个字符,或者它可能编码(或编码部分)控制字符。可以通过将字节编码为文本来解决此问题。常见的编码使用十六进制。每个字节恰好编码为两个字符,每个字符 4 位。这使程序员很容易看到字节的内容。另一方面,Base64 不是那么清晰,因为它将每 6 位编码为一个字符。所以base 64是一种更高效的编码,但是对于人类来说不是很容易阅读。

如果您希望明文输入清晰易读,请确保使用良好的字符编码。密文 - 尽管名称 - 由字节组成。如果您想从中创建字符,请使用 base 64。

【讨论】:

  • 错误数据仅在新的64kb块的开头,其余数据编码正确。
  • 不幸的是,这对我们来说很难调试。但请注意,使用您视为二进制的任何数据的字符串函数是危险的。例如,您在 64Ki 块上调用 str() 函数,但如果您的编码与 ASCII 不同,则很可能将一个字符一分为二。十六进制块之一显示二进制和 ASCII 数字。如果要加密任何文件,则不应使用 any 字符编码(密码除外)。
猜你喜欢
  • 2014-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-01
  • 1970-01-01
  • 2013-03-16
  • 2013-08-16
相关资源
最近更新 更多