模仿抖音用户ID加密ID的算法MB4E,提高自己平台ID安全性

news2024/12/26 12:48:01

先看抖音的格式 对ID加密的格式 MB4EENgLILJPeQKhJht-rjcc6y0ECMk_RGTceg6JBAA=

需求是 同一个ID 比如 413884936367560  每次获取得到的加密ID都是不同的,最终解密的ID都是413884936367560

注意这是一个加密后可解密原文的方式,不是单向加密

那么如下进行一个模仿。目前拆测 固定前缀MB4E和后缀BAA= 这俩要么和机房有关 要么就是和场景有关的一个标识性设置。

下面分别由Python和golang进行实现

记的安装 pip install pycryptodome

from Cryptodome.Cipher import AES
import base64
import os

# 固定前缀和后缀  这俩要么和机房有关 要么就是和场景有关的一个标识性设置
PREFIX = "MB4EE"
SUFFIX = "BAA="

# 密钥(假设为16字节)
KEY = b'1234567890123456'


def pad(data):
    # PKCS7 填充
    padding_len = 16 - (len(data) % 16)
    return data + bytes([padding_len] * padding_len)


def unpad(data):
    # 去除 PKCS7 填充
    return data[:-data[-1]]


def encrypt_id(user_id):
    # 生成随机IV(16字节)
    iv = os.urandom(16)

    # 创建AES加密器
    cipher = AES.new(KEY, AES.MODE_CFB, iv)

    # 加密用户ID
    user_id_bytes = user_id.to_bytes((user_id.bit_length() + 7) // 8, 'big')
    padded_user_id = pad(user_id_bytes)
    encrypted_id = cipher.encrypt(padded_user_id)

    # 将IV和加密结果编码为URL安全的Base64
    encoded_id = base64.urlsafe_b64encode(iv + encrypted_id).decode('utf-8')

    # 去除编码结果中的填充字符 '='
    encoded_id = encoded_id.rstrip('=')

    # 添加固定前缀和后缀
    sec_user_id = PREFIX + encoded_id + SUFFIX

    return sec_user_id


def decrypt_id(sec_user_id):
    # 去除固定前缀和后缀
    encoded_id = sec_user_id[len(PREFIX):-len(SUFFIX)]

    # 解码URL安全的Base64,并手动添加填充字符 '='
    padding_len = 4 - (len(encoded_id) % 4)
    encoded_id += '=' * padding_len

    # 解码Base64
    decoded_id = base64.urlsafe_b64decode(encoded_id)

    # 提取IV和加密结果
    iv = decoded_id[:16]
    encrypted_id = decoded_id[16:]

    # 创建AES解密器
    cipher = AES.new(KEY, AES.MODE_CFB, iv)

    # 解密用户ID
    padded_user_id = cipher.decrypt(encrypted_id)
    user_id_bytes = unpad(padded_user_id)
    user_id = int.from_bytes(user_id_bytes, 'big')

    return user_id


# 示例
user_id = 413884936367560
sec_user_id = encrypt_id(user_id)
print(f"Encrypted ID: {sec_user_id}")

decrypted_id = decrypt_id(sec_user_id)
print(f"Decrypted ID: {decrypted_id}")

运行结果如下

go语言的实现

package main

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"encoding/base64"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"strings"
)

// 固定前缀和后缀
const (
	PREFIX = "MB4EE"
	SUFFIX = "BAA="
)

// 密钥(假设为16字节)
var key = []byte("1234567890123456")

// 填充数据
func pad(data []byte) []byte {
	padding := aes.BlockSize - len(data)%aes.BlockSize
	padtext := make([]byte, padding)
	for i := range padtext {
		padtext[i] = byte(padding)
	}
	return append(data, padtext...)
}

// 去除填充数据
func unpad(data []byte) ([]byte, error) {
	length := len(data)
	unpadding := int(data[length-1])
	if unpadding > length {
		return nil, errors.New("unpad error. This could happen when incorrect encryption key is used")
	}
	return data[:(length - unpadding)], nil
}

