Python实现AES128_ECB_pkcs7padding数据加解密

Python实现AES128_ECB_pkcs7padding数据加解密

Python实现AES128_ECB_pkcs7padding数据加解密

由于公司测试需要,需要模拟物联网设备向业务系统上传数据和接收数据,但是由于上下行数据为加密数据,寻找了很多方法,网上的加密方法大多实现的都是普通字符串的加解密,而设备的数据格式为字节式16进制字符串,如时间‘230213091406’代表2023-02-13 09:14:06每两位为一个字节,加解密后与期望的结果不一致,所以根据需求,使用python实现需求数据的加解密。

1.实现需求

1.采用标准的分组加密对称密钥加密算法: AES128 算法 advanced encryption standard 128 algorithm
2.数据补齐算法:补齐算法使用PKCS7Padding算法
PKCS7Padding:填充的原则是,如果需要N字节补齐,报文长度少于N个字节,需要补满N个字节,补(N-len)个(N-len)。如果报文长度正好时N字节的整数倍,则需要补N个十进制N。
举例:
需要8字节补齐,123这个节符串余3个字节,8-3= 5,补满后如:123+5个十进制的5,
如果字符串长度正好是8字节的整数倍,则需要再补8个字节的十进制的8。
本协议采用AES128 ECB加密算法。补齐对齐位数为128位,即16字节。

2.代码实现

话不多说,直接上代码,代码中也标明了每个函数的功能

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
'''
-------------------------------------------------------------------------
@Project :
@File :
@IDE  :PyCharm
@Author :
@Date :
function : AES128_ECB_pkcs7Padding加密16进制字符串
-------------------------------------------------------------------------
'''

import codecs
from Crypto.Cipher import AES

def hexStr_to_hexList(hexstr):
    '''
    将16进制字符串转换成16进制列表
    :param hexstr:
    :return:
    '''
    hexstrLen = len(hexstr)
    if hexstrLen % 2 == 0:
        hexList = [f'0x{hexstr[i:i+2]}' for i in range(0, hexstrLen, 2)]
    else:
        hexstr = hexstr + '0'
        hexList = [f'0x{hexstr[i:i + 2]}' for i in range(0, hexstrLen, 2)]

    return hexList

def hexStr_to_padd7ing_hexBytes(hexStr, block_size=16):
    '''
    将16进制字符串转换成16进制字节列表,并按pksc7Padding要求进行填充
    :param hexStr:
    :param block_size:
    :return:
    '''
    hexList = hexStr_to_hexList(hexstr=hexStr)
    eval_hexList = [eval(hexval) for hexval in hexList]

    hexListLen = len(hexList)
    pad = block_size - hexListLen % block_size
    for i in range(pad):
        eval_hexList.append(pad)

    return bytearray(eval_hexList)

def keyStr_to_hexBytes(key, size=16):
    '''
    将秘钥的字符串转换成字节列表,不够16位用0补齐
    :param key:
    :param size:
    :return:
    '''
    keyList = hexStr_to_hexList(hexstr=key)
    if len(keyList) < size:
        for i in range(0, size-len(keyList)):
            keyList.append('0x00')
    evalKey = [eval(val) for val in keyList]

    return bytearray(evalKey)

def hexList_to_hexStr(hexList):
    '''
    将16进制字符串列表转换成一个16进制字符串
    :param hexList:
    :return:
    '''
    hex_str = ''
    for hex in hexList:
        str_list = hex.split('x')
        if len(str_list[1]) == 1:
            str_list[1] = '0'+str_list[1]
        hex_str = hex_str + str_list[1]

    return hex_str


def encryptData(data, key):
    '''
    加密数据
    :param data:
    :param key:
    :return:
    '''
    key_byte = keyStr_to_hexBytes(key)
    data_byte = hexStr_to_padd7ing_hexBytes(data)
    # 通过AES.MODE_ECB处理初始密码字符串,并返回cipher对象
    cipher = AES.new(key_byte, AES.MODE_ECB)
    # 输入需要加密的字符串,注意字符串长度要是16的倍数。
    encrypt_data = cipher.encrypt(data_byte)
    encrypt_data = codecs.encode(encrypt_data, 'hex').upper()
    data = str(encrypt_data).split("'")[1]  # 将Byte类型转换成字符串

    return data

def decryptData(data, key):
    '''
    解密数据
    :param data:
    :param key:
    :return:
    '''
    hexStr = hexStr_to_hexList(hexstr=str(data))
    eval_data = [eval(val) for val in hexStr]

    data_byte = bytearray(eval_data)
    key_byte = keyStr_to_hexBytes(key)

    # 通过AES.MODE_ECB处理初始密码字符串,并返回cipher对象
    cipher = AES.new(key_byte, AES.MODE_ECB)
    # 输入需要解密的字符串,注意字符串长度要是16的倍数。
    decrypt_data = cipher.decrypt(data_byte)

    unpad = lambda s: s[:-ord(s[len(s) - 1:])]
    unpad_data = unpad(s=decrypt_data)

    decrypt_hexStr_list = [hex(data) for data in unpad_data]
    data = hexList_to_hexStr(hexList=decrypt_hexStr_list)

    return data



if __name__ == "__main__":
    key = '35472468183894402541'
    data = '230213091406000028690101FFFFFFB30000000002141264200330010000'
    encrypt_data = encryptData(data=data, key=key)
    print(f'原始数据:{data}')
    print(f'加密前的数据:{encrypt_data}')
    decrypt_data = decryptData(data=encrypt_data, key=key)
    print(f'解密后的数据:{decrypt_data}')

接下来可以看看结果如何:
在这里插入图片描述
至此已完成数据的加解密,并且与预期结果一致。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值