AES算法之Python代码实现

AES算法

第 1章 基本特性

1.1 DES算法的替代者

1.2 对称密码

1.3 可逆算法

1.4 分组密码

第2章 基本概念

2.1 密钥

密钥是AES算法实现加密和解密的根本。使用同一个密钥。支持三种长度的密钥:128位,192位,256位。从安全性来看,AES256安全性最高,从性能来看,AES128性能最高。本质原因是它们的加密处理轮数不同。

2.2填充

要想了解填充的概念,我们先要了解AES的分组加密特性。
在这里插入图片描述

AES算法在对明文加密的时候,并不是把整个明文一股脑加密成一整段密文,而是把明文拆分成一个个独立的明文块,每个一个明文块长度128bit。
这些明文块经过AES加密器的复杂处理,生成一个个对立的密文块,这些密文块拼接在一起,就是最终的AES加密结果。
但是这里涉及到一个问题:
假如一段明文长度是192bit,如果按每128bit一个明文块来拆分的话,第二个明文块只有64bit,不足128bit。这时候怎么办呢?就需要对明文块进行填充(Padding)。
AES在不同的语言实现中有许多不同的填充算法,我们列举几种典型的填充来介绍一下。需要注意的是,如果在AES加密的时候使用了某一种填充方式,解密的时候也必须采用同样的填充方式。

2.2.1 NoPadding

NoPadding: 不做任何填充,但是要求明文必须是16字节的整数倍。

2.2.2 PKSC5Padding

PKCS5Padding(默认):如果明文块少于16个字节(128bit),在明文块末尾补足相应数量的字符,且每个字节的值等于缺少的字符数。比如明文:{1,2,3,4,5,a,b,c,d,e},缺少6个字节,则补全为{1,2,3,4,5,a,b,c,d,e,6,6,6,6,6,6}。

2.2.3 IS010126Padding

ISO10126Padding:如果明文块少于16个字节(128bit),在明文块末尾补足相应数量的字节,最后一个字符值等于缺少的字符数,其他字符填充随机数。比如明文{1,2,3,4,5,a,b,c,d,e},缺少6个字节,则可能补全为{1,2,3,4,5,a,b,c,d,e,1,2,3,4,5,&}。

2.3模式

AES的工作模式,体现在把明文加密成密文块的处理过程中。AES加密算法提供了五种不同的工作模式:其中最常用的是ECB,CBC模式。
(1)ECB:Electronic Codebook Book 电码本模式
相同的明文块经过加密会变成相同的密文块,因此安全性较差。
在这里插入图片描述
(2) CBC:Cipher Block Chaining 密码分组链接模式。
目的是防止同样的明文块始终加密成同样的密文块。
在这里插入图片描述

(3) CTR:Counter 计算器模式
(4) CFB:Cipher FeedBack 密码反馈模式
(5) OFB:Output FeedBack 输出反馈模式
同样的,如果在AES加密的时候使用了某一种工作模式,解密的时候也必须采用同样的工作模式。

第3章 加密流程

• 把明文按照128bit拆分成若干个明文块。
• 按照选择的填充方式来填充最后一个明文块。
• 每一个明文块利用AES加密器和密钥,加密成密文块。
• 拼接所有的密文块,成为最终的密文结果。
在这里插入图片描述

第4章 代码实现

在ECB和CBC模式下,用三种填充模式实现AES加密解密。

import base64
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
secret = "123456789123456789123456789123"             #由用户输入的16位或24位或32位长的初始密码字符串
print('密钥长度:',len(secret))
#密钥处理,16的整数倍
def add_to_16(text):
    while len(text)%16 !=0:
        text+='\0'
    return (text)
secret=add_to_16(secret)
print('不做任何填充,但是要求密钥必须是16字节的整数倍:',secret)

'''PKSC5Padding 填充
def add_to_16(text):
    byte=16-len(text)%16
    print(byte)
    return (text+chr(byte)*byte)
secret=add_to_16(secret)
print(secret)
'''
'''ISO10126Padding 填充 
def add_to_16(text)
    byte=16-len(text)%16
    print(byte)
    return(text+get_random_bytes(byte))
secret=add_to_16(secret)
print(secret)
'''
#cipher = AES.new(secret.encode('utf-8'),AES.MODE_ECB)      #通过AES.MODE_ECB处理初始密码字符串,并返回cipher对象
iv=get_random_bytes(16)  #随机获取16位变量
cipher = AES.new(secret.encode('utf-8'),AES.MODE_CBC,iv)
data="12345678912345"
#明文处理
def add_to_16(text):
    while len(text)%16 !=0:
        text+='\0'
    return (text)
data=add_to_16(data)
print('明文:',data)
encrypt_data= cipher.encrypt(data.encode('utf-8'))     #输入需要加密的字符串,注意字符串长度要是16的倍数。16,32,48..
print ('密文',encrypt_data)                                              #输出加密后的字符串
encrypt_data = base64.b64encode(encrypt_data)
print ('密文的base64编码:',base64.b64encode(encrypt_data))             #输出加密后的字符串的base64编码。
encrypt_data = base64.b64decode(encrypt_data)
print('密文的base64编码的解码:',encrypt_data)
cipher = AES.new(secret.encode('utf-8'),AES.MODE_CBC,iv)
decrypt_data = cipher.decrypt(encrypt_data)
decrypt_data=decrypt_data.decode('utf-8')
print('明文:',decrypt_data)

运行结果:

密钥长度: 30
不做任何填充,但是要求密钥必须是16字节的整数倍: 123456789123456789123456789123  
明文: 12345678912345  
密文 b']\xd8\xc3\x13=\xcd\xd6\xe6\x15\xf1\xf6\xca_fE\x90'
密文的base64编码: b'WGRqREV6M04xdVlWOGZiS1gyWkZrQT09'
密文的base64编码的解码: b']\xd8\xc3\x13=\xcd\xd6\xe6\x15\xf1\xf6\xca_fE\x90'
明文: 12345678912345  

第5章CTF题

链接:https://www.anquanke.com/post/id/177122
以下为题目内容:
在这里插入图片描述 在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值