实验三编程实现CBC和CTR模式下的AESPython实现
⽂章⽬录
⼀.实验⽬的
1.了解分组密码的结构特点;
2.掌握传统分组密码结构AES,以及AES在两种⼯作模式CBC和CTR下的实现;
3.通过使⽤Python(推荐)或者C,编程分别实现CBC和CTR模式下的AES加密解密。
⼆. 实验内容
在本次实验中,需要实现两个加密/解密系统,⼀个在密⽂分组链接模式(CBC)下使⽤AES,另⼀个在计数器模式(CTR)中使⽤AES。完成程序后,使⽤附件的中给出的四组密钥和密⽂(⼗六进制形式)来验证你的代码。
三.要求
1.在两种模式下,16字节的加密IV都要求是随机⽣成的,并被添加到密⽂前⾯;
2.对于CBC加密,要求使⽤PKCS5填充⽅案;
3.对于AES的基本实现,你可以使⽤现有的加密库,如PyCrypto(Python),Crypto++(C++)或任何其他语⾔和库;
4.要求⾃⼰实现CBC和CTR模式,⽽不是直接调⽤AES库的内置功能;
四.实验内容
(⼀)CBC模式下的AES
1.CBC模式简介
CBC模式的全称是Cipher Block Chaining模式(密⽂分组链接模式),之所以叫这个名字,是因为密⽂分组像链条⼀样相互连接在⼀起。在CBC模式中,⾸先将明⽂分组与前⼀个密⽂分组进⾏XOR运算,然后再进⾏加密。
加解密如图:
2.加密过程
(1)⽤CBC 是分组密码的⼀种⼯作模式,在加密前要对最后⼀块明⽂进⾏填充,实验要求使⽤ PKCS5 填充⽅案。
PKCS5 是按 8 字节分组对数据进⾏填充的:如果要填充 1 个字节,那填⼊的值就是 0x01;如果要填充 2 个字节,那么填⼊的值就是0x02,以此类推。但若待加密数据长度正好为 8 的整数倍时,则需要填⼊ 8 个 0x08。
h <0x07><0x07><0x07><0x07><0x07><0x07><0x07> 7
he <0x06><0x06><0x06><0x06><0x06><0x06> 6
hel <0x05><0x05><0x05><0x05><0x05> 5
hell <0x04><0x04><0x04><0x04> 4
hello <0x03><0x03><0x03> 3
hello <0x02><0x02> 2
hello w <0x01> 1
hello wo <0x08><0x08><0x08><0x08><0x08><0x08><0x08><0x08> 8 // 数据块
hello wor <0x07><0x07><0x07><0x07><0x07><0x07><0x07> 7
hello word <0x06><0x06><0x06><0x06><0x06><0x06> 6
(2)加密过程只能串形实现
(3)加密公式:
加密过程代码实现
C =1E (K ,[P iv ])
lambda编程1⨁C =i E (K ,[P C j −j ⨁(1)])
plainText = bytes (plainText )
blockSZ = self .block_size
iv = bytes (iv )
# PKCS#7填充规则
padLen = (blockSZ - len (plainText ) % blockSZ )
plainText = plainText + bytes ([padLen ] * padLen )
#填充密⽂内容
cipherText = bytearray (blockSZ + len (plainText ))
cipherText [0:blockSZ ] = iv
for i in range (blockSZ , len (cipherText ), blockSZ ):
#块长度
j = i + blockSZ
#异或操作
after_xor =bytes (xor_block (plainText [i - blockSZ :i ], cipherText [i - blockSZ :i ]))
#调⽤加密接⼝
cipherText [i :j ] = self .my_cipher .encrypt (after_xor )
return cipherText
2.解密过程:
(1)⾸先IV获取,根据题⽬中要求,密⽂前16个字节是被随机⽣成的IV值
(2)加密填充时应⽤的是PKCS7(PKCS5是其中的⼀个特例),所以解密时要去掉后⾯的填充
(3)解密可以并⾏实现,因为C1,C2…Cn均为已知,两个输⼊的异或均可以同时得到。
(4)解密式⼦:
并⾏运算下,可以:
解密过程代码实现
P =1D (K ,C )IV
1⨁P =j D (K ,C )C j −j ⨁(1)
[P ,P .....P ]=12N [D (K ,C ),D (K ,C )....,D (K ,C ))][IV ,C .....,C ]
12N ⨁1N
blockSZ = self.block_size
cipherText =bytes(cipherText)
after__cipher.decrypt(cipherText[blockSZ:])
blocks = xor_block(after_decrypt, cipherText[:-blockSZ])
plainText =bytes(blocks)
return plainText[:-plainText[-1]]
(⼆)CTR模式下的AES加密
1.CTR模式简介
CTR模式全称CounTeR模式(计数器模式)。CTR模式是⼀种通过将逐次累加的计数器进⾏加密来⽣成密钥流的流密码。⾃增的算⼦⽤密钥加密之后的输出和明⽂异或的结果得到密⽂,相当于⼀次⼀密。这种加密⽅式简单快速,安全可靠,⽽且可以并⾏加密,但是在计算器不能维持很长的情况下,密钥只能使⽤⼀次。
每次加密时都会⽣成⼀个不同的值(nonce)作为计数器的初始值。当分组长度为128⽐特时,计数器的初始值可能如下图所⽰:在这⾥插⼊图⽚描述
加密过程中计数器的值会产⽣如下变化:
2.加密过程
⾸先⽣成count值
def_get_timers(self,iv, msgLen):
#iv: 计时器初值
#msgLen: 密⽂长度(明⽂)
blockSZ = self.block_size
blocks =int((msgLen + blockSZ -1)//blockSZ)
timer = int_from_bytes(iv)
timers = iv
for i in range(1, blocks):
timer +=1
timers += int_to_bytes(timer)
return timers
然后进⾏加密过程
def encrypt(self, plainText, count):
count=bytes(count)
#各个计数器值
counters= self._get_timers(count,len(plainText))
blocks = xor_block(self._pt(counters), plainText) ciphertext =bytes(blocks)
return count+ciphertext[:len(plainText)]
3.CTR解密过程同理
def decrypt(self, cipherText):
blockSZ = self.block_size
# 加密和解密只有输⼊不同
pt = pt(cipherText[blockSZ:], cipherText[:blockSZ]) return pt[blockSZ:]
(三)CBC和CTR完整代码实现:
import Crypto.Cipher.AES as AES
import operator
from binascii import a2b_hex
from Crypto import Random
# 进⾏异或(bytes ^ bytes) 按位异或,迭代器
def xor_block(left, right):
return ,left,right)
#CBC模式实现:
class CBC_Cipher(object):
def__init__(self, key):
<_cipher = w(key, AES.MODE_ECB)
self.block_size = AES.block_size
def encrypt(self, plainText, iv):
plainText =bytes(plainText)
blockSZ = self.block_size
iv =bytes(iv)
# PKCS#7填充规则
padLen =(blockSZ -len(plainText)% blockSZ)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论