一、对称加密

对称加密:需要对加密解密使用相同密钥的加密算法。

优点:速度快,适合加密大量数据时使用。

缺点:不利于传送密钥。(后面文章在介绍非对称加密传输对称加密的密钥,此处应用是文件加密,密钥只有自己知道)

aes ecb加密解密 python python aes cbc加密_数据

对称加密的本质是密钥与明文进行异或运算,因此速度非常快,某些情况下还可以进行并行加密(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模式是将整个明文分成若干段相同的小段,然后对每一小段进行加密。

解密过程直接将图中原文与密文位置互换即可

aes ecb加密解密 python python aes cbc加密_数据_02

1.2 CBC 模式

CBC模式是先将明文切分成若干小段,然后每一小段与初始块或者上一段的密文段进行异或运算后,再与密钥进行加密。

解密过程直接将图中向 “” 的箭头反过来变成向上的,再用同样的算法与密钥进行解密。

aes ecb加密解密 python python aes cbc加密_算法_03

1.3 CFB模式

CFB模式是先将明文切分成若干小段,对上一个密文进行加密处理(第一次就用初始画向量),然后与明文块进行异或,得到新的密文,再重复上述操作

解密过程直接将图中向 “” 的箭头反过来变成向上的,注意,解密的过程同加密,第一步仍然是对初始化向量IV进行加密,然后与密文1进行异或,得到明文1,之后的过程同样操作,直到最后一个解密完成

aes ecb加密解密 python python aes cbc加密_加密解密_04

1.4 OFB模式

OFB模式是先将明文切分成若干小段,不断的对初始化向量进行加密,将加密的结果与明文进行异或,最终得到密文。

解密过程直接将图中向 “” 的箭头反过来变成向上的,注意,解密的过程同加密,第一步仍然是对初始化向量IV进行加密,然后与密文1进行异或,得到明文1,之后的过程同样操作,直到最后一个解密完成(文字同CFB)

aes ecb加密解密 python python aes cbc加密_加密解密_05

1.5 CFB 模式与 OFB 模式对比

上面讲的 CFB 与 OFB,在同片与文字上有相近的地方,将不同点进行局部放大,观察 CFB 与 OFB 的差异,有助于对这两个加密模式的理解,总的来说,OFB 就是不断对初始化向量进行加密,再与明文异或,CFB是不断的对密文进行加密,在与新的明文异或。

aes ecb加密解密 python python aes cbc加密_python_06

二、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 加解密失败,解密数据与元数据不相等')