逆向使用的公共加密解密的方法与算法

pythonAES加密解密方法-ECB模式

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

def decrypt_aes(ciphertext, key):
    ciphertext = base64.b64decode(ciphertext)                           # 使用base64解码密文
    cipher = AES.new(key.encode(), AES.MODE_ECB)                        # 创建AES对象并指定使用ECB模式和PKCS7填充
    plaintext = cipher.decrypt(ciphertext)                              # 解密密文
    plaintext = unpad(plaintext, AES.block_size)                        # 去除填充数据
    return plaintext.decode('utf-8')

def encrypt_aes(plaintext, key):
    cipher = AES.new(key.encode(), AES.MODE_ECB)                        # 创建AES对象并指定使用ECB模式和PKCS7填充
    padded_plaintext = pad(plaintext.encode(), AES.block_size)          # 对明文进行填充
    ciphertext = cipher.encrypt(padded_plaintext)                       # 加密明文
    encrypted_text = base64.b64encode(ciphertext).decode()              # 使用base64进行编码
    return encrypted_text

使用ddddocr识别图片滑块的距离

import ddddocr
def get_distance():                                                 # 使用ocr识别滑块距离
    with open('./block.png', 'rb') as f:
        target_bytes = f.read()
    with open('./canvas.png', 'rb') as f:
        background_bytes = f.read()
    res = self.det.slide_match(target_bytes, background_bytes, simple_target=True)  # target 的四个值就是缺口位置的左上角和右下角的左边位置
    distance = res['target'][0]
    return distance

使用OpenCV识别滑块缺口距离

import cv2
import PIL
import numpy as np
from PIL import Image
from pathlib import Path


def imshow(img, winname='test', delay=0):
    """cv2展示图片"""
    cv2.imshow(winname, img)
    cv2.waitKey(delay)
    cv2.destroyAllWindows()


def pil_to_cv2(img):
    """
    pil转cv2图片
    :param img: pil图像, <type 'PIL.JpegImagePlugin.JpegImageFile'>
    :return: cv2图像, <type 'numpy.ndarray'>
    """
    img = cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
    return img


def bytes_to_cv2(img):
    """
    二进制图片转cv2
    :param img: 二进制图片数据, <type 'bytes'>
    :return: cv2图像, <type 'numpy.ndarray'>
    """
    # 将图片字节码bytes, 转换成一维的numpy数组到缓存中
    img_buffer_np = np.frombuffer(img, dtype=np.uint8)
    # 从指定的内存缓存中读取一维numpy数据, 并把数据转换(解码)成图像矩阵格式
    img_np = cv2.imdecode(img_buffer_np, 1)
    return img_np


def cv2_open(img, flag=None):
    """
    统一输出图片格式为cv2图像, <type 'numpy.ndarray'>
    :param img: <type 'bytes'/'numpy.ndarray'/'str'/'Path'/'PIL.JpegImagePlugin.JpegImageFile'>
    :param flag: 颜色空间转换类型, default: None
        eg: cv2.COLOR_BGR2GRAY(灰度图)
    :return: cv2图像, <numpy.ndarray>
    """
    if isinstance(img, bytes):
        img = bytes_to_cv2(img)
    elif isinstance(img, (str, Path)):
        img = cv2.imread(str(img))
    elif isinstance(img, np.ndarray):
        img = img
    elif isinstance(img, PIL.Image.Image):
        img = pil_to_cv2(img)
    else:
        raise ValueError(f'输入的图片类型无法解析: {type(img)}')
    if flag is not None:
        img = cv2.cvtColor(img, flag)
    return img


def get_distance(bg, tp, im_show=False, save_path=None):
    """
    :param bg: 背景图路径或 Path 对象或图片二进制
               eg: 'assets/bg.jpg'、Path('assets/bg.jpg')
    :param tp: 缺口图路径或 Path 对象或图片二进制
               eg: 'assets/tp.jpg'、Path('assets/tp.jpg')
    :param im_show: 是否显示结果, <type 'bool'>; default: False
    :param save_path: 保存路径, <type 'str'/'Path'>; default: None
    :return: 缺口位置
    """
    # 读取图片
    bg_img = cv2_open(bg)
    tp_gray = cv2_open(tp, flag=cv2.COLOR_BGR2GRAY)

    # 金字塔均值漂移
    bg_shift = cv2.pyrMeanShiftFiltering(bg_img, 5, 50)

    # 边缘检测
    tp_gray = cv2.Canny(tp_gray, 255, 255)
    bg_gray = cv2.Canny(bg_shift, 255, 255)

    # 目标匹配
    result = cv2.matchTemplate(bg_gray, tp_gray, cv2.TM_CCOEFF_NORMED)
    # 解析匹配结果
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)

    distance = max_loc[0]
    if save_path or im_show:
        # 需要绘制的方框高度和宽度
        tp_height, tp_width = tp_gray.shape[:2]
        # 矩形左上角点位置
        x, y = max_loc
        # 矩形右下角点位置
        _x, _y = x + tp_width, y + tp_height
        # 绘制矩形
        bg_img = cv2_open(bg)
        cv2.rectangle(bg_img, (x, y), (_x, _y), (0, 0, 255), 2)
        # 保存缺口识别结果到背景图
        if save_path:
            save_path = Path(save_path).resolve()
            save_path = save_path.parent / f"{save_path.stem}{save_path.suffix}"
            save_path = save_path.__str__()
            cv2.imwrite(save_path, bg_img)
        # 显示缺口识别结果
        if im_show:
            imshow(bg_img)
    return distance


