简单安全文件传输代码演示—DES加密算法
一、引言
在互联网环境中,数据隐私的保护至关重要,如果数据被篡改或损坏,可能会导致接收方无法正确解析和使用这些数据。通过安全文件传输,可以确保数据在传输过程中不被非法窃取或篡改,保证数据的完整性和可用性,避免因数据损坏或丢失而造成的损失。
二、 DES加密算法原理
DES加密算法的基本原理
DES(Data Encryption Standard)加密算法首先是对称加密算法,它的原理是将明文分成64位的块,然后通过一个密钥进行加密和解密。在加密过程中,DES使用了一个56位的密钥(因为每个第8位用作奇偶校验),同时使用了一个16轮的迭代过程。
在每一轮中,明文块被分为左右两部分,每部分32位,分别记为L0和R0。然后,经过一系列的代换和置换操作,每一轮产生48位的输出,这个输出再被组合成32位的数据,并作为下一轮的输入。经过16轮这样的操作后,左右两部分会交换并连接在一起,然后进行逆置换。
解密过程中,使用同样的密钥和逆置换操作,将密文还原为原始的明文。
DES加密算法具有分组加密、对称、有效秘钥长度为56位等特点,它是基于两种加密技术的组合:混乱和扩散。混乱是指密文中每一位都与密钥中的每一位有关,而扩散是指明文中的每一位影响密文中的多位。
三、文件加密解密代码演示
使用Python编写DES安全文件传输
在本次代码编写中为了方便理解,采用Python语言编写,通过使用Crypto库,并且从Crypto.Cipher模块中导入DES类,用于创建对象。
- 文件目录如下:
1、文件上传
首先将我们需要加密的文件上传到我们的 “files” 目录下
- 代码演示:
def upload_file():
file_to_upload = input("请输入要上传的文件路径: ")
encrypted_file = f"加密_{os.path.basename(file_to_upload)}"
encrypted_file_path = os.path.join("files", encrypted_file)
# # 复制文件到 "files" 目录下
shutil.copy(file_to_upload, encrypted_file_path)
print(f"待加密的文件放到: {encrypted_file_path}")
2、文件加密
1.首先,通过DES.new(key, DES.MODE_ECB)创建一个DES加密对象,其中key是用于加密的密钥。在这里我使用的模式是ECB。
2.打开输入文件(input_file),以二进制模式(‘rb’)读取其内容,并将其存储在plaintext变量中。此时的明文是未加密的原始数据。
3.因为DES加密时要求明文长度必须是8的倍数,所以如果明文长度不是8的倍数,会在明文的末尾添加足够的’\0’字符,以使明文长度达到8的倍数。这一步是为了确保加密过程中数据块的处理正确。
4.使用DES加密对象对填充后的明文进行加密,结果存储在ciphertext中。这是通过调用cipher.encrypt(padded_plaintext)完成的。
5.打开输出文件(output_file),以二进制模式(‘wb’)将加密后的密文写入到文件中。
- 代码演示
# DES 加密文件
def encrypt_file(input_file, output_file, key):
cipher = DES.new(key, DES.MODE_ECB)
with open(input_file, 'rb') as f:
plaintext = f.read()
padded_plaintext = plaintext + b'\0' * (8 - len(plaintext) % 8) # 补齐到8的倍数
ciphertext = cipher.encrypt(padded_plaintext)
with open(output_file, 'wb') as f:
f.write(ciphertext)
3、文件解密
1.首先,通过DES.new(key, DES.MODE_ECB)创建一个DES解密对象,其中key是用于解密的密钥。
2.打开输入文件(input_file),并且以二进制模式(‘rb’)读取其内容,并将其存储在ciphertext变量中。
3.使用DES解密对象对密文进行解密,结果存储在decrypted_text中。这是通过调用cipher.decrypt(ciphertext)完成的。
4.解密后的文本可能包含尾部的填充字符’\0’,使用rstrip(b’\0’)方法去除这些字符。
5.打开输出文件(output_file),并且以二进制模式(‘wb’)将解密后的明文写入到文件中
- 代码演示
# DES 解密文件
def decrypt_file(input_file, output_file, key):
cipher = DES.new(key, DES.MODE_ECB)
with open(input_file, 'rb') as f:
ciphertext = f.read()
decrypted_text = cipher.decrypt(ciphertext)
with open(output_file, 'wb') as f:
f.write(decrypted_text.rstrip(b'\0'))
4、 辅助加密代码
在这里创建了一个加密辅助函数,用于用户可以遍历目录进行加密自己想要加密的文件,该代码功能主要是:从"files"目录中选择一个以"加密_"开头的文件进行加密,并保存在"jiami_file"目录下,加密后的文件名格式为"加密_原文件名
- 代码演示:
def encrypt_file_for_user():
print("请选择要加密的文件:")
# 获取"files"目录下的所有文件
files_in_directory = os.listdir("files")
# 筛选出以"加密_"开头的文件
filtered_files = [file for file in files_in_directory if file.startswith("加密_")]
# 如果筛选后没有文件,则给出提示并结束函数
if not filtered_files:
print("没有符合条件的文件。")
return
# 按文件名排序筛选出的文件
filtered_files.sort()
# 打印排序后的文件列表,每行一个文件的编号和文件名
for i, filename in enumerate(filtered_files, start=1):
print(f"{i}. {filename}")
# 提示用户输入要加密的文件的编号,并读取用户输入
choice = int(input("输入要加密的文件的编号: "))
# 检查用户输入的编号是否有效(即是否在1到文件数量之间)
if 1 <= choice <= len(filtered_files):
# 如果有效,则选择该编号对应的文件,并获取其路径
selected_file = filtered_files[choice - 1] # 注意,列表的索引是从0开始的,而我们的编号是从1开始的,所以这里用choice-1
input_file_path = os.path.join("files", selected_file)
# 使用固定的密钥"qwert215"来加密文件
key = b'qwert215'
encrypt_filename = f"加密_{os.path.basename(selected_file)}" # 创建加密后的文件名,格式为"加密_原文件名" 在这里我们给加密过后的文件加入了一个文字特征值,为了方便我们遍历文件
encrypt_file_path = os.path.join("jiami_file", encrypt_filename) # 加密后的文件路径
# 调用encrypt_file函数进行加密,并指定输入和输出文件的路径以及密钥
encrypt_file(input_file_path, encrypt_file_path, key)
# 打印加密后的文件保存路径
print(f"文件加密完成,加密后的文件保存在: {encrypt_file_path}")
else: # 如果用户输入的编号无效
print("无效的选择。")
5、 辅助解密代码
在这里创建了一个解密辅助函数,用于用户可以遍历目录进行解密自己想要解密的文件,该代码功能主要是:从"jiami_file"目录中选择一个以"加密_"开头的文件进行解密,并保存在"jiemi_file"目录下,解密后的文件名格式为解密_原文件名
- 代码演示:
def decrypt_file_for_user():
print("请选择要解密的文件:")
files_in_directory = os.listdir("jiami_file")
filtered_files = [file for file in files_in_directory if
file.startswith("加密_加密_")]
for i, filename in enumerate(filtered_files, start=1):
print(f"{i}. {filename}")
choice = int(input("输入要解密的文件的编号: "))
if 1 <= choice <= len(filtered_files):
selected_file = filtered_files[choice - 1]
input_file_path = os.path.join("jiami_file", selected_file)
decrypted_filename = f"解密_{choice}.txt"
decrypted_file_path = os.path.join("jiemi_file", decrypted_filename)
# 使用固定的密钥"qwert215"来解密文件
key = b'qwert215'
decrypt_file(input_file_path, decrypted_file_path, key)
print(f"文件解密完成,解密后的文件保存在: {decrypted_file_path}")
else:
print("无效的选择。")
- 完整代码如下:
import os
import shutil
from Crypto.Cipher import DES
# DES 加密文件
def encrypt_file(input_file, output_file, key):
cipher = DES.new(key, DES.MODE_ECB)
with open(input_file, 'rb') as f:
plaintext = f.read()
padded_plaintext = plaintext + b'\0' * (8 - len(plaintext) % 8) # 补齐到8的倍数
ciphertext = cipher.encrypt(padded_plaintext)
with open(output_file, 'wb') as f:
f.write(ciphertext)
# DES 解密文件
def decrypt_file(input_file, output_file, key):
cipher = DES.new(key, DES.MODE_ECB)
with open(input_file, 'rb') as f:
ciphertext = f.read()
decrypted_text = cipher.decrypt(ciphertext)
with open(output_file, 'wb') as f:
f.write(decrypted_text.rstrip(b'\0'))
# 加密和解密过程
def decrypt_file_for_user():
print("请选择要解密的文件:")
files_in_directory = os.listdir("jiami_file")
filtered_files = [file for file in files_in_directory if
file.startswith("加密_加密_")]
for i, filename in enumerate(filtered_files, start=1):
print(f"{i}. {filename}")
choice = int(input("输入要解密的文件的编号: "))
if 1 <= choice <= len(filtered_files):
selected_file = filtered_files[choice - 1]
input_file_path = os.path.join("jiami_file", selected_file)
decrypted_filename = f"解密_{choice}.txt"
decrypted_file_path = os.path.join("jiemi_file", decrypted_filename)
key = b'qwert215'
decrypt_file(input_file_path, decrypted_file_path, key)
print(f"文件解密完成,解密后的文件保存在: {decrypted_file_path}")
else:
print("无效的选择。")
def encrypt_file_for_user():
print("请选择要加密的文件:")
files_in_directory = os.listdir("files")
filtered_files = [file for file in files_in_directory if
file.startswith("加密_")]
if not filtered_files:
print("没有符合条件的文件。")
return
# 按文件名排序
filtered_files.sort()
for i, filename in enumerate(filtered_files, start=1):
print(f"{i}. {filename}")
choice = int(input("输入要加密的文件的编号: "))
if 1 <= choice <= len(filtered_files):
selected_file = filtered_files[choice - 1]
input_file_path = os.path.join("files", selected_file)
key = b'qwert215'
encrypt_filename = f"加密_{os.path.basename(selected_file)}"
encrypt_file_path = os.path.join("jiami_file", encrypt_filename)
encrypt_file(input_file_path, encrypt_file_path, key)
print(f"文件加密完成,加密后的文件保存在: {encrypt_file_path}")
else:
print("无效的选择。")
def upload_file():
file_to_upload = input("请输入要上传的文件路径: ")
encrypted_file = f"加密_{os.path.basename(file_to_upload)}"
encrypted_file_path = os.path.join("files", encrypted_file)
# # 复制文件到 "file" 目录下
shutil.copy(file_to_upload, encrypted_file_path)
print(f"待加密的文件放到: {encrypted_file_path}")
def main():
while True:
print("\n1. 上传文件")
print("2. 加密文件")
print("3. 解密文件")
print("4. 退出")
choice = input("请输入你的选择: ")
if choice == '1':
upload_file()
elif choice == '2':
encrypt_file_for_user()
elif choice == '3':
decrypt_file_for_user()
elif choice == '4':
break
else:
print("请再一次输入你的选择")
if __name__ == "__main__":
main()
# 解密