JavaScript代码混淆工具的实现及其使用

JavaScript代码混淆工具的实现及其使用

JavaScript代码可逆混淆工具

这里的实现使用简单的异或(XOR)加密方式进行混淆,并提供解混淆的功能。请注意,这种方法只是一种基本的混淆手段,作为一种思路和学习实践,并不能提供强大的安全性,适用于对安全性要求不高的场景。

JavaScript代码混淆工具的目的,保护代码,防止他人轻易窃取代码逻辑或进行恶意篡改。这个结果是可逆(即混淆后能恢复原始代码,以便修改源代码)的,并且混淆后的代码,能在其它HTML文件中正常使用。

下面给出两种实现。

一、HTML5实现JavaScript代码混淆工具

先看界面

实现源码

<!DOCTYPE html>
<html>
<head>
    <title>简单的JavaScript 可逆混淆工具</title>
    <style>
        body {
            font-family: sans-serif;
        }
        textarea {
            width: 90%;
            height: 200px;
            margin-bottom: 10px;
        }
        button {
            padding: 10px 20px;
            background-color: #4CAF50;
            color: white;
            border: none;
            cursor: pointer;
            margin-right: 5px;
            margin-bottom: 10px;
        }
        .small-button {
            padding: 5px 10px;
            font-size: 12px;
        }
        .button-group {
            margin-bottom: 15px;
        }
    </style>
</head>
<body>
    <h1>JavaScript 可逆混淆工具</h1>

    <div>
        <label for="originalCode">原始 JavaScript 代码:</label><br>
        <textarea id="originalCode"></textarea>
        <div class="button-group">
            <button class="small-button" onclick="copyText('originalCode')">复制</button>
            <button class="small-button" onclick="clearText('originalCode')">清除</button>
        </div>
    </div>

    <div>
        <button onclick="obfuscateCode()">混淆</button>
        <button onclick="deobfuscateCode()">解混淆</button>
    </div>

    <div>
        <label for="obfuscatedCode">混淆后的 JavaScript 代码:</label><br>
        <textarea id="obfuscatedCode"></textarea>
        <div class="button-group">
            <button class="small-button" onclick="copyText('obfuscatedCode')">复制</button>
            <button class="small-button" onclick="clearText('obfuscatedCode')">清除</button>
        </div>
    </div>

    <script>
        const key = 'MySecretKey'; // 密钥,用于异或加密

        // 复制文本框内容
        function copyText(elementId) {
            const textArea = document.getElementById(elementId);
            textArea.select();
            document.execCommand('copy');
            alert('已复制到剪贴板');
        }

        // 清除文本框内容
        function clearText(elementId) {
            document.getElementById(elementId).value = '';
        }

        function obfuscateCode() {
            const originalCode = document.getElementById('originalCode').value;
            let obfuscatedCode = xorEncrypt(originalCode, key);
            
            // 添加eval和解混淆函数
            obfuscatedCode = `eval(xorDecrypt("${obfuscatedCode}", '${key}')); //密钥'${key}'

function xorDecrypt(text, key) {
    const decodedText = atob(text);
    let result = '';
    for (let i = 0; i < decodedText.length; i++) {
        const charCode = decodedText.charCodeAt(i) ^ key.charCodeAt(i % key.length);
        result += String.fromCharCode(charCode);
    }
    return decodeURIComponent(result);
}`;
            
            document.getElementById('obfuscatedCode').value = obfuscatedCode;
        }

        function deobfuscateCode() {
            let obfuscatedCode = document.getElementById('obfuscatedCode').value;
            
            // 移除添加的eval和解混淆函数
            if (obfuscatedCode.startsWith('eval(xorDecrypt(')) {
                const startQuote = obfuscatedCode.indexOf('"') + 1;
                const endQuote = obfuscatedCode.indexOf('"', startQuote);
                obfuscatedCode = obfuscatedCode.substring(startQuote, endQuote);
            }
            
            const originalCode = xorDecrypt(obfuscatedCode, key);
            document.getElementById('originalCode').value = originalCode;
        }

        function xorEncrypt(text, key) {
            const encodedText = encodeURIComponent(text);
            const keyBytes = new TextEncoder().encode(key);
            const textBytes = new TextEncoder().encode(encodedText);
            const resultBytes = Array.from(textBytes).map((byte, i) => byte ^ keyBytes[i % keyBytes.length]);
            const resultString = String.fromCharCode(...resultBytes);
            return btoa(resultString);
        }
        
        function xorDecrypt(text, key) {
            const decodedText = atob(text);
            const keyBytes = new TextEncoder().encode(key);
            const decodedBytes = Array.from(decodedText).map(char => char.charCodeAt(0));
            const resultBytes = decodedBytes.map((byte, i) => byte ^ keyBytes[i % keyBytes.length]);
            const resultString = String.fromCharCode(...resultBytes);
            try {
                const decoded = decodeURIComponent(new TextDecoder().decode(new Uint8Array(resultBytes)));
                return decoded;
            } catch (e) {
                console.error("解码错误:", e);
                return ""; // 或者其他错误处理方式
            }
        }
    </script>