// 加密用户ID
func encryptID(userID int64) (string, error) {
	// 生成随机IV(16字节)
	iv := make([]byte, aes.BlockSize)
	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
		return "", err
	}

	// 创建AES加密器
	block, err := aes.NewCipher(key)
	if err != nil {
		return "", err
	}

	// 加密用户ID
	userIDBytes := make([]byte, 8)
	binary.BigEndian.PutUint64(userIDBytes, uint64(userID))
	paddedUserID := pad(userIDBytes)
	ciphertext := make([]byte, len(paddedUserID))
	mode := cipher.NewCFBEncrypter(block, iv)
	mode.XORKeyStream(ciphertext, paddedUserID)

	// 将IV和加密结果编码为URL安全的Base64
	encodedID := base64.URLEncoding.EncodeToString(append(iv, ciphertext...))

	// 去除编码结果中的填充字符 '='
	encodedID = strings.TrimRight(encodedID, "=")

	// 添加固定前缀和后缀
	secUserID := PREFIX + encodedID + SUFFIX

	return secUserID, nil
}

// 解密用户ID
func decryptID(secUserID string) (int64, error) {
	// 去除固定前缀和后缀
	encodedID := secUserID[len(PREFIX) : len(secUserID)-len(SUFFIX)]

	// 解码URL安全的Base64,并手动添加填充字符 '='
	paddingLen := 4 - len(encodedID)%4
	encodedID += strings.Repeat("=", paddingLen)

	// 解码Base64
	decodedID, err := base64.URLEncoding.DecodeString(encodedID)
	if err != nil {
		return 0, err
	}

	// 提取IV和加密结果
	iv := decodedID[:aes.BlockSize]
	ciphertext := decodedID[aes.BlockSize:]

	// 创建AES解密器
	block, err := aes.NewCipher(key)
	if err != nil {
		return 0, err
	}

	// 解密用户ID
	mode := cipher.NewCFBDecrypter(block, iv)
	mode.XORKeyStream(ciphertext, ciphertext)
	paddedUserID, err := unpad(ciphertext)
	if err != nil {
		return 0, err
	}

	// 转换为int64
	userID := int64(binary.BigEndian.Uint64(paddedUserID))

	return userID, nil
}

func main() {
	userID := int64(66015130374)
	secUserID, err := encryptID(userID)
	if err != nil {
		fmt.Println("Encrypt error:", err)
		return
	}
	fmt.Println("Encrypted ID:", secUserID)

	decryptedID, err := decryptID(secUserID)
	if err != nil {
		fmt.Println("Decrypt error:", err)
		return
	}
	fmt.Println("Decrypted ID:", decryptedID)
}

运行结果如下

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2137079.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows 环境下 vscode 配置 C/C++ 环境

