在Python中加密/解密动图而不保存最终副本到硬盘

3 投票
1 回答
2277 浏览
提问于 2025-04-17 20:15

好的,我们再试一次。

我想用PyCrypto给一个动图加密,然后发给别人。接收方在收到后,应该能运行我的pycrypto脚本来查看这个动图——而且不需要把未加密的文件存到硬盘上。简单来说,我想把未加密的文件保存在内存中,这样其他库就可以直接访问,而不需要把它保存到磁盘。

在加密方面,我一直在使用

import os, random, struct
from Crypto.Cipher import AES

def encrypt_file(key='8c57d066796428d5a8f4b012155dad90', in_filename='tile.png', out_filename=None, chunksize=8192):
    """ Encrypts a file using AES (CBC mode) with the
        given key.

        key:
            The encryption key - a string that must be
            either 16, 24 or 32 bytes long. Longer keys
            are more secure.

        in_filename:
            Name of the input file

        out_filename:
            If None, '<in_filename>.enc' will be used.

        chunksize:
            Sets the size of the chunk which the function
            uses to read and encrypt the file. Larger chunk
            sizes can be faster for some files and machines.
            chunksize must be divisible by 16.
    """
    if not out_filename:
        out_filename = in_filename + '.enc'

    iv = ''.join(chr(random.randint(0, 0xFF)) for i in range(16))
    encryptor = AES.new(key, AES.MODE_CBC, iv)
    filesize = os.path.getsize(in_filename)

    with open(in_filename, 'r') as infile:
        with open(out_filename, 'w') as outfile:
            outfile.write(struct.pack('<Q', filesize))
            outfile.write(iv)

            while True:
                chunk = infile.read(chunksize)
                if len(chunk) == 0:
                    break
                elif len(chunk) % 16 != 0:
                    chunk += ' ' * (16 - len(chunk) % 16)

                outfile.write(encryptor.encrypt(chunk))

,但这似乎一点作用都没有。我甚至不知道从哪里开始解密,因为我需要在不把文件存到硬盘的情况下访问解密后的文件。

谢谢大家。

1 个回答

3

你觉得用 StringIO 来代替一个实际的磁盘文件 out_filename 怎么样?

其实可以用一个虚拟的磁盘,结构和真实的磁盘文件一样。

举个例子:

import StringIO

f=StringIO.StringIO()

for line in ['line {}\n'.format(i) for i in range(25)]:
    f.write(line)

f.seek(0)

for line in f:
    print line.strip() 

所以你需要把 with open(out_filename, 'w') as outfile: ... 这段代码换成 outfile=StringIO.StringIO(),其他的部分就可以保持不变。

像这样:

with open(in_filename, 'r') as infile:
    outfile=StringIO.StringIO()
    outfile.write(struct.pack('<Q', filesize))
    outfile.write(iv)

    while True:
        chunk = infile.read(chunksize)
        if len(chunk) == 0:
            break
        elif len(chunk) % 16 != 0:
            chunk += ' ' * (16 - len(chunk) % 16)

        outfile.write(encryptor.encrypt(chunk)) 

撰写回答