加入收藏 | 设为首页 | 会员中心 | 我要投稿 咸宁站长网 (https://www.0715zz.cn/)- 文字识别、智能机器人、媒体智能、低代码、运维!
当前位置: 首页 > 运营中心 > 交互 > 正文

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

发布时间:2022-08-25 10:32:38 所属栏目:交互 来源:互联网
导读:由来 做爬虫逆向的时候, 经常要用到加密解密 目录 pkcs7填充: pad和unpad crypto: 一个共同方法 + 一个例子 pkcs7填充: pad和unpad 1. 为什么要PKCS7填充? 因为PKCS7是当下各大加密算法都遵循的数据填充算法 2. 基础 1个字节有8位, 所以16个字节是128位, 比
  由来
 
  做爬虫逆向的时候, 经常要用到加密解密
 
  目录
 
  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 '1x0fx0fx0fx0fx0fx0fx0fx0fx0fx0fx0fx0fx0fx0fx0f' == p1, 'pad 1 error'
 
  b = r'1x0fx0fx0fx0fx0fx0fx0fx0fx0fx0fx0fx0fx0fx0fx0f'
  assert f"'{b}'" == repr(p1), 'pad 1 1 error'
 
  p2 = pad('11')
  assert '11x0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0e' == p2, 'pad 2 error'
 
  p15 = pad('111111111122222')
  assert '111111111122222x01' == p15, 'pad 15 error'
 
  p16 = pad('1111111111222222')
  assert '1111111111222222x10x10x10x10x10x10x10x10x10x10x10x10x10x10x10x10' == p16, 'pad 16 error'
 
 
  def test_unpad():
  p1 = '1x0fx0fx0fx0fx0fx0fx0fx0fx0fx0fx0fx0fx0fx0fx0f'
  assert '1' == unpad(p1)
 
  p2 = '11x0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0ex0e'
  assert '11' == unpad(p2)
 
  p15 = '111111111122222x01'
  assert '111111111122222' == unpad(p15)
 
  p16 = '1111111111222222x10x10x10x10x10x10x10x10x10x10x10x10x10x10x10x10'
  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()
 

(编辑:咸宁站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读