vscode Visual Studio Code(简称 VSCode)是一个由微软开发的免费、开源的代码编辑器。它支持多种编程语言,并提供了代码高亮、智能代码补全、代码重构、调试等功能,非常适合开发者使用。VSCode 通过安装扩展(Extension…

abVIEW 可以同时支持脚本编程和图形编程

LabVIEW 可以同时支持脚本编程和图形编程,但主要依赖其独特的 图形编程 环境(G语言),其中程序通过连线与节点来表示数据流和功能模块。不过,LabVIEW 也支持通过以下方式实现脚本编程的能力: 1. 调用外部脚本…

第4步CentOS配置SSH服务用SSH终端XShell等连接方便文件上传或其它操作

宿主机的VM安装CENTOS文件无法快速上传,也不方便输入命令行,用SSH终端xshell连接虚拟机的SSH工具就方便多了,实现VM所在宿主机Win10上的xshell能连接vm的centos要实现以下几个环节 1、确保宿主机与虚拟机的连通性。 2、虚拟机安装SSH服务&…

ESP8266_MicroPython——GPIO_LED_KEY_外部中断

MicroPython 文章目录 MicroPython前言一、安装软件二、点亮第一颗LED灯三、KEY按键四、外部中断总结 前言 MicroPython比较简单但是没有系统的更新过文章,准备写一下ESP8266——MicroPython的文章做一个系列。 一、安装软件 安装开发软件 Thonny,安装…

豆包MarsCode编程助手:产品功能解析与应用场景探索!

随着现代技术的不断进化升级,人工智能正在逐步改变着我们的日常工作方式。特别是对于复杂的项目,代码编写、优化、调试、测试等环节充满挑战。为了简化这些环节、提高开发效率,许多智能编程工具应运而生,豆包MarsCode 编程助手就是…

瑞芯微Android6 内核编译报错解决方案

1、报错内容如下图所示 错误内容: Kernel: arch/arm/boot/zImage is ready make: *** [kernel.img] Error 127 2、分析与解决方法 由于之前在ubuntu环境下编译没问题,现在是在centos环境下重新编译的时候报错,所以经过分析对比两个环境的…

非关系型数据库Redis

文章目录 一,关系型数据库和非关系型数据可区别1.关系型数据库2.非关系型数据库3.区别3.1存储方式3.2扩展方式3.2事务性的支持 二,非关系型数据为什么产生三,Redis1.Redis是什么2.Redis优点3.Redis适用范围4. Redis 快的原因4.1 基于内存运行…

1-4微信小程序基础

模板配置 🌮🌮目标 1.能够使用WXML模板语法渲染页面结构2.能够使用WXSS样式渲染标签样式3.能够使用app.json对小程序进行全局配置4.能够使用page.json对小程序页面进行个性化配置5.如何发起网络数据请求 数据绑定的基本原则 在data中定义数据在WXML中…

(论文解读)Visual-Language Prompt Tuning with Knowledge-guided Context Optimization

Comment: accepted by CVPR2023 基于知识引导上下文优化的视觉语言提示学习 摘要 提示调优是利用任务相关的可学习标记将预训练的视觉语言模型(VLM)适应下游任务的有效方法。基于CoOp的代表性的工作将可学习的文本token与类别token相结合,…

Linux环境使用Git同步教程

📖 前言:由于CentOS 7已于2024年06月30日停止维护,为了避免操作系统停止维护带来的影响,我们将把系统更换为Ubuntu并迁移数据,在此之前简要的学习Git的上传下载操作。 目录 🕒 1. 连接🕘 1.1 配…

Effective C++笔记之二十二:C++临时变量的析构

先来看段代码 #include <iostream> #include <string>std::string myBlog() {return "https://blog.csdn.net/caoshangpa"; }int main() {const char *p myBlog().c_str();std::cout << p << std::endl;return 0; } 预期输出&#xff1a;…

Netty笔记06-组件ByteBuf

文章目录 概述ByteBuf 的特点ByteBuf的组成ByteBuf 的生命周期 ByteBuf 相关api1. ByteBuf 的创建2. 直接内存 vs 堆内存3. 池化 vs 非池化4. ByteBuf写入代码示例 5. ByteBuffer扩容6. ByteBuf 读取7. retain() & release()TailContext 释放未处理消息逻辑HeadContext 8. …

【新片场-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

面试爱考 | 设计模式

一、概述二、创建型 1. 单例&#xff08;Singleton&#xff09; IntentClass DiagramImplementationExamplesJDK 2. 简单工厂&#xff08;Simple Factory&#xff09; IntentClass DiagramImplementation 3. 工厂方法&#xff08;Factory Method&#xff09; IntentClass Diagr…

饿了么基于Flink+Paimon+StarRocks的实时湖仓探索

摘要&#xff1a;本文整理自饿了么大数据架构师、Apache Flink Contributor 王沛斌老师在8月3日 Streaming Lakehouse Meetup Online&#xff08;Paimon x StarRocks&#xff0c;共话实时湖仓架构&#xff09;上的分享。主要分为以下三个内容&#xff1a; 饿了么实时数仓演进之…

GHOST重装后DEF盘数据救援指南

一、现象解析&#xff1a;GHOST重装后的DEF盘失踪之谜 在计算机维护的日常中&#xff0c;GHOST重装因其快速便捷的特点&#xff0c;成为众多用户解决系统问题的首选方法。然而&#xff0c;这一操作虽能迅速恢复系统至初始状态&#xff0c;却也暗藏风险&#xff0c;尤其是当不慎…

火语言RPA流程组件介绍--单选/复选框

&#x1f6a9;【组件功能】&#xff1a;勾选页面单选/复选框元素 配置预览 配置说明 丨目标元素 支持T或# 默认FLOW输入项 通过自动捕获工具捕获(选择元素工具使用方法)或手动填写网页元素的css,xpath&#xff0c;指定对应网页元素作为操作目标 丨操作 对目标元素进行的勾…

分布式中间件-redis相关概念介绍

文章目录 什么是redis?示意图Redis的主要特点Redis的主要用途Redis的工作原理Redis的持久化与备份 redis 6.x新增特性多线程数据加载客户端缓存新的 RESP 3 协议支持ACL&#xff08;Access Control List&#xff09;功能新增数据类型性能改进配置文件的改进其他改进 redis数据…

MySQL:表中的数据类型

数值类型 int类型 int类型包含以下五种&#xff1a; 类型大小tinyint1 bytesmallint2 bytemediumint3 byteint4 bytebigint8 byte 表t1的num列的类型就是tinyint&#xff0c;我们尝试对其插入数据&#xff0c;来测试其范围。tinynt占1 byte&#xff0c;那么就可以表示256个数…