# with open("./img/slide_bg.jpg", "rb") as f:
#     bg_img = f.read()
# with open("./img/slide_slice.png", "rb") as f:
#     slice_img = f.read()
# distance = get_distance(bg_img, slice_img)
# print(distance)

关于轨迹的生成-算法

轨迹主要是针对滑块的,可以利用贝塞尔曲线、缓动函数等,来生成正确的轨迹,基于贝塞尔曲线的可以参考:https://github.com/2833844911/gurs ,吾爱上也有个大佬利用 tanharctan 函数整合生成轨迹的:https://www.52pojie.cn/forum.php?mod=viewthread&tid=1162979

基于缓动函数的可以参考以下代码(来源于互联网收集):

import random


def __ease_out_expo(sep):
    """
    缓动函数 easeOutExpo
    参考:https://easings.net/zh-cn#easeOutExpo
    """
    if sep == 1:
        return 1
    else:
        return 1 - pow(2, -10 * sep)


def get_slide_track(distance):
    """
    根据滑动距离生成滑动轨迹
    :param distance: 需要滑动的距离
    :return: 滑动轨迹<type 'list'>: [[x,y,t], ...]
        x: 已滑动的横向距离
        y: 已滑动的纵向距离, 除起点外, 均为0
        t: 滑动过程消耗的时间, 单位: 毫秒
    """

    if not isinstance(distance, int) or distance < 0:
        raise ValueError(f"distance类型必须是大于等于0的整数: distance: {distance}, type: {type(distance)}")
    # 初始化轨迹列表
    slide_track = [
        [random.randint(-50, -10), random.randint(-50, -10), 0],
        [0, 0, 0],
    ]
    # 共记录count次滑块位置信息
    count = 30 + int(distance / 2)
    # 初始化滑动时间
    t = random.randint(50, 100)
    # 记录上一次滑动的距离
    _x = 0
    _y = 0
    for i in range(count):
        # 已滑动的横向距离
        x = round(__ease_out_expo(i / count) * distance)
        # 滑动过程消耗的时间
        t += random.randint(10, 20)
        if x == _x:
            continue
        slide_track.append([x, _y, t])
        _x = x
    slide_track.append(slide_track[-1])
    return slide_track

JS 原生的AES加密解密

const CryptoJS = require('crypto-js');  //引用AES源码js
const key = CryptoJS.enc.Utf8.parse("12dfa21a2fdsgSAW");  //十六位十六进制数作为密钥
const iv = CryptoJS.enc.Utf8.parse('12dfa21a2fdsgSAW');   //十六位十六进制数作为密钥偏移量

//加密方法
export function Encrypt(word){
  let srcs = CryptoJS.enc.Utf8.parse(word);
  let encrypted = CryptoJS.AES.encrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
  return encrypted.ciphertext.toString().toUpperCase();
}
//解密方法
export function Decrypt(word){
  let encryptedHexStr = CryptoJS.enc.Hex.parse(word);
  let srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
  let decrypt = CryptoJS.AES.decrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
  let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
  return decryptedStr.toString();
}
import CryptoJS from 'crypto-js/crypto-js'

// 默认的 KEY 与 iv 如果没有给
const KEY = CryptoJS.enc.Utf8.parse('zczyL2d9DfhLZO0z');
const IV = CryptoJS.enc.Utf8.parse('412SFA342442zczy');
/**
 * AES加密 :字符串 key iv  返回base64
 */
export function Encrypt(word, keyStr, ivStr) {
  let key = KEY;
  let iv = IV;

  if (keyStr) {
    key = CryptoJS.enc.Utf8.parse(keyStr);
    iv = CryptoJS.enc.Utf8.parse(ivStr);
  }

  let srcs = CryptoJS.enc.Utf8.parse(word);
  var encrypted = CryptoJS.AES.encrypt(srcs, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.ZeroPadding
  });
  // console.log("-=-=-=-", encrypted.ciphertext)
  return CryptoJS.enc.Base64.stringify(encrypted.ciphertext);

}
/**
 * AES 解密 :字符串 key iv  返回base64
 *
 */
export function Decrypt(word, keyStr, ivStr) {
  let key  = KEY;
  let iv = IV;

  if (keyStr) {
    key = CryptoJS.enc.Utf8.parse(keyStr);
    iv = CryptoJS.enc.Utf8.parse(ivStr);
  }

  let base64 = CryptoJS.enc.Base64.parse(word);
  let src = CryptoJS.enc.Base64.stringify(base64);

  var decrypt = CryptoJS.AES.decrypt(src, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.ZeroPadding
  });

  var decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
  return decryptedStr.toString();
}
posted @ 2023-09-14 13:57  愺様  阅读(52)  评论(0编辑  收藏  举报