当前位置: 移动技术网 > IT编程>脚本编程>Python > Python基础学习之AES加密

Python基础学习之AES加密

2018年03月27日  | 移动技术网IT编程  | 我要评论

神之墓地2.4b,救尔心胶囊,藤崎琴音

◆ 简介:

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 不加密,并作为密文的一部分发送。

这里写图片描述

已证明,如果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')

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网