python实现aes加密解密

引子:

   在windows中python3使用  pycryptodemo 模块实现Aes加密解密。Aes加密有多种方式,自己可以上网了解下。 AES是每16位一加密,并且保证key和vi都是16位的。废话不多说直接上代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import base64
from Crypto.Cipher import AES
from binascii import b2a_hex,a2b_hex
 
 
class PrpCrypt(object):
    def __init__(self,key,iv):
        self.key=key.encode('utf-8')
        self.mode=AES.MODE_CBC
        self.iv=iv.encode('utf-8')
 
    def pad_byte(self, b):
        '''
        1 先计算所传入bytes类型文本与16的余数
        2 在将此余数转成bytes 当然用0补位也可以
        3 已知了 余数 那么就用余数*被转成的余数,就得到了需要补全的bytes
        4 拼接原有文本和补位
        :param b: bytes类型的文本
        :return: 返回补全后的bytes文本
        '''
        bytes_num_to_pad = AES.block_size - (len(b) % AES.block_size)
        # python3 中默认unicode转码
        # 实际上byte_to_pad 就已经 将 数字转成了unicode 对应的字符  即使你的入参正好是16的倍数,那么bytes也是把列表整体的转码也是有值的
        # 后边解密的匿名函数 拿到最后一个数字后,就知道应该截取的长度,在反着切片就行了
        # 这样保证了数据的完整性
        byte_to_pad = bytes([bytes_num_to_pad])
        padding = byte_to_pad * bytes_num_to_pad
        padded = b + padding
        return padded
 
    def encrypt(self,text):
        '''
        1 先生成aes实例
        2 对传入的text转成bytes
        3 对传入的text补全
        4 调用encrypt 加密 得到密文
        5 先将密文转16进制,在将16进制用base64转码,然后在将得到的base64解码
        其实在步骤4 就已经完成了aes加密,我所在的公司加密比较复杂 ,需要的可以直接返回步骤4的值
 
        :param text:
        :return:
        '''
        cryptor = AES.new(self.key,self.mode,self.iv)
        text = text.encode('utf-8')
        text = self.pad_byte(text)
        self.ciphertext = cryptor.encrypt(text)
        cryptbase64 = base64.b64encode(b2a_hex(self.ciphertext)).decode('utf8')
        return cryptbase64
 
 
    def decrypt(self,text):
        '''
        解密和加密的顺序是相反的
        1 定义匿名函数,去掉补位
        2 base64解码
        3 生成aes实例
        4 16进制转2进制
        5 使用decrypt解码  得到补全的bytes类型明文
 
        :param text:
        :return:  解密且去掉补位的明文
        '''
        unpad = lambda s: s[:-ord(s[len(s) - 1:])]
        base64Str = base64.b64decode(text.encode('utf8'))
        cryptor = AES.new(self.key, self.mode, self.iv)
        aesStr = cryptor.decrypt(a2b_hex(base64Str))
        aesStr = str(unpad(aesStr), encoding='utf8')
        return aesStr
 
 
 
if __name__ == '__main__':
    data='sadfsasdgsdfgdsf123'
    pc=PrpCrypt('daajanbaqa654321','1234567890123456')
    redata = pc.encrypt(data)
    print(redata)
    result=pc.decrypt(redata)
    print(result)

  思路:

      这里引用一句前辈的话,思路很重要。具体的怎么实现反而在其次。

      1 因为Aes是按照16位加密的,key和iv都好说,可以直接设置成定长的16位。

      2 因为传入的数据和传回的数据不是定长的,所以加密的时候要先判断是否是16位的倍数,如果不够那么就补全。

      3 问题是对端拿到数据后怎么知道从哪里截取。

        1 在对传入数据做是否16位判断的时候,你就知道了要补多少位,将这个数字转成bytes类型,python3中默认unicode码。

        2 对端拿到数据后,先截取最后一位,在根据unicode转成对应数字,那么对端就知道了从哪开始截取。

        3 看下unicode和utf8的关系,utf8是unicode实现的一种方式

posted @   Yuan_x  阅读(8185)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示