当前位置:   article > 正文

python实现AES各种模式数据加密_pythonaes加解密

pythonaes加解密

AES简介

AES(Advanced Encryption Standard,高级加密标准)是一种广泛使用的对称分组加密技术。它使用固定长度的密钥和分组大小来加密和解密数据,确保数据的机密性和完整性。下面将详细介绍AES加密的原理、特点以及应用。

原理

AES加密的核心在于其加密算法和密钥管理。它采用一个固定的分组大小(通常是128位),将待加密的数据分成多个分组,并对每个分组进行加密。加密过程中,使用一个密钥来生成加密所需的子密钥,这些子密钥与明文分组进行特定的数学运算,生成密文分组。解密过程则是使用相同的密钥和算法,将密文分组还原为明文分组。

AES支持三种长度的密钥:128位、192位和256位。密钥的长度决定了加密的强度和安全性。一般来说,密钥长度越长,加密强度越高,但加密和解密的速度也会相应降低。

特点

  1. 高加密强度:AES算法提供了比传统加密算法更高的加密强度,能够有效地抵抗各种攻击手段。
  2. 快速加密:AES算法的加密和解密速度非常快,适用于大量数据的实时加密和解密需求。
  3. 灵活性:AES支持多种分组大小和密钥长度,可以根据实际需求进行调整。
  4. 安全性:AES算法经过严格的数学分析和安全评估,被认为是安全的加密算法。

当然,AES加密也存在一些潜在的问题。由于是对称加密算法,AES的安全性完全依赖于密钥的保密性。如果密钥被泄露或丢失,加密的数据就可能被轻易解密。因此,在使用AES加密时,需要采取严格的密钥管理措施,确保密钥的安全存储和传输。

应用

AES加密在各个领域都有广泛的应用,包括网络通信、数据存储、电子支付等。它被广泛用于保护敏感信息的机密性,防止未经授权的访问和泄露。例如,在网络通信中,AES可以用于加密传输的数据包,确保数据在传输过程中的安全性;在数据存储中,AES可以用于加密存储的敏感数据,防止数据被非法获取或篡改。

总的来说,AES加密是一种高效、安全且广泛应用的对称加密算法。它提供了强大的加密强度和快速的加密速度,能够满足各种场景下的安全需求。然而,在使用AES加密时,需要注意密钥的管理和保护,以确保加密的安全性。

环境安装

使用pip安装pycryptodome库:

pip install pycryptodome
  • 1

AES加密模式介绍

AES支持多种工作模式,这些模式决定了如何处理密钥和明文,以及如何在多个数据块之间传递信息。常见的AES工作模式包括:

  • ECB (Electronic Codebook): 每个数据块独立加密,不使用链接。安全性较低,因为相同的明文块会产生相同的密文块。
  • CBC (Cipher Block Chaining): 每个数据块在加密前与前一个密文块进行异或操作。提高了安全性,但要求一个初始化向量(IV)。
  • CFB (Cipher Feedback): 加密器的输出反馈回输入,与下一个明文块进行异或操作。也要求IV。
  • OFB (Output Feedback): 加密器的输出用于异或下一个明文块,但加密器的输入是前一个加密器的输出。同样需要IV。
  • CTR (Counter): 使用一个计数器与密钥进行加密,然后结果与明文块进行异或操作。也要求一个非密文的初始化计数器。

使用各种AES模式编写示例

from Crypto.Cipher import AES
import base64
import binascii

# 数据类
class MData():
    def __init__(self, data = b"",characterSet='utf-8'):
        # data肯定为bytes
        self.data = data
        self.characterSet = characterSet
  
    def saveData(self,FileName):
        with open(FileName,'wb') as f:
            f.write(self.data)

    def fromString(self,data):
        self.data = data.encode(self.characterSet)
        return self.data

    def fromBase64(self,data):
        self.data = base64.b64decode(data.encode(self.characterSet))
        return self.data

    def fromHexStr(self,data):
        self.data = binascii.a2b_hex(data)
        return self.data

    def toString(self):
        return self.data.decode(self.characterSet)

    def toBase64(self):
        return base64.b64encode(self.data).decode()

    def toHexStr(self):
        return binascii.b2a_hex(self.data).decode()

    def toBytes(self):
        return self.data

    def __str__(self):
        try:
            return self.toString()
        except Exception:
            return self.toBase64()


