feat: x27cn v1.1.0 - 添加文件混淆功能,支持 HTML/JS/CSS 加密

This commit is contained in:
violettools
2026-01-24 19:09:44 +08:00
parent 3d11a290e5
commit 5e61edf72a
6 changed files with 468 additions and 25 deletions

View File

@@ -53,7 +53,7 @@
## X27CN 加密库
X27CN 是 CFspider 使用的代码混淆加密算法,现已作为独立 Python 库发布。
X27CN 是 CFspider 使用的代码混淆加密算法,现已作为独立 Python 库发布。支持文本加密和整个前端文件混淆。
### 安装
@@ -66,35 +66,53 @@ pip install x27cn
```python
import x27cn
# 加密
# 加密文本
encrypted = x27cn.encrypt('Hello World')
print(encrypted) # <faee><38db><e120>...
# 解密
decrypted = x27cn.decrypt(encrypted)
print(decrypted) # Hello World
# 自定义密钥
encrypted = x27cn.encrypt('敏感数据', key='mySecretKey')
decrypted = x27cn.decrypt(encrypted, key='mySecretKey')
# 混淆整个 HTML 文件(生成自解密页面)
x27cn.obfuscate_file('index.html') # 生成 index.obf.html
# 混淆 JavaScript 文件
x27cn.obfuscate_file('app.js') # 生成 app.obf.js
# 混淆 CSS 文件
x27cn.obfuscate_file('style.css') # 生成 style.obf.css
```
### 支持的格式
### 命令行工具
```python
# 标准格式(<xxxx> 标签)
encrypted = x27cn.encrypt('text')
```bash
# 混淆 HTML 文件
x27cn obfuscate index.html
# 纯十六进制
hex_encrypted = x27cn.encrypt_hex('text')
# 混淆 JS 文件
x27cn obfuscate app.js dist/app.js
# Base64
b64_encrypted = x27cn.encrypt_base64('text')
# 使用自定义密钥
x27cn obfuscate app.html --key=mySecretKey
# 加密/解密文本
x27cn encrypt -t "Hello World"
x27cn decrypt -t "<faee><38db>..."
```
### 混淆效果
```html
<!-- 原始 HTML -->
<h1>Hello World</h1>
<script>alert('Secret!');</script>
<!-- 混淆后(自动解密) -->
<script>(function(){var _$='<9525>...';...})();</script>
```
浏览器加载混淆后的文件会自动解密并正常显示原始内容,源代码无法被直接查看。
### 安全说明
X27CN 设计用于**代码混淆**,不是密码学安全的加密算法。适用于前端代码混淆、API 响应混淆、配置文件保护等场景。
X27CN 设计用于**代码混淆**,不是密码学安全的加密算法。适用于前端代码保护、API 响应混淆、防止代码被轻易复制等场景。
---

View File

@@ -15,7 +15,7 @@ import x27cn
# 加密
encrypted = x27cn.encrypt('Hello World')
print(encrypted) # <e5d6><32af>...
print(encrypted) # <faee><38db>...
# 解密
decrypted = x27cn.decrypt(encrypted)
@@ -26,7 +26,92 @@ encrypted = x27cn.encrypt('敏感数据', key='mySecretKey')
decrypted = x27cn.decrypt(encrypted, key='mySecretKey')
```
## API
## 文件混淆(前端代码保护)
### Python API
```python
import x27cn
# 混淆整个 HTML 文件(生成自解密页面)
x27cn.obfuscate_file('index.html') # 生成 index.obf.html
# 混淆 JavaScript 文件
x27cn.obfuscate_file('app.js') # 生成 app.obf.js
# 混淆 CSS 文件
x27cn.obfuscate_file('style.css') # 生成 style.obf.css
# 自定义输出路径和密钥
x27cn.obfuscate_file('app.html', 'dist/app.html', key='myKey')
```
### 命令行
```bash
# 混淆 HTML
x27cn obfuscate index.html
# 混淆 JS
x27cn obfuscate app.js dist/app.js
# 使用自定义密钥
x27cn obfuscate app.html --key=mySecretKey
# 加密文本
x27cn encrypt -t "Hello World"
# 解密文本
x27cn decrypt -t "<faee><38db>..."
```
### 混淆效果
**原始 HTML:**
```html
<!DOCTYPE html>
<html>
<body>
<h1>Hello World</h1>
<script>alert('Secret!');</script>
</body>
</html>
```
**混淆后:**
```html
<!DOCTYPE html>
<html>
<body>
<script>
(function(){var _$='<9525><0d5b>...';var _k=[0x78,0x32,...];...})();
</script>
</body>
</html>
```
浏览器加载混淆后的文件会自动解密并正常显示原始内容。
### 内联混淆
```python
import x27cn
html = '''
<html>
<style>body { color: red; }</style>
<script>alert('hello');</script>
</html>
'''
# 只混淆内联 JS
result = x27cn.obfuscate_inline_js(html)
# 只混淆内联 CSS
result = x27cn.obfuscate_inline_css(html)
```
## API 参考
### 基础加密/解密
@@ -44,6 +129,22 @@ b64_encrypted = x27cn.encrypt_base64('text')
decrypted = x27cn.decrypt_base64(b64_encrypted)
```
### 文件混淆
```python
# 混淆整个文件
x27cn.obfuscate_file(input_path, output_path=None, key='x27cn2026')
# 混淆 HTML 字符串
x27cn.obfuscate_html(html_content, key='x27cn2026')
# 混淆 JS 字符串
x27cn.obfuscate_js(js_content, key='x27cn2026')
# 混淆 CSS 字符串
x27cn.obfuscate_css(css_content, key='x27cn2026')
```
### 密钥管理
```python
@@ -71,9 +172,10 @@ X27CN v2 使用以下加密步骤:
X27CN 设计用于**代码混淆**,不是密码学安全的加密算法。
适用场景:
- 前端代码混淆
- 前端代码混淆保护
- API 响应混淆
- 配置文件保护
- 防止代码被轻易复制
不适用场景:
- 密码存储(请使用 bcrypt/argon2

View File

@@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
[project]
name = "x27cn"
version = "1.0.0"
version = "1.1.0"
description = "X27CN 代码混淆加密库 - Code obfuscation and encryption library"
readme = "README.md"
license = {text = "MIT"}
license = "MIT"
requires-python = ">=3.7"
authors = [
{name = "CFspider", email = "cfspider@example.com"}
@@ -17,13 +17,14 @@ keywords = [
"obfuscation",
"security",
"encoding",
"html",
"javascript",
"加密",
"混淆"
]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
@@ -36,6 +37,9 @@ classifiers = [
"Topic :: Software Development :: Libraries :: Python Modules",
]
[project.scripts]
x27cn = "x27cn.cli:main"
[project.urls]
Homepage = "https://github.com/violettoolssite/CFspider"
Documentation = "https://github.com/violettoolssite/CFspider#x27cn-加密库"

View File

@@ -14,6 +14,10 @@ Code obfuscation and encryption library
# 自定义密钥
encrypted = x27cn.encrypt('data', key='mySecretKey')
decrypted = x27cn.decrypt(encrypted, key='mySecretKey')
# 文件混淆
x27cn.obfuscate_file('app.html') # 生成 app.obf.html
x27cn.obfuscate_file('script.js') # 生成 script.obf.js
"""
from .core import (
@@ -27,9 +31,19 @@ from .core import (
DEFAULT_KEY,
)
__version__ = '1.0.0'
from .obfuscate import (
obfuscate_html,
obfuscate_js,
obfuscate_css,
obfuscate_file,
obfuscate_inline_js,
obfuscate_inline_css,
)
__version__ = '1.1.0'
__author__ = 'CFspider'
__all__ = [
# 核心加密
'encrypt',
'decrypt',
'encrypt_hex',
@@ -38,5 +52,12 @@ __all__ = [
'decrypt_base64',
'generate_key',
'DEFAULT_KEY',
# 文件混淆
'obfuscate_html',
'obfuscate_js',
'obfuscate_css',
'obfuscate_file',
'obfuscate_inline_js',
'obfuscate_inline_css',
]

96
x27cn/x27cn/cli.py Normal file
View File

@@ -0,0 +1,96 @@
"""
X27CN 命令行工具
用法:
x27cn encrypt <file> [output] [--key=密钥]
x27cn decrypt <file> [output] [--key=密钥]
x27cn obfuscate <file> [output] [--key=密钥]
"""
import argparse
import sys
from .core import encrypt, decrypt, DEFAULT_KEY
from .obfuscate import obfuscate_file
def main():
parser = argparse.ArgumentParser(
prog='x27cn',
description='X27CN 代码混淆加密工具'
)
parser.add_argument('--version', action='version', version='x27cn 1.0.0')
subparsers = parser.add_subparsers(dest='command', help='命令')
# encrypt 命令
enc_parser = subparsers.add_parser('encrypt', help='加密文本或文件')
enc_parser.add_argument('input', help='输入文件或文本')
enc_parser.add_argument('output', nargs='?', help='输出文件(可选)')
enc_parser.add_argument('--key', '-k', default=DEFAULT_KEY, help='加密密钥')
enc_parser.add_argument('--text', '-t', action='store_true', help='将 input 作为文本而非文件')
# decrypt 命令
dec_parser = subparsers.add_parser('decrypt', help='解密文本或文件')
dec_parser.add_argument('input', help='输入文件或加密文本')
dec_parser.add_argument('output', nargs='?', help='输出文件(可选)')
dec_parser.add_argument('--key', '-k', default=DEFAULT_KEY, help='解密密钥')
dec_parser.add_argument('--text', '-t', action='store_true', help='将 input 作为文本而非文件')
# obfuscate 命令
obf_parser = subparsers.add_parser('obfuscate', help='混淆加密文件(生成自解密代码)')
obf_parser.add_argument('input', help='输入文件 (.html/.js/.css)')
obf_parser.add_argument('output', nargs='?', help='输出文件(可选)')
obf_parser.add_argument('--key', '-k', default=DEFAULT_KEY, help='加密密钥')
args = parser.parse_args()
if not args.command:
parser.print_help()
sys.exit(0)
try:
if args.command == 'encrypt':
if args.text:
result = encrypt(args.input, args.key)
print(result)
else:
with open(args.input, 'r', encoding='utf-8') as f:
content = f.read()
result = encrypt(content, args.key)
if args.output:
with open(args.output, 'w', encoding='utf-8') as f:
f.write(result)
print(f'加密完成: {args.output}')
else:
print(result)
elif args.command == 'decrypt':
if args.text:
result = decrypt(args.input, args.key)
print(result)
else:
with open(args.input, 'r', encoding='utf-8') as f:
content = f.read()
result = decrypt(content, args.key)
if args.output:
with open(args.output, 'w', encoding='utf-8') as f:
f.write(result)
print(f'解密完成: {args.output}')
else:
print(result)
elif args.command == 'obfuscate':
output = obfuscate_file(args.input, args.output, args.key)
print(f'混淆完成: {output}')
except FileNotFoundError:
print(f'错误: 文件不存在 - {args.input}', file=sys.stderr)
sys.exit(1)
except Exception as e:
print(f'错误: {e}', file=sys.stderr)
sys.exit(1)
if __name__ == '__main__':
main()

202
x27cn/x27cn/obfuscate.py Normal file
View File

@@ -0,0 +1,202 @@
"""
X27CN 文件混淆加密模块
支持对整个 HTML/JS/CSS 文件进行加密混淆,生成自解密代码。
"""
import os
import re
from typing import Optional
from .core import encrypt, DEFAULT_KEY
def obfuscate_html(content: str, key: str = DEFAULT_KEY) -> str:
"""
混淆加密 HTML 文件内容
生成一个自解密的 HTML 页面,浏览器加载时自动解密并渲染原始内容。
Args:
content: HTML 文件内容
key: 加密密钥
Returns:
自解密 HTML 代码
Example:
>>> html = '<h1>Hello</h1>'
>>> obfuscated = obfuscate_html(html)
>>> # 浏览器加载 obfuscated 会显示 "Hello"
"""
encrypted = encrypt(content, key)
key_bytes = key.encode('utf-8')
key_array = ','.join(hex(b) for b in key_bytes)
return f'''<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
</head>
<body>
<script>
(function(){{var _$='{encrypted.replace("'", "\\'")}';var _k=[{key_array}];var _d=function(_e,_k){{if(!_e)return'';var _h='',_m,_p=/<([0-9a-fA-F]{{1,4}})>/g;while((_m=_p.exec(_e))!==null)_h+=_m[1];if(!_h||_h.length%2!==0)return'';var _kb=new Uint8Array(_k.length);for(var i=0;i<_k.length;i++)_kb[i]=_k[i];var _ek=new Uint8Array(256),_sb=new Uint8Array(256),_isb=new Uint8Array(256);for(var i=0;i<256;i++){{_ek[i]=(_kb[i%_kb.length]^((7*i+13)&255))&255;_sb[i]=((167*i+89)&255)}}for(var i=0;i<256;i++)_isb[_sb[i]]=i;var _eb=new Uint8Array(_h.length/2);for(var i=0;i<_h.length;i+=2)_eb[i/2]=parseInt(_h.substr(i,2),16);var _st=0;for(var i=0;i<_kb.length;i++)_st^=_kb[i];var _db=new Uint8Array(_eb.length);for(var i=0;i<_eb.length;i++){{var v=_eb[i],_ns=(_st+v+_ek[(i+128)%256])&255;v=((v-3*i-_st)%256+256)%256;v=((v>>5)|(v<<3))&255;v=_isb[v];v=v^_ek[i%256];_st=_ns;_db[i]=v}}return new TextDecoder().decode(_db)}};var _c=_d(_$,_k);document.open();document.write(_c);document.close()}})();
</script>
</body>
</html>'''
def obfuscate_js(content: str, key: str = DEFAULT_KEY) -> str:
"""
混淆加密 JavaScript 文件内容
生成一个自解密的 JS 代码,加载时自动解密并执行原始代码。
Args:
content: JavaScript 文件内容
key: 加密密钥
Returns:
自解密 JavaScript 代码
Example:
>>> js = 'alert("Hello");'
>>> obfuscated = obfuscate_js(js)
>>> # 执行 obfuscated 会弹出 "Hello"
"""
encrypted = encrypt(content, key)
key_bytes = key.encode('utf-8')
key_array = ','.join(hex(b) for b in key_bytes)
return f'''(function(){{var _$='{encrypted.replace("'", "\\'")}';var _k=[{key_array}];var _d=function(_e,_k){{if(!_e)return'';var _h='',_m,_p=/<([0-9a-fA-F]{{1,4}})>/g;while((_m=_p.exec(_e))!==null)_h+=_m[1];if(!_h||_h.length%2!==0)return'';var _kb=new Uint8Array(_k.length);for(var i=0;i<_k.length;i++)_kb[i]=_k[i];var _ek=new Uint8Array(256),_sb=new Uint8Array(256),_isb=new Uint8Array(256);for(var i=0;i<256;i++){{_ek[i]=(_kb[i%_kb.length]^((7*i+13)&255))&255;_sb[i]=((167*i+89)&255)}}for(var i=0;i<256;i++)_isb[_sb[i]]=i;var _eb=new Uint8Array(_h.length/2);for(var i=0;i<_h.length;i+=2)_eb[i/2]=parseInt(_h.substr(i,2),16);var _st=0;for(var i=0;i<_kb.length;i++)_st^=_kb[i];var _db=new Uint8Array(_eb.length);for(var i=0;i<_eb.length;i++){{var v=_eb[i],_ns=(_st+v+_ek[(i+128)%256])&255;v=((v-3*i-_st)%256+256)%256;v=((v>>5)|(v<<3))&255;v=_isb[v];v=v^_ek[i%256];_st=_ns;_db[i]=v}}return new TextDecoder().decode(_db)}};eval(_d(_$,_k))}})();'''
def obfuscate_css(content: str, key: str = DEFAULT_KEY) -> str:
"""
混淆加密 CSS 文件内容
生成一个自解密的 JS 代码,加载时自动解密并注入样式。
Args:
content: CSS 文件内容
key: 加密密钥
Returns:
自解密 JavaScript 代码(用于注入 CSS
Example:
>>> css = 'body { color: red; }'
>>> obfuscated = obfuscate_css(css)
>>> # 执行 obfuscated 会注入样式
"""
encrypted = encrypt(content, key)
key_bytes = key.encode('utf-8')
key_array = ','.join(hex(b) for b in key_bytes)
return f'''(function(){{var _$='{encrypted.replace("'", "\\'")}';var _k=[{key_array}];var _d=function(_e,_k){{if(!_e)return'';var _h='',_m,_p=/<([0-9a-fA-F]{{1,4}})>/g;while((_m=_p.exec(_e))!==null)_h+=_m[1];if(!_h||_h.length%2!==0)return'';var _kb=new Uint8Array(_k.length);for(var i=0;i<_k.length;i++)_kb[i]=_k[i];var _ek=new Uint8Array(256),_sb=new Uint8Array(256),_isb=new Uint8Array(256);for(var i=0;i<256;i++){{_ek[i]=(_kb[i%_kb.length]^((7*i+13)&255))&255;_sb[i]=((167*i+89)&255)}}for(var i=0;i<256;i++)_isb[_sb[i]]=i;var _eb=new Uint8Array(_h.length/2);for(var i=0;i<_h.length;i+=2)_eb[i/2]=parseInt(_h.substr(i,2),16);var _st=0;for(var i=0;i<_kb.length;i++)_st^=_kb[i];var _db=new Uint8Array(_eb.length);for(var i=0;i<_eb.length;i++){{var v=_eb[i],_ns=(_st+v+_ek[(i+128)%256])&255;v=((v-3*i-_st)%256+256)%256;v=((v>>5)|(v<<3))&255;v=_isb[v];v=v^_ek[i%256];_st=_ns;_db[i]=v}}return new TextDecoder().decode(_db)}};var _s=document.createElement('style');_s.textContent=_d(_$,_k);document.head.appendChild(_s)}})();'''
def obfuscate_file(
input_path: str,
output_path: Optional[str] = None,
key: str = DEFAULT_KEY
) -> str:
"""
混淆加密文件
根据文件扩展名自动选择混淆方式:
- .html -> 生成自解密 HTML
- .js -> 生成自解密 JS
- .css -> 生成自解密 CSSJS 注入)
Args:
input_path: 输入文件路径
output_path: 输出文件路径(可选,默认添加 .obf 后缀)
key: 加密密钥
Returns:
输出文件路径
Example:
>>> obfuscate_file('app.html')
'app.obf.html'
>>> obfuscate_file('script.js', 'dist/script.js')
'dist/script.js'
"""
# 读取文件
with open(input_path, 'r', encoding='utf-8') as f:
content = f.read()
# 获取扩展名
ext = os.path.splitext(input_path)[1].lower()
# 根据类型混淆
if ext == '.html' or ext == '.htm':
obfuscated = obfuscate_html(content, key)
elif ext == '.js':
obfuscated = obfuscate_js(content, key)
elif ext == '.css':
obfuscated = obfuscate_css(content, key)
else:
# 其他类型当作文本加密
obfuscated = encrypt(content, key)
# 确定输出路径
if output_path is None:
base, ext = os.path.splitext(input_path)
output_path = f"{base}.obf{ext}"
# 写入文件
with open(output_path, 'w', encoding='utf-8') as f:
f.write(obfuscated)
return output_path
def obfuscate_inline_js(html_content: str, key: str = DEFAULT_KEY) -> str:
"""
混淆 HTML 中的内联 JavaScript
保持 HTML 结构,只加密 <script> 标签内的代码。
Args:
html_content: HTML 内容
key: 加密密钥
Returns:
混淆后的 HTML
"""
def replace_script(match):
script_content = match.group(1)
if not script_content.strip():
return match.group(0)
obfuscated = obfuscate_js(script_content, key)
return f'<script>{obfuscated}</script>'
pattern = re.compile(r'<script[^>]*>([^<]*)</script>', re.IGNORECASE | re.DOTALL)
return pattern.sub(replace_script, html_content)
def obfuscate_inline_css(html_content: str, key: str = DEFAULT_KEY) -> str:
"""
混淆 HTML 中的内联 CSS
将 <style> 标签替换为自解密 JS 注入。
Args:
html_content: HTML 内容
key: 加密密钥
Returns:
混淆后的 HTML
"""
def replace_style(match):
style_content = match.group(1)
if not style_content.strip():
return match.group(0)
obfuscated = obfuscate_css(style_content, key)
return f'<script>{obfuscated}</script>'
pattern = re.compile(r'<style[^>]*>([^<]*)</style>', re.IGNORECASE | re.DOTALL)
return pattern.sub(replace_style, html_content)