python实现AES的加密解密

了解AES

AES(Advanced Encryption Standard)是一种对称加密算法,相较于DES和3DES算法而言,AES算法有着更高的速度和资源使用效率,安全级别也较之更高.

公式:

C = E(K,P):明文P,密钥K,AES加密函数组成E,密文C。

主要要了解以下几点:

  1. AES密钥的长度使用的是128bite、192bite或256bite(位),即16Byte、24Byte或32Byte(字节),分别对应的加密轮数为10、12、14.长度越长,安全界别越高,效率低
  2. 对要加密的数据分组时,每一组的分组长度理论上16、24或32(跟密钥长度对应).
  3. 分组后的每组数据和密钥进行位运算,得到谜文,每组谜文连接后的长度和明文是一致的.
  4. 分组密码加密中的四种模式有ECB、CBC、CFB、OFB,使用加密模式不同,得到的谜文也不同.其中最常见的有ECB和CBC.
    下面说说这两种模式的特点:
  • ECB模式
    对明文分组,每组明文通过加密算法和密钥位运算得到密文,之后按照顺序将计算所得的密文连在一起即可,各段数据之间互不影响.
    特点:
    1.简单,有利于并行计算,误差不会被传送;
    2.不能隐藏明文的模式;
    3.可能对明文进行主动攻击;
    加密消息块相互独立成为被攻击的弱点(如果明文有规律,密文也有规律)

  • CBC模式(使用最多的模式)
    CBC模式需要一个初始化向量iv(和密钥长度相等的字符串)
    它的实现机制使加密的各段数据之间有了联系。
    加密步骤如下:
    1)首先将数据分组得到D1D2…Dn
    2)第一组数据D1与初始化向量iv位运算的结果进行加密得到第一组密文C1
    3)第二组数据D2与第一组的加密结果C1位运算以后的结果进行加密,得到第二组密文C2
    4)之后的数据以此类推,得到Cn
    5)按顺序连为C1C2C3…Cn即为加密结果。
    特点:
    1.不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。每个密文块依赖于所有的信息块,明文消息中一个改变会影响所有密文块
    2.发送方和接收方都需要知道初始化向量
    3.加密过程是串行的,无法被并行化(在解密时,从两个邻接的密文块中即可得到一个平文块。因此,解密过程可以被并行化)。
    4.解密时初始化向量必须相同

在上面的加密过程中,当明文长度不是8字节的整数倍的时候,需要对数据进行填充.这样有一个问题:
填充的值是什么呢?
下面是一种思路:

  • 计算要填充的字节数.(缺多少位够8字节)
    如缺6位,就把填充值设置为6:解密的时候,将最后一个字节的值取出来转换成整形数就行,得出的整数就是要删除的字节数.
    按照上面这个思路,会出现一个BUG,即如果最后一个字节的值正好是8,那怎么办.
    要解决这个BUG,我们可以这样做,即在计算填充的时候,如果明文数据是8的整数倍的话,我们可以也在数据后边填充8个字节,值为8,
    这样,如果解密得到最后一个字节的数据是8的话,就直接删除8个字节就可以了,上面的填充的方式不用变.

python实现AES加密和解密

  1. CBC模式的加密的实现代码如下:
def cryptoEn(string, key, iv):
   """
    :param string: 原始数据
    :param key: 密钥
    :param iv: 向量
    :return: 
    """
    print "原始data:", string   
    # 分组数据快大小 
    BS = AES.block_size
    # 填充方案
    pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
    # CBC模式
    mode = AES.MODE_CBC
    cipher = AES.new(key,mode,iv)
    encrypted = cipher.encrypt(pad(string)).encode('hex')
    print "加密后的数据:" encrypted
  1. CBC模式的解密代码
def cryptoDe(destring, key, iv):
	"""
    :param string: 需要解密的数据
    :param key: 密钥
    :param iv: 向量
    :return: 
    """
  
    print "需要解密的数据:", destring   
    # 分组数据快大小 
    BS = AES.block_size
    # 解密时删除填充的值
    unpad = lambda s : s[0:-ord(s[-1])]
    #CBC模式
    mode = AES.MODE_CBC
    cipher = AES.new(key,mode,iv)
    decrypted = unpad(cipher.decrypt(destring.decode('hex')))
    print "解密后数据:", decrypted

你可能感兴趣的:(python知识点)