0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

为什么要PKCS7填充?如何获取真实字符串?

冬至配饺子 来源:缪斯之子 作者:肖新苗 2022-08-23 11:04 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

由来

做爬虫逆向的时候, 经常要用到加密解密

目录

pkcs7填充: pad和unpad

crypto: 一个共同方法 + 一个例子

pkcs7填充: pad和unpad

1. 为什么要PKCS7填充?

因为PKCS7是当下各大加密算法都遵循的数据填充算法

2. 基础

1个字节有8位, 所以16个字节是128位, 比如: 一个字母A就是一个字节

16进制: 0-9, a,b,c,d,e,f, 其中a代表10,后面依次加1, 满16进一,所以 15对应\x0f,16对应\x10

转换:

int -> unicode: chr(1) 结果是 \x01

unicode -> int: ord('\x11')值为17

3. pkcs7补位规则

补位的个数: 不足16位字节的倍数,补足变成16位的倍数,如果刚好是16的倍数, 补16个字节

补位的值: 等于补位个数的unicode码, 比如:content有7位,那么补充9个字节,每个字节的值都是\x09

4. 如何获取真实字符串?

直接获取字符串的最后一个字符,转换为int即为补位的数, 然后,真实 = 原始字符串长度 - 补位的数

def pad(content: str, block_size: int = 16) -> str:
p_len = block_size - len(content) % block_size
p = p_len * chr(p_len)
return content + p

def unpad(content: str) -> str:
last_char = ord(content[-1])
# 获取真实字符串,去掉最后补位的数据
return content[:-last_char]

def test_pad():
# 计算字符数
assert 3 == len('11中'), 'pad china error'
assert 4 == len('abcd'), 'pad china error'

p1 = pad('1')
assert '1\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f' == p1, 'pad 1 error'

b = r'1\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f'
assert f"'{b}'" == repr(p1), 'pad 1 1 error'

p2 = pad('11')
assert '11\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e' == p2, 'pad 2 error'

p15 = pad('111111111122222')
assert '111111111122222\x01' == p15, 'pad 15 error'

p16 = pad('1111111111222222')
assert '1111111111222222\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' == p16, 'pad 16 error'


def test_unpad():
p1 = '1\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f'
assert '1' == unpad(p1)

p2 = '11\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e'
assert '11' == unpad(p2)

p15 = '111111111122222\x01'
assert '111111111122222' == unpad(p15)

p16 = '1111111111222222\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'
assert '1111111111222222' == unpad(p16)

crypto: 一个共同方法 + 一个例子

代码很简单, 不需要过多的解释

from base64 import b64decode, b64encode
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad

class CryptoR():

def __init__(self, key: str, iv: str):
self.aes = AES.new(key.encode('utf8'), AES.MODE_CBC, iv.encode('utf8'))

def encrypto(self, text: str) -> str:
p = pad(text.encode('utf8'), AES.block_size)
return b64encode(self.aes.encrypt(p)).decode('utf8')

def decrypto(self, text: str) -> str:
d = self.aes.decrypt(b64decode(text))
return unpad(d, AES.block_size).decode('utf8')

def call_en():
text = 'm3u8.okjx.cc|057f1eed099f2f7e'
key = 'dvyYRQlnPRCMdQSe'
iv = '057f1eed099f2f7e'
aes = CryptoR(key, iv)
e1 = aes.encrypto(text)
assert e1 == 'ncZvyrJ2IPdKSF2EmvfZAGVrtAj9D8eXnGpjPTV1QTM=', 'encrypto error'

def call_de():
text = 'HCizZLcgJfm1LvajcEBMHChheUySaJgXpuPL+L9BDW4jdd9ds5qCycVwN6SpotDujY/tok+sT2M//AeeKnDk6TrZ0gvFa1szUi8j3xg2TTZXZMW/52wuXhr1vnxrbrz4socZ2twSY1T63NiJx3XAcLe6RXfSmBxuPzstMQ0pDSSDNPT4H5hKYy1wo227zzcnxdAuwo1WTvcdaMIuXBS/9IkbqNFklzikvvdGjJjsVxRLwSd5T6v4I47CUAgVtncxpf3cKlM37lmEWpZwskJKG/IGkJRRy9K2a/tdIMWNu0JbsF0jlyMNT/kT2OS08jsRsGJPxOnpEiFIPgE6UPGUgq7+SaBHvFdSfusdqDTwBHuyXJTZBixolYEnggfr3UfWOtP1pvWR4R7bY2N7XJ7gEf6QMfjbu0YB1V4+2WX5ucy43954EniGFbUw2Zxi35y+OGgkpunPTzccVbGw871RjiU7iNVo+IXvQHgG+0FPjaWUezWYm4YAePohtxJYAqg+1XATcgFOKTUn21QQCDKAuQ=='
key = '0EAE7A71512EC09C'
iv = '675480787382e6f4'
aes = CryptoR(key, iv)
d1 = aes.decrypto(text)
d2 =
assert d1 == d2, 'decrypto error'


def main():
call_en()
call_de()


if __name__ == '__main__':
main()




