欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Python基础学习之AES加密

程序员文章站 2022-05-01 18:38:01
◆ 简介: Advanced Encryption Standard(AES),高级加密标准,在密码学中又称Rijndael 加密法,是美国联邦*采用的一种区块加密标准。这个标...

◆ 简介:

Advanced Encryption Standard(AES),高级加密标准,在密码学中又称Rijndael 加密法,是美国联邦*采用的一种区块加密标准。这个标准用来替代原先的DES(因为DES不安全了),已经被多方分析且广为全世界所使用。

AES有5种加密操作模式:

1. 电码本模式(Electronic Codebook Book (ECB))

2. 密码分组链接模式(Cipher Block Chaining (CBC))

3. 计算器模式(Counter (CTR))

4. 密码反馈模式(Cipher FeedBack (CFB))

5. 输出反馈模式(Output FeedBack (OFB))

◆ 加密操作模式原理:

操作模式是使用分组密码(即伪随机置换)来加密任意长度消息的基本方法。通过使用足够多的0来填充,可将任意长度的消息填充为总长度为分组大小的倍数。

这里仅简单地介绍密码分组链接模式CBC。在这种模式中,首先选择一个长度为n(分组大小)的随机初始向量(IV)。然后,通过对当前明文和前一个密文的异或值做伪随机置换,来获得下一个密文分组。即c0 := IV,然后从i=1 到l (其中l 为分组组数),令ci := Fk(ci-1异或mi)。最终密文为0,c1…cl>,注意IV 不加密,并作为密文的一部分发送。

Python基础学习之AES加密

已证明,如果F 为伪随机置换,那么CBC加密模式是CPA安全的。

CBC模式的加密是依次执行,对于即时通信较为合适,而面对数据量较大的文件加密,CBC模式不是最有效率的选择,可以考虑有并行操作的OFB模式或CTR模式(但需要注意CTR模式计数器长度)。

伪随机置换的概念具体请参考Jonathan Katz, Yehuda Lindell 编著的现代密码学一书,这里从应用的角度出发不作深入介绍。CPA安全(抗选择明文攻击)的概念亦是。

AES采用对称分组密码*,对几乎所有依赖伪随机置换的密码学方案实现而言,AES是一个极好的选择对象。

◆ 需安装模块:

pycrypto

◆ 代码实现:

import sys
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
from Crypto import Random


class prpcrypt():
    def __init__(self, key):
        self.key = key
        self.mode = AES.MODE_CBC

    # 加密函数,如果text不是16的倍数【加密文本text必须为16的倍数!】,那就补足为16的倍数
    def encrypt(self, text):
        # 生成随机初始向量IV
        iv = Random.new().read(AES.block_size)
        cryptor = AES.new(self.key, self.mode, iv)

        # 这里密钥key 长度必须为16(AES-128)、24(AES-192)、或32(AES-256)Bytes 长度.目前AES-128足够用
        length = 16
        count = len(text)

        if (count % length != 0):
            add = length - (count % length)
        else:
            add = 0
        text = text + ('\0' * add)
        ciphertext = cryptor.encrypt(text)

        # 因为AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题
        # 所以这里统一把加密后的字符串转化为16进制字符串
        return b2a_hex(iv+ciphertext)

    # 解密后,去掉补足的空格用strip() 去掉
    def decrypt(self, text):
        ciphertext = a2b_hex(text)
        iv = ciphertext[0:AES.block_size]
        ciphertext = ciphertext[AES.block_size:len(ciphertext)]
        cryptor = AES.new(self.key, self.mode, iv)
        plain_text = cryptor.decrypt(ciphertext)
        return plain_text.rstrip('\0')