Python对二进制文件进行加密和解密

加密是对信息进行编码的过程,只有有密码才能访问它。这一点至关重要,因为它可以安全地保护您不希望任何人看到或访问的数据。

<a href='/tag/python.html'>Python</a>对二进制文件进行加密和解密

在本教程中,您将学习如何使用Python通过加密库对文件或任何字节对象(也包括字符串对象)进行加密。

我们将使用对称加密,这意味着用于加密数据的相同密钥也可用于解密。那里有很多加密算法,我们将使用的库是基于AES算法构建的。

注意:了解加密和哈希算法之间的区别非常重要,在加密中,一旦拥有密钥,您就可以检索原始数据,而在哈希函数中则不能,因此,它们被称为单向加密。

一、安装依赖

让我们从安装加密开始:

pip3 install cryptography


打开一个新的Python文件,让我们开始吧:

from cryptography.fernet import Fernet

Fernet是对称身份验证密码技术的实现,让我们首先生成该密钥并将其写入文件:

def write_key():
"""
Generates a key and save it into a file
"""
key = Fernet.generate_key()
with open("key.key", "wb") as key_file:
key_file.write(key)


generate_key()函数会生成一个新的Fernet密钥,你需要将其保存在安全的地方,如果丢失了该密钥,则将无法再解密使用此密钥加密的数据。

由于此密钥是唯一的,因此我们不会在每次加密任何内容时生成密钥,因此我们需要一个函数来为我们加载该密钥:

def load_key():
"""
Loads the key from the current directory named `key.key`
"""
return open("key.key", "rb").read()


二、字符串加密

现在我们知道了如何获取密钥,让我们从加密字符串对象开始,只是为了让您首先熟悉它。

生成密钥并将其写入文件:
# generate and write a new key
write_key()
让我们加载该密钥:

# load the previously generated key
key = load_key()


一些消息:

message = "some secret message".encode()



我们需要对字符串进行编码,以将其转换为字节以适合加密,encode()方法使用utf-8编解码器对该字符串进行编码。使用该键初始化Fernet类:

# initialize the Fernet class
f = Fernet(key)


加密消息:

# encrypt the message
encrypted = f.encrypt(message)


f.encrypt()方法对传递的数据进行加密,这种加密的结果称为“ Fernet令牌”,并具有强大的隐私性和真实性保证。

让我们看看它加密后的输出:
# print how it looks
print(encrypted)
输出:

b'gAAAAABdjSdoqn4kx6XMw_fMx5YT2eaeBBCEue3N2FWHhlXjD6JXJyeELfPrKf0cqGaYkcY6Q0bS22ppTBsNTNw2fU5HVg-c-0o-KVqcYxqWAIG-LVVI_1U='


解密:

decrypted_encrypted = f.decrypt(encrypted)
print(decrypted_encrypted)

输出:

b'some secret message'


的确是同一条信息。

f.decrypt()方法解密Fernet令牌。成功解密后,这将返回原始明文作为结果,否则将引发异常。

三、文件加密

现在您知道了如何基本加密字符串,让我们深入研究文件加密,我们需要一个函数来给定文件名和密钥名来加密文件:

def encrypt(filename, key):
"""
Given a filename (str) and key (bytes), it encrypts the file and write it
"""
f = Fernet(key)


在使用给定的密钥初始化Fernet对象之后,让我们首先阅读该文件:

with open(filename, "rb") as file:
	# read all file data
	file_data = file.read()


之后,加密我们刚刚读取的数据:

# encrypt data
encrypted_data = f.encrypt(file_data)


用相同的名称写入加密文件,这样它将覆盖原始文件(暂时不要在敏感信息上使用此文件,只需对一些垃圾数据进行测试):

# write the encrypted file
with open(filename, "wb") as file:
	file.write(encrypted_data)


这样做了,现在要解密的功能,它是相同的过程,除了我们将使用解密()函数,而不是加密() :

def decrypt(filename, key):
    """
    Given a filename (str) and key (bytes), it decrypts the file and write it
    """
    f = Fernet(key)
    with open(filename, "rb") as file:
        # read the encrypted data
        encrypted_data = file.read()
    # decrypt data
    decrypted_data = f.decrypt(encrypted_data)
    # write the original file
    with open(filename, "wb") as file:
        file.write(decrypted_data)



让我们测试一下,我在当前目录中有一个csv文件和一个密钥,如下图所示:

<a href='/tag/python.html'>Python</a>对二进制文件进行加密和解密

它是完全可读的文件,要对其进行加密,我们需要做的就是调用我们刚编写的函数:

# uncomment this if it's the first time you run the code, to generate the key
# write_key()
# load the key
key = load_key()
# file name
file = "data.csv"
# encrypt it
encrypt(file, key)


执行此操作后,您可能会看到文件的大小增加了,而且它是垃圾数据,您甚至无法读取一个单词!

要将文件恢复为原始格式,只需调用crypto()函数:

# decrypt the file
decrypt(file, key)


而已!您会看到原始文件代替了之前的加密文件。

但是请注意,您需要提防大文件,因为文件必须完全位于内存中才能适合加密,因此您需要考虑使用一些拆分数据的方法或对大文件进行压缩!

完整的代码如下:

from cryptography.fernet import Fernet

def write_key():
    """
    Generates a key and save it into a file
    """
    key = Fernet.generate_key()
    with open("key.key", "wb") as key_file:
        key_file.write(key)

def load_key():
    """
    Loads the key from the current directory named `key.key`
    """
    return open("key.key", "rb").read()

def encrypt(filename, key):
    """
    Given a filename (str) and key (bytes), it encrypts the file and write it
    """
    f = Fernet(key)
    with open(filename, "rb") as file:
        # read all file data
        file_data = file.read()
    # encrypt data
    encrypted_data = f.encrypt(file_data)
    # write the encrypted file
    with open(filename, "wb") as file:
        file.write(encrypted_data)

def decrypt(filename, key):
    """
    Given a filename (str) and key (bytes), it decrypts the file and write it
    """
    f = Fernet(key)
    with open(filename, "rb") as file:
        # read the encrypted data
        encrypted_data = file.read()
    # decrypt data
    decrypted_data = f.decrypt(encrypted_data)
    # write the original file
    with open(filename, "wb") as file:
        file.write(decrypted_data)


if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser(description="Simple File Encryptor Script")
    parser.add_argument("file", help="File to encrypt/decrypt")
    parser.add_argument("-g", "--generate-key", dest="generate_key", action="store_true",
                        help="Whether to generate a new key or use existing")
    parser.add_argument("-e", "--encrypt", action="store_true",
                        help="Whether to encrypt the file, only -e or -d can be specified.")
    parser.add_argument("-d", "--decrypt", action="store_true",
                        help="Whether to decrypt the file, only -e or -d can be specified.")

    args = parser.parse_args()
    file = args.file
    generate_key = args.generate_key

    if generate_key:
        write_key()
    # load the key
    key = load_key()

    encrypt_ = args.encrypt
    decrypt_ = args.decrypt

    if encrypt_ and decrypt_:
        raise TypeError("Please specify whether you want to encrypt the file or decrypt it.")
    elif encrypt_:
        encrypt(file, key)
    elif decrypt_:
        decrypt(file, key)
    else:
        raise TypeError("Please specify whether you want to encrypt the file or decrypt it.")好
好了,python中aes对称加密与解密今天就说到这了

{{collectdata}}

网友评论0