</body>
</html>

二、Python实现JavaScript代码混淆工具

先看效果图

源码如下:

import tkinter as tk
from tkinter import ttk, messagebox, scrolledtext
import base64
import urllib.parse

class XorObfuscator:
    def __init__(self, key='MySecretKey'):
        self.key = key
    
    def _xor_operation(self, text_bytes, key_bytes):
        return bytes([text_bytes[i] ^ key_bytes[i % len(key_bytes)] for i in range(len(text_bytes))])
    
    def encrypt(self, plaintext):
        try:
            encoded = urllib.parse.quote(plaintext).encode('utf-8')
            key_bytes = self.key.encode('utf-8')
            encrypted = self._xor_operation(encoded, key_bytes)
            return base64.b64encode(encrypted).decode('utf-8')
        except Exception as e:
            return f"加密错误: {str(e)}"
    
    def decrypt(self, ciphertext):
        try:
            key_bytes = self.key.encode('utf-8')
            decoded = base64.b64decode(ciphertext)
            decrypted = self._xor_operation(decoded, key_bytes)
            return urllib.parse.unquote(decrypted.decode('utf-8'))
        except:
            return "解码错误 - 请检查密钥或输入内容"

class ObfuscationToolApp(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Python 可逆混淆工具")
        self.geometry("800x600")
        self.obfuscator = XorObfuscator()
        self.create_widgets()
    
    def create_widgets(self):
        # 原始代码区域
        ttk.Label(self, text="原始代码:").pack(pady=5)
        self.original_text = scrolledtext.ScrolledText(self, height=10)
        self.original_text.pack(fill=tk.X, padx=10)
        
        # 原始代码操作按钮
        btn_frame1 = ttk.Frame(self)
        btn_frame1.pack(pady=5)
        ttk.Button(btn_frame1, text="复制", command=self.copy_original).pack(side=tk.LEFT, padx=5)
        ttk.Button(btn_frame1, text="清除", command=self.clear_original).pack(side=tk.LEFT)
        
        # 操作按钮
        btn_frame2 = ttk.Frame(self)
        btn_frame2.pack(pady=10)
        ttk.Button(btn_frame2, text="混淆", command=self.obfuscate).pack(side=tk.LEFT, padx=20)
        ttk.Button(btn_frame2, text="解混淆", command=self.deobfuscate).pack(side=tk.LEFT, padx=20)
        
        # 混淆后代码区域
        ttk.Label(self, text="混淆后代码:").pack(pady=5)
        self.obfuscated_text = scrolledtext.ScrolledText(self, height=10)
        self.obfuscated_text.pack(fill=tk.X, padx=10)
        
        # 混淆代码操作按钮
        btn_frame3 = ttk.Frame(self)
        btn_frame3.pack(pady=5)
        ttk.Button(btn_frame3, text="复制", command=self.copy_obfuscated).pack(side=tk.LEFT, padx=5)
        ttk.Button(btn_frame3, text="清除", command=self.clear_obfuscated).pack(side=tk.LEFT)
        
        # 密钥设置
        settings_frame = ttk.Frame(self)
        settings_frame.pack(pady=10)
        ttk.Label(settings_frame, text="密钥:").pack(side=tk.LEFT)
        self.key_entry = ttk.Entry(settings_frame, width=20)
        self.key_entry.insert(0, "MySecretKey")
        self.key_entry.pack(side=tk.LEFT, padx=5)
        ttk.Button(settings_frame, text="更新密钥", command=self.update_key).pack(side=tk.LEFT)
    
    def update_key(self):
        new_key = self.key_entry.get()
        self.obfuscator.key = new_key
        messagebox.showinfo("提示", "密钥已更新")
    
    def get_text(self, text_widget):
        return text_widget.get("1.0", tk.END).strip()
    
    def set_text(self, text_widget, content):
        text_widget.delete("1.0", tk.END)
        text_widget.insert(tk.INSERT, content)
    
    def copy_original(self):
        self.clipboard_clear()
        self.clipboard_append(self.get_text(self.original_text))
    
    def clear_original(self):
        self.original_text.delete("1.0", tk.END)
    
    def copy_obfuscated(self):
        self.clipboard_clear()
        self.clipboard_append(self.get_text(self.obfuscated_text))
    
    def clear_obfuscated(self):
        self.obfuscated_text.delete("1.0", tk.END)
    
    def obfuscate(self):
        original_code = self.get_text(self.original_text)
        encrypted = self.obfuscator.encrypt(original_code)
        
        # 生成JavaScript版本的解密函数
        obfuscated_code = f'''eval(xorDecrypt("{encrypted}", "{self.obfuscator.key}"));

function xorDecrypt(text, key) {{
    const decodedText = atob(text);
    let result = '';
    for (let i = 0; i < decodedText.length; i++) {{
        const charCode = decodedText.charCodeAt(i) ^ key.charCodeAt(i % key.length);
        result += String.fromCharCode(charCode);
    }}
    return decodeURIComponent(result);
}}'''
        
        self.set_text(self.obfuscated_text, obfuscated_code)
    
    def deobfuscate(self):
        code = self.get_text(self.obfuscated_text)
        if code.startswith('eval(xorDecrypt("'):
            start = code.find('"') + 1
            end = code.find('"', start)
            encrypted = code[start:end]
        else:
            encrypted = code
        
        result = self.obfuscator.decrypt(encrypted)
        self.set_text(self.original_text, result)


if __name__ == "__main__":
    app = ObfuscationToolApp()
    app.mainloop()

三、运用到一个简单的猜数字游戏

下面通过一个例子,演示如何使用

原来(未混淆JavaScript代码)的如下

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>猜数字游戏</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            margin-top: 50px;
        }
        input {
            margin: 10px;
            padding: 5px;
        }
        button {
            padding: 10px 20px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <h1>猜数字游戏</h1>
    <p>我已经想好了一个1到100之间的数字,你能猜到它是什么吗?</p>
    <input type="number" id="guess" placeholder="请输入你的猜测">
    <button onclick="checkGuess()">提交</button>
    <button onclick="restartGame()">重玩</button>
    <p id="result"></p>

    <script>
        let randomNumber = Math.floor(Math.random() * 100) + 1; // 生成一个1到100的随机数
        let attempts = 0;

        function checkGuess() {
            const userGuess = document.getElementById('guess').value;
            attempts++;
            if (userGuess == randomNumber) {
                document.getElementById('result').innerText = `恭喜你!猜对了!数字是 ${randomNumber},你总共猜了 ${attempts} 次。`;
            } else if (userGuess > randomNumber) {
                document.getElementById('result').innerText = '太大了,再试一次!';
            } else if (userGuess < randomNumber) {
                document.getElementById('result').innerText = '太小了,再试一次!';
            }
        }

        function restartGame() {
            randomNumber = Math.floor(Math.random() * 100) + 1; // 重新生成随机数
            attempts = 0; // 重置尝试次数
            document.getElementById('guess').value = ''; // 清空输入框
            document.getElementById('result').innerText = ''; // 清空结果提示
        }
    </script>
</body>
</html>

混淆后代码

<script> </script>源代码复制到工具中混淆,将混淆后的代码替换源代码即可。混淆后代码为:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>猜数字游戏</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            margin-top: 50px;
        }
        input {
            margin: 10px;
            padding: 5px;
        }
        button {
            padding: 10px 20px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <h1>猜数字游戏</h1>
    <p>我已经想好了一个1到100之间的数字,你能猜到它是什么吗?</p>
    <input type="number" id="guess" placeholder="请输入你的猜测">
    <button onclick="checkGuess()">提交</button>
    <button onclick="restartGame()">重玩</button>
    <p id="result"></p>

    <script>
eval(xorDecrypt("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", 'MySecretKey')); //密钥'MySecretKey'

function xorDecrypt(text, key) {
    const decodedText = atob(text);
    let result = '';
    for (let i = 0; i < decodedText.length; i++) {
        const charCode = decodedText.charCodeAt(i) ^ key.charCodeAt(i % key.length);
        result += String.fromCharCode(charCode);
    }
    return decodeURIComponent(result);
}
    </script>
</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学习&实践爱好者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值