### 封装类
class AEScryptor():
    def __init__(self,key,mode,iv = '',paddingMode= "NoPadding",characterSet ="utf-8"):
        '''
        构建一个AES对象
        key: 秘钥,字节型数据
        mode: 使用模式:AES.MODE_CBC, AES.MODE_ECB, AES.MODE_GCM(秘钥长度32,NoPadding)
        iv: iv偏移量,字节型数据
        paddingMode: 填充模式,默认为NoPadding, 可选NoPadding,ZeroPadding,PKCS5Padding,PKCS7Padding
        characterSet: 字符集编码
        '''
        self.key = key
        self.mode = mode
        self.iv = iv
        self.characterSet = characterSet
        self.paddingMode = paddingMode
        self.data = ""

    def __ZeroPadding(self,data):
        data += b'\x00'
        while len(data) % 16 != 0:
            data += b'\x00'
        return data

    def __StripZeroPadding(self,data):
        data = data[:-1]
        while len(data) % 16 != 0:
            data = data.rstrip(b'\x00')
            if data[-1] != b"\x00":
                break
        return data

    def __PKCS5_7Padding(self,data):
        needSize = 16-len(data) % 16
        if needSize == 0:
            needSize = 16
        return data + needSize.to_bytes(1,'little')*needSize

    def __StripPKCS5_7Padding(self,data):
        paddingSize = data[-1]
        return data.rstrip(paddingSize.to_bytes(1,'little'))

    def __paddingData(self,data):
        if self.paddingMode == "NoPadding":
		    if self.mode == AES.MODE_GCM:
				return
		    else:
            	if len(data) % 16 == 0:
                    return data
            	else:
                    return self.__ZeroPadding(data)
        elif self.paddingMode == "ZeroPadding":
            return self.__ZeroPadding(data)
        elif self.paddingMode == "PKCS5Padding" or self.paddingMode == "PKCS7Padding":
            return self.__PKCS5_7Padding(data)
        else:
            print("不支持Padding")

    def __stripPaddingData(self,data):
        if self.paddingMode == "NoPadding":
		    if self.mode == AES.MODE_GCM:
				return data
		    elsereturn self.__StripZeroPadding(data)
            	
        elif self.paddingMode == "ZeroPadding":
            return self.__StripZeroPadding(data)

        elif self.paddingMode == "PKCS5Padding" or self.paddingMode == "PKCS7Padding":
            return self.__StripPKCS5_7Padding(data)
        else:
            print("不支持Padding")

    def setCharacterSet(self,characterSet):
        '''
        设置字符集编码
        characterSet: 字符集编码
        '''
        self.characterSet = characterSet

    def setPaddingMode(self,mode):
        '''
        设置填充模式
        mode: 可选NoPadding,ZeroPadding,PKCS5Padding,PKCS7Padding
        '''
        self.paddingMode = mode

    def decryptFromBase64(self,entext):
        '''
        从base64编码字符串编码进行AES解密
        entext: 数据类型str
        '''
        mData = MData(characterSet=self.characterSet)
        self.data = mData.fromBase64(entext)
        return self.__decrypt()

    def decryptFromHexStr(self,entext):
        '''
        从hexstr编码字符串编码进行AES解密
        entext: 数据类型str
        '''
        mData = MData(characterSet=self.characterSet)
        self.data = mData.fromHexStr(entext)
        return self.__decrypt()

    def decryptFromString(self,entext):
        '''
        从字符串进行AES解密
        entext: 数据类型str
        '''
        mData = MData(characterSet=self.characterSet)
        self.data = mData.fromString(entext)
        return self.__decrypt()

    def decryptFromBytes(self,entext):
        '''
        从二进制进行AES解密
        entext: 数据类型bytes
        '''
        self.data = entext
        return self.__decrypt()

    def encryptFromString(self,data):
        '''
        对字符串进行AES加密
        data: 待加密字符串,数据类型为str
        '''
        self.data = data.encode(self.characterSet)
        return self.__encrypt()

    def __encrypt(self):
        if self.mode == AES.MODE_CBC:
            aes = AES.new(self.key,self.mode,self.iv) 
        elif self.mode == AES.MODE_ECB:
            aes = AES.new(self.key,self.mode) 
        elif self.mode == AES.MODE_GCM:
            aes = AES.new(self.key,self.mode,self.iv) 
        else:
            print("不支持这种模式")  
            return           
		if self.mode == AES.MODE_GCM:
	        # data = self.__paddingData(self.data)
		    ciphertext, auth_tag = aes.encrypt_and_digest(self.data)
	        enData = ciphertext + auth_tag
		    # enData = aes.encrypt(data)
	        return MData(enData)
		else:
            data = self.__paddingData(self.data)
            enData = aes.encrypt(data)
            return MData(enData)

    def __decrypt(self):
        if self.mode == AES.MODE_CBC:
            aes = AES.new(self.key,self.mode,self.iv) 
        elif self.mode == AES.MODE_ECB:
            aes = AES.new(self.key,self.mode) 
		elif self.mode == AES.MODE_GCM:
            aes = AES.new(self.key,self.mode,self.iv) 
        else:
            print("不支持这种模式")  
            return  

		if self.mode == AES.MODE_GCM:
		    ciphertext = self.data[:-16]
		    auth_tag = self.data[-16:]
		    data = aes.decrypt_and_verify(ciphertext, auth_tag)
		    mData = MData(data,characterSet=self.characterSet)
	        return mData
		else:         
	        data = aes.decrypt(self.data)
	        mData = MData(self.__stripPaddingData(data),characterSet=self.characterSet)
	        return mData


if __name__ == '__main__':
    key = b"01234567891234560123456789123456"
    iv =  b"0123456789123456"
    data = "二月二龙抬头"
    # aes = AEScryptor(key,AES.MODE_CBC,iv,paddingMode= "ZeroPadding",characterSet='utf-8')
    # aes = AEScryptor(key,AES.MODE_ECB,iv,paddingMode= "ZeroPadding",characterSet='utf-8')
    aes = AEScryptor(key,AES.MODE_GCM,iv,paddingMode= "NoPadding",characterSet='utf-8')
    rData = aes.encryptFromString(data)
    print("密文toHexStr:",rData.toHexStr())
    print("密文:",rData.toBase64())
    rData = aes.decryptFromBase64(rData.toBase64())
    print("明文:",rData)


  • 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
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号