一、对称加密
对称加密:需要对加密和解密使用相同密钥的加密算法。
优点:速度快,适合加密大量数据时使用。
缺点:不利于传送密钥。(后面文章在介绍非对称加密传输对称加密的密钥,此处应用是文件加密,密钥只有自己知道)
对称加密的本质是密钥与明文进行异或运算,因此速度非常快,某些情况下还可以进行并行加密(OFB模式)
对称加密有五种模式,分别是:
1.电码本模式(Electronic Codebook Book (ECB))
2.密码分组链接模式(Cipher Block Chaining (CBC))
3.密码反馈模式(Cipher FeedBack (CFB))
4.输出反馈模式(Output FeedBack (OFB))
5.计算器模式(Counter (CTR))(不常见,不做介绍)
1.1 ECB模式
ECB模式是将整个明文分成若干段相同的小段,然后对每一小段进行加密。
解密过程直接将图中原文与密文位置互换即可
1.2 CBC 模式
CBC模式是先将明文切分成若干小段,然后每一小段与初始块或者上一段的密文段进行异或运算后,再与密钥进行加密。
解密过程直接将图中向 “下” 的箭头反过来变成向上的,再用同样的算法与密钥进行解密。
1.3 CFB模式
CFB模式是先将明文切分成若干小段,对上一个密文进行加密处理(第一次就用初始画向量),然后与明文块进行异或,得到新的密文,再重复上述操作
解密过程直接将图中向 “下” 的箭头反过来变成向上的,注意,解密的过程同加密,第一步仍然是对初始化向量IV进行加密,然后与密文1进行异或,得到明文1,之后的过程同样操作,直到最后一个解密完成
1.4 OFB模式
OFB模式是先将明文切分成若干小段,不断的对初始化向量进行加密,将加密的结果与明文进行异或,最终得到密文。
解密过程直接将图中向 “下” 的箭头反过来变成向上的,注意,解密的过程同加密,第一步仍然是对初始化向量IV进行加密,然后与密文1进行异或,得到明文1,之后的过程同样操作,直到最后一个解密完成(文字同CFB)
1.5 CFB 模式与 OFB 模式对比
上面讲的 CFB 与 OFB,在同片与文字上有相近的地方,将不同点进行局部放大,观察 CFB 与 OFB 的差异,有助于对这两个加密模式的理解,总的来说,OFB 就是不断对初始化向量进行加密,再与明文异或,CFB是不断的对密文进行加密,在与新的明文异或。
二、Python 密码库——Cryptodome
后续再补充
三、用python实现文件加密
from Cryptodome.Cipher import AES
import operator # 导入 operator,用于比较原始数据与加解密后的数据
AES_BLOCK_SIZE = AES.block_size # AES 加密数据块大小, 只能是16
AES_KEY_SIZE = 16 # AES 密钥长度(单位字节),可选 16、24、32,对应 128、192、256 位密钥
key = "ok let's go" # AES 加解密密钥
# 待加密文本补齐到 block size 的整数倍
def PadTest(bytes):
while len(bytes) % AES_BLOCK_SIZE != 0: # 循环直到补齐 AES_BLOCK_SIZE 的倍数
bytes += ' '.encode() # 通过补空格(不影响源文件的可读)来补齐
return bytes # 返回补齐后的字节列表
# 待加密的密钥补齐到对应的位数
def PadKey(key):
if len(key) > AES_KEY_SIZE: # 如果密钥长度超过 AES_KEY_SIZE
return key[:AES_KEY_SIZE] # 截取前面部分作为密钥并返回
while len(key) % AES_KEY_SIZE != 0: # 不到 AES_KEY_SIZE 长度则补齐
key += ' '.encode() # 补齐的字符可用任意字符代替
return key # 返回补齐后的密钥
# AES 加密
def EnCrypt(key, bytes):
myCipher = AES.new(key, AES.MODE_ECB) # 新建一个 AES 算法实例,使用 ECB(电子密码本)模式
encryptData = myCipher.encrypt(bytes) # 调用加密方法,得到加密后的数据
return encryptData # 返回加密数据
# AES 解密
def DeCrypt(key, encryptData):
myCipher = AES.new(key, AES.MODE_ECB) # 新建一个 AES 算法实例,使用 ECB(电子密码本)模式
bytes = myCipher.decrypt(encryptData) # 调用解密方法,得到解密后的数据
return bytes # 返回解密数据
# 主函数,从这里开始执行
if __name__ == '__main__':
with open('testfile/source.c', 'rb') as f: # 以二进制模式打开文件
bytes = f.read() # 将文件内容读取出来到字节列表中
print('源文件长度:{}'.format(len(bytes)))
key = PadKey(key.encode()) # 将密钥转换位字节列表并补齐密钥
bytes = PadTest(bytes) # 补齐原始数据
print('补齐后的源文件长度:{}'.format(len(bytes)))
encryptTest = EnCrypt(key, bytes) # 利用密钥对原始数据进行加密
decryptTest = DeCrypt(key, encryptTest) # 利用密钥对加密的数据进行解密
if operator.eq(bytes, decryptTest) == True: # 检查加解密是否成功
print('AES 加解密成功!')
else:
print('AES 加解密失败,解密数据与元数据不相等')