审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 字符串
    +关注

    关注

    1

    文章

    594

    浏览量

    23046
  • 加密解密算法

    关注

    0

    文章

    7

    浏览量

    1741
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    网络通讯的结构及地址

    序: uint16_t port = htons(8080); // 关键:端口必须转换,否则可能解析错误 3. IP地址转换 需将“点分十进制字符串”(如\"192.168.1.1
    发表于 11-17 07:59

    MD5信息摘要算法实现一(基于蜂鸟E203协处理器)

    长度。 MD5算法填充规则如下: ①先把输入的字符串数据转换为二进制数据; ②而后通过运用多个“0”和一个“1”进行填充,“1”为结束标志位,需要加在消息的结束位置,然后填充多个“0”
    发表于 10-30 07:18

    LM3466 多 LED 电流平衡器技术手册

    到电源的数或每个 LED 的正向电压 字符串。 如果任何 LED 灯在运行过程中打开,LM3466 会自动平衡通过所有剩余活动 LED 灯的电源电流。 如 因此,即使一些 LED
    的头像 发表于 08-29 14:27 862次阅读
    LM3466 多<b class='flag-5'>串</b> LED 电流平衡器技术手册

    labview如何生成一个带字符串返回的dll

    labview如何生成一个dll,如下图,要求一个输入,类型是字符串,返回类型也是字符串
    发表于 08-28 23:20

    在Python中字符串逆序有几种方式,代码是什么

    对于一个给定的字符串,逆序输出,这个任务对于python来说是一种很简单的操作,毕竟强大的列表和字符串处理的一些列函数足以应付这些问题 了,今天总结了一下python中对于字符串的逆序输出的几种常用
    的头像 发表于 08-28 14:44 790次阅读

    harmony-utils之StrUtil,字符串工具类

    harmony-utils之StrUtil,字符串工具类 harmony-utils 简介与说明 [harmony-utils] 一款功能丰富且极易上手的HarmonyOS工具库,借助众多实用工具类
    的头像 发表于 07-03 11:32 386次阅读

    PLC通过智能网关实现HTTP协议通讯,先取得token后再提交获取JSON格式的数据文件

    如下: 限定字符串的长度:当数据类型设置为字符串即CHAR[n]时,限定字符串的最大字符数,如‘[n=24]’,范围1~128; 限定小数的位数: 当数据类型设置为浮点数即REAL/L
    发表于 06-17 16:07

    STM32C031C6使用的是UART2通讯,通过printf()函数发送字符串时,汉字错码怎么解决?

    使用的是UART2通讯,通过printf()函数发送字符串时,汉字错码(见下图),应该是KEIL哪里没有设置好的问题。 启用了UART2的中断接收,可以接收到串口调试助手的数据,但是缓存区的指针没有归零,下次接收时缓存区中的内容接续(如下图所示),不知道用什么命令来清除缓存区(即让指针归零)。
    发表于 03-07 12:30

    请问如何用Verilog实现将ascaii码数值字符串转换成定点数?

    我需要接收一个ascaii码字符串,内容是12位有效数字的数值,带小数。我不知道怎么把小数部分转换成定点数。
    发表于 01-23 21:57

    字符串在数据库中的存储方式

    数据库是现代信息技术中存储和管理数据的核心组件。字符串作为最常见的数据类型之一,在数据库中的存储方式对其性能和可扩展性有着重要影响。 数据类型 固定长度字符串 :如CHAR类型,它为每个字符串分配
    的头像 发表于 01-07 15:41 1263次阅读

    字符串在编程中的应用实例

    字符串在编程中有着广泛的应用,它们被用于表示文本数据、处理用户输入、构建动态内容等。以下是一些字符串在编程中的应用实例: 1. 用户输入与输出 用户输入 :程序通常需要从用户那里获取输入,这些输入通
    的头像 发表于 01-07 15:33 1145次阅读

    字符串字符数组的区别

    在编程语言中,字符串字符数组是两种基本的数据结构,它们都用于存储和处理文本数据。尽管它们在功能上有一定的重叠,但在内部表示、操作方式和使用场景上存在显著差异。 1. 内部表示 字符串 字符串
    的头像 发表于 01-07 15:29 1699次阅读

    字符串反转的实现方式

    在编程中,字符串反转是一个基础而重要的操作,它涉及到将一个字符串中的字符顺序颠倒过来。这个操作在多种编程语言中都有不同的实现方式,本文将探讨几种常见的字符串反转方法。 1. 递归方法
    的头像 发表于 01-07 15:27 1256次阅读

    字符串处理方法 字符串转数字的实现

    在编程中,将字符串转换为数字是一个常见的需求。不同的编程语言有不同的方法来实现这一功能。以下是一些常见编程语言中的字符串转数字的实现方法: Python 在Python中,可以使用内置的 int
    的头像 发表于 01-07 15:26 1418次阅读

    养成良好的编程习惯|堆内存初值不一定是0

    ;} 代码很简单,使用 malloc 申请一段堆内存,假设内存空间足够大。 通过 getchar 配合 while 循环,从标准输入获取一个字符串,直到遇到换行符结束。 最后就是把获取字符串
    的头像 发表于 12-18 09:14 575次阅读