python 实现AES-CBC加解密

  • CBC(Cipher Block Chaining,加密块链)模式
  • 为了克服ECB模式的安全缺陷,设计了密码分组链接模式,它使得当同一个明文分组重复出现时产生不同的密文分组。对每个分组使用相同的密钥,加密函数的输入是当前的明文分组和前一个密文分组的异或。从效果上看,将明文分组序列的处理连接起来了。
  • 为了产生第一个密文分组,要使用一个初始向量IV,IV必须被发送方和接收方都知道,为了做到最大程度的安全性,IV应该和密钥一样受到保护。
  • CBC加密需要三个参数,原文、密钥、偏移量才可完成,安全性更高,更不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。
  • 这里,我采用NoPadding方式补齐原文的方式进行举例,具体代码如下:
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
import hashlib
from crcmod import *
from binascii import *
import binascii

#例子如下
#明文:str(binascii.b2a_hex(str.encode('tuya49368a48b746')))[2:-1]
#密文:51506024af73925e15da8873afb08f9d
#key:str(binascii.b2a_hex(str.encode('8sHRRhqNAdXnSvpA')))[2:-1]
#iv:str(binascii.b2a_hex(str.encode('8sHRRhqNAdXnSvpA')))[2:-1]

#如果text不足16位的倍数就用"00"补足,即采用NoPadding方式补齐
def PKCS_zero(text):
    newbytes = '00'
    if len(text) % 32:
        add = 32 - (len(text) % 32)
        add = add >> 1
    else:
        add = 0
    text = text + newbytes * add
    return text
    
# 加密函数
def AES_CBC_encrypt(text,key,iv):
    print("AES_CBC_encrypt")
    print(" key  :", key, type(key))
    print(" iv   :", iv, type(iv))
    print("plain :", text, type(text))

    mode = AES.MODE_CBC
    text = PKCS_zero(text)
    text = bytes.fromhex(text)
    print("plain :", bytes.hex(text),type(text))
    key = bytes.fromhex(key)
    iv = bytes.fromhex(iv)

    cryptos = AES.new(key, mode, iv)
    cipher_text = bytes.hex(cryptos.encrypt(text))
    # 因为AES加密后的字符串不一定是ascii字符集的,输出保存可能存在问题,所以这里转为16进制字符串

    print("cipher:", cipher_text, type(cipher_text))
    print("************************************************")
    return cipher_text
    # 解密后,去掉补足的空格用strip() 去掉
   
#AES-CBC解密
def AES_CBC_decrypt(text,key,iv):
    print("AES_CBC_decrypt")
    print(" key  :", key, type(key))
    print(" iv   :", iv, type(iv))
    print("plain :", text, type(text))

    text = bytes.fromhex(text)
    key = bytes.fromhex(key)
    iv  = bytes.fromhex(iv)

    mode = AES.MODE_CBC
    cryptos = AES.new(key, mode, iv)

    plain_text = bytes.hex(cryptos.decrypt(text))

    print("cipher:", plain_text, type(plain_text))
    print("************************************************")

    return plain_text
  • 由上面的例子可以得出以下结果:
AES_CBC_encrypt
 key  : 387348525268714e4164586e53767041 <class 'str'>
 iv   : 387348525268714e4164586e53767041 <class 'str'>
plain : 74757961343933363861343862373436 <class 'str'>
plain : 74757961343933363861343862373436 <class 'str'>
cipher: 51506024af73925e15da8873afb08f9d <class 'str'>
************************************************
AES_CBC_decrypt
 key  : 387348525268714e4164586e53767041 <class 'str'>
 iv   : 387348525268714e4164586e53767041 <class 'str'>
plain : 51506024af73925e15da8873afb08f9d <class 'str'>
cipher: 74757961343933363861343862373436 <class 'str'>
************************************************
  • 5
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值