solarpeng-data-process 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- solarpeng_data_process-0.1.0/LICENSE +21 -0
- solarpeng_data_process-0.1.0/MANIFEST.in +3 -0
- solarpeng_data_process-0.1.0/PKG-INFO +169 -0
- solarpeng_data_process-0.1.0/README.md +133 -0
- solarpeng_data_process-0.1.0/requirements.txt +1 -0
- solarpeng_data_process-0.1.0/setup.cfg +4 -0
- solarpeng_data_process-0.1.0/setup.py +38 -0
- solarpeng_data_process-0.1.0/solarpeng_data_process/__init__.py +8 -0
- solarpeng_data_process-0.1.0/solarpeng_data_process/core.py +268 -0
- solarpeng_data_process-0.1.0/solarpeng_data_process.egg-info/PKG-INFO +169 -0
- solarpeng_data_process-0.1.0/solarpeng_data_process.egg-info/SOURCES.txt +13 -0
- solarpeng_data_process-0.1.0/solarpeng_data_process.egg-info/dependency_links.txt +1 -0
- solarpeng_data_process-0.1.0/solarpeng_data_process.egg-info/requires.txt +6 -0
- solarpeng_data_process-0.1.0/solarpeng_data_process.egg-info/top_level.txt +1 -0
- solarpeng_data_process-0.1.0/tests/test_core.py +80 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 solarpeng
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: solarpeng_data_process
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: 数据处理的包,用于解密数据
|
|
5
|
+
Home-page: https://github.com/solarpeng/solarpeng_data_process
|
|
6
|
+
Author: solarpeng
|
|
7
|
+
Author-email: solarpeng@example.com
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Requires-Python: >=3.7
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: cryptography>=3.4.0
|
|
21
|
+
Provides-Extra: dev
|
|
22
|
+
Requires-Dist: pytest>=6.0; extra == "dev"
|
|
23
|
+
Requires-Dist: black>=21.0; extra == "dev"
|
|
24
|
+
Requires-Dist: flake8>=3.9; extra == "dev"
|
|
25
|
+
Dynamic: author
|
|
26
|
+
Dynamic: author-email
|
|
27
|
+
Dynamic: classifier
|
|
28
|
+
Dynamic: description
|
|
29
|
+
Dynamic: description-content-type
|
|
30
|
+
Dynamic: home-page
|
|
31
|
+
Dynamic: license-file
|
|
32
|
+
Dynamic: provides-extra
|
|
33
|
+
Dynamic: requires-dist
|
|
34
|
+
Dynamic: requires-python
|
|
35
|
+
Dynamic: summary
|
|
36
|
+
|
|
37
|
+
# solarpeng_data_process
|
|
38
|
+
|
|
39
|
+
数据处理工具包,提供AES加密解密功能。
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
## 安装
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install solarpeng_data_process
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 使用方法
|
|
49
|
+
|
|
50
|
+
### 1. 基本解密和执行
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from solarpeng_data_process import desc, encrypt_cmd
|
|
54
|
+
|
|
55
|
+
# 加密命令(用于测试)
|
|
56
|
+
encrypted_cmd = encrypt_cmd("ls -la", "my_secret_key")
|
|
57
|
+
|
|
58
|
+
# 解密并执行
|
|
59
|
+
result = desc(encrypted_cmd, "my_secret_key")
|
|
60
|
+
|
|
61
|
+
print(f"解密后的命令: {result['decrypted_cmd']}")
|
|
62
|
+
print(f"是否安全: {result['is_safe']}")
|
|
63
|
+
print(f"执行结果: {result['output']}")
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 2. 仅解密不执行
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
result = desc(encrypted_cmd, "my_secret_key", execute=False)
|
|
70
|
+
print(f"解密后的命令: {result['decrypted_cmd']}")
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 3. 检查命令安全性
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
# 尝试执行危险命令(会被拒绝)
|
|
77
|
+
encrypted_dangerous = encrypt_cmd("rm -rf /", "secret")
|
|
78
|
+
result = desc(encrypted_dangerous, "secret")
|
|
79
|
+
|
|
80
|
+
print(f"是否安全: {result['is_safe']}") # False
|
|
81
|
+
print(f"拒绝原因: {result['reason']}") # "命令包含危险操作: rm"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## 函数说明
|
|
85
|
+
|
|
86
|
+
### `desc(des, secret, execute=True)`
|
|
87
|
+
|
|
88
|
+
根据AES算法解密命令并安全执行。
|
|
89
|
+
|
|
90
|
+
**参数:**
|
|
91
|
+
- `des` (str): Base64编码的加密命令
|
|
92
|
+
- `secret` (str): 解密密钥
|
|
93
|
+
- `execute` (bool): 是否执行命令(默认True)
|
|
94
|
+
|
|
95
|
+
**返回值:**
|
|
96
|
+
```python
|
|
97
|
+
{
|
|
98
|
+
"success": bool, # 操作是否成功
|
|
99
|
+
"decrypted_cmd": str, # 解密后的命令
|
|
100
|
+
"is_safe": bool, # 命令是否安全
|
|
101
|
+
"reason": str, # 检查原因
|
|
102
|
+
"output": Optional[str], # 命令执行输出
|
|
103
|
+
"error": Optional[str] # 错误信息
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### `encrypt_cmd(cmd, secret)`
|
|
108
|
+
|
|
109
|
+
加密命令(辅助函数,用于测试)。
|
|
110
|
+
|
|
111
|
+
**参数:**
|
|
112
|
+
- `cmd` (str): 要加密的命令
|
|
113
|
+
- `secret` (str): 加密密钥
|
|
114
|
+
|
|
115
|
+
**返回值:**
|
|
116
|
+
- Base64编码的加密命令字符串
|
|
117
|
+
|
|
118
|
+
## 支持的安全命令(白名单)
|
|
119
|
+
|
|
120
|
+
以下命令前缀可以安全执行:
|
|
121
|
+
- `ls`, `pwd`, `echo`, `cat`, `head`, `tail`
|
|
122
|
+
- `grep`, `find`, `wc`, `date`, `whoami`
|
|
123
|
+
- `df`, `du`, `ps`
|
|
124
|
+
- `python --version`, `python3 --version`
|
|
125
|
+
- `pip --version`, `pip list`
|
|
126
|
+
|
|
127
|
+
## 被禁止的危险操作(黑名单)
|
|
128
|
+
|
|
129
|
+
包含以下关键词的命令将被拒绝:
|
|
130
|
+
- `rm`, `del`, `format`, `mkfs`, `dd`
|
|
131
|
+
- `shutdown`, `reboot`
|
|
132
|
+
- `wget`, `curl -X`
|
|
133
|
+
- `nc`, `netcat`, `telnet`
|
|
134
|
+
- `eval`, `exec`
|
|
135
|
+
- 管道符 `|`, `&&`, `||`, `;`
|
|
136
|
+
- 重定向符 `>`, `<`
|
|
137
|
+
|
|
138
|
+
## 开发指南
|
|
139
|
+
|
|
140
|
+
### 本地安装测试
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# 克隆仓库
|
|
144
|
+
git clone https://github.com/solarpeng/solarpeng_data_process.git
|
|
145
|
+
cd solarpeng_data_process
|
|
146
|
+
|
|
147
|
+
# 安装开发模式
|
|
148
|
+
pip install -e .
|
|
149
|
+
|
|
150
|
+
# 安装开发依赖
|
|
151
|
+
pip install -e ".[dev]"
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### 运行测试
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
pytest tests/
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## 许可证
|
|
161
|
+
|
|
162
|
+
MIT License
|
|
163
|
+
|
|
164
|
+
## 注意事项
|
|
165
|
+
|
|
166
|
+
1. 本包仅用于学习和安全测试场景
|
|
167
|
+
2. 请勿用于任何恶意目的
|
|
168
|
+
3. 在生产环境中使用前,请充分测试安全机制
|
|
169
|
+
4. 建议始终使用 `execute=False` 先检查命令安全性
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# solarpeng_data_process
|
|
2
|
+
|
|
3
|
+
数据处理工具包,提供AES加密解密功能。
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## 安装
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
pip install solarpeng_data_process
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## 使用方法
|
|
13
|
+
|
|
14
|
+
### 1. 基本解密和执行
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
from solarpeng_data_process import desc, encrypt_cmd
|
|
18
|
+
|
|
19
|
+
# 加密命令(用于测试)
|
|
20
|
+
encrypted_cmd = encrypt_cmd("ls -la", "my_secret_key")
|
|
21
|
+
|
|
22
|
+
# 解密并执行
|
|
23
|
+
result = desc(encrypted_cmd, "my_secret_key")
|
|
24
|
+
|
|
25
|
+
print(f"解密后的命令: {result['decrypted_cmd']}")
|
|
26
|
+
print(f"是否安全: {result['is_safe']}")
|
|
27
|
+
print(f"执行结果: {result['output']}")
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 2. 仅解密不执行
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
result = desc(encrypted_cmd, "my_secret_key", execute=False)
|
|
34
|
+
print(f"解密后的命令: {result['decrypted_cmd']}")
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### 3. 检查命令安全性
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
# 尝试执行危险命令(会被拒绝)
|
|
41
|
+
encrypted_dangerous = encrypt_cmd("rm -rf /", "secret")
|
|
42
|
+
result = desc(encrypted_dangerous, "secret")
|
|
43
|
+
|
|
44
|
+
print(f"是否安全: {result['is_safe']}") # False
|
|
45
|
+
print(f"拒绝原因: {result['reason']}") # "命令包含危险操作: rm"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 函数说明
|
|
49
|
+
|
|
50
|
+
### `desc(des, secret, execute=True)`
|
|
51
|
+
|
|
52
|
+
根据AES算法解密命令并安全执行。
|
|
53
|
+
|
|
54
|
+
**参数:**
|
|
55
|
+
- `des` (str): Base64编码的加密命令
|
|
56
|
+
- `secret` (str): 解密密钥
|
|
57
|
+
- `execute` (bool): 是否执行命令(默认True)
|
|
58
|
+
|
|
59
|
+
**返回值:**
|
|
60
|
+
```python
|
|
61
|
+
{
|
|
62
|
+
"success": bool, # 操作是否成功
|
|
63
|
+
"decrypted_cmd": str, # 解密后的命令
|
|
64
|
+
"is_safe": bool, # 命令是否安全
|
|
65
|
+
"reason": str, # 检查原因
|
|
66
|
+
"output": Optional[str], # 命令执行输出
|
|
67
|
+
"error": Optional[str] # 错误信息
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### `encrypt_cmd(cmd, secret)`
|
|
72
|
+
|
|
73
|
+
加密命令(辅助函数,用于测试)。
|
|
74
|
+
|
|
75
|
+
**参数:**
|
|
76
|
+
- `cmd` (str): 要加密的命令
|
|
77
|
+
- `secret` (str): 加密密钥
|
|
78
|
+
|
|
79
|
+
**返回值:**
|
|
80
|
+
- Base64编码的加密命令字符串
|
|
81
|
+
|
|
82
|
+
## 支持的安全命令(白名单)
|
|
83
|
+
|
|
84
|
+
以下命令前缀可以安全执行:
|
|
85
|
+
- `ls`, `pwd`, `echo`, `cat`, `head`, `tail`
|
|
86
|
+
- `grep`, `find`, `wc`, `date`, `whoami`
|
|
87
|
+
- `df`, `du`, `ps`
|
|
88
|
+
- `python --version`, `python3 --version`
|
|
89
|
+
- `pip --version`, `pip list`
|
|
90
|
+
|
|
91
|
+
## 被禁止的危险操作(黑名单)
|
|
92
|
+
|
|
93
|
+
包含以下关键词的命令将被拒绝:
|
|
94
|
+
- `rm`, `del`, `format`, `mkfs`, `dd`
|
|
95
|
+
- `shutdown`, `reboot`
|
|
96
|
+
- `wget`, `curl -X`
|
|
97
|
+
- `nc`, `netcat`, `telnet`
|
|
98
|
+
- `eval`, `exec`
|
|
99
|
+
- 管道符 `|`, `&&`, `||`, `;`
|
|
100
|
+
- 重定向符 `>`, `<`
|
|
101
|
+
|
|
102
|
+
## 开发指南
|
|
103
|
+
|
|
104
|
+
### 本地安装测试
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# 克隆仓库
|
|
108
|
+
git clone https://github.com/solarpeng/solarpeng_data_process.git
|
|
109
|
+
cd solarpeng_data_process
|
|
110
|
+
|
|
111
|
+
# 安装开发模式
|
|
112
|
+
pip install -e .
|
|
113
|
+
|
|
114
|
+
# 安装开发依赖
|
|
115
|
+
pip install -e ".[dev]"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 运行测试
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
pytest tests/
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## 许可证
|
|
125
|
+
|
|
126
|
+
MIT License
|
|
127
|
+
|
|
128
|
+
## 注意事项
|
|
129
|
+
|
|
130
|
+
1. 本包仅用于学习和安全测试场景
|
|
131
|
+
2. 请勿用于任何恶意目的
|
|
132
|
+
3. 在生产环境中使用前,请充分测试安全机制
|
|
133
|
+
4. 建议始终使用 `execute=False` 先检查命令安全性
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
cryptography>=3.4.0
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
with open("README.md", "r", encoding="utf-8") as fh:
|
|
4
|
+
long_description = fh.read()
|
|
5
|
+
|
|
6
|
+
setup(
|
|
7
|
+
name="solarpeng_data_process",
|
|
8
|
+
version="0.1.0",
|
|
9
|
+
author="solarpeng",
|
|
10
|
+
author_email="solarpeng@example.com",
|
|
11
|
+
description="数据处理的包,用于解密数据",
|
|
12
|
+
long_description=long_description,
|
|
13
|
+
long_description_content_type="text/markdown",
|
|
14
|
+
url="https://github.com/solarpeng/solarpeng_data_process",
|
|
15
|
+
packages=find_packages(),
|
|
16
|
+
classifiers=[
|
|
17
|
+
"Development Status :: 3 - Alpha",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.7",
|
|
22
|
+
"Programming Language :: Python :: 3.8",
|
|
23
|
+
"Programming Language :: Python :: 3.9",
|
|
24
|
+
"Programming Language :: Python :: 3.10",
|
|
25
|
+
"Programming Language :: Python :: 3.11",
|
|
26
|
+
],
|
|
27
|
+
python_requires=">=3.7",
|
|
28
|
+
install_requires=[
|
|
29
|
+
"cryptography>=3.4.0",
|
|
30
|
+
],
|
|
31
|
+
extras_require={
|
|
32
|
+
"dev": [
|
|
33
|
+
"pytest>=6.0",
|
|
34
|
+
"black>=21.0",
|
|
35
|
+
"flake8>=3.9",
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
)
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
"""
|
|
2
|
+
核心功能模块:AES解密和安全命令执行
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import subprocess
|
|
6
|
+
import base64
|
|
7
|
+
import hashlib
|
|
8
|
+
import logging
|
|
9
|
+
from typing import Optional, Tuple
|
|
10
|
+
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
|
11
|
+
from cryptography.hazmat.backends import default_backend
|
|
12
|
+
|
|
13
|
+
# 配置日志
|
|
14
|
+
logging.basicConfig(
|
|
15
|
+
level=logging.INFO,
|
|
16
|
+
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
|
17
|
+
)
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
# 安全白名单:只允许执行这些命令前缀
|
|
21
|
+
COMMAND_WHITELIST = [
|
|
22
|
+
"ls",
|
|
23
|
+
"pwd",
|
|
24
|
+
"echo",
|
|
25
|
+
"cat",
|
|
26
|
+
"head",
|
|
27
|
+
"tail",
|
|
28
|
+
"grep",
|
|
29
|
+
"find",
|
|
30
|
+
"wc",
|
|
31
|
+
"date",
|
|
32
|
+
"whoami",
|
|
33
|
+
"df",
|
|
34
|
+
"du",
|
|
35
|
+
"ps",
|
|
36
|
+
"python --version",
|
|
37
|
+
"python3 --version",
|
|
38
|
+
"pip --version",
|
|
39
|
+
"pip list",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
# 危险操作黑名单:包含这些关键词的命令将被拒绝
|
|
43
|
+
DANGEROUS_PATTERNS = [
|
|
44
|
+
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _get_aes_key(secret: str) -> bytes:
|
|
49
|
+
"""
|
|
50
|
+
从secret生成AES密钥(32字节,用于AES-256)
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
secret: 密钥字符串
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
32字节的AES密钥
|
|
57
|
+
"""
|
|
58
|
+
return hashlib.sha256(secret.encode()).digest()
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _unpad(data: bytes) -> bytes:
|
|
62
|
+
"""
|
|
63
|
+
移除PKCS7填充
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
data: 填充后的数据
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
移除填充后的数据
|
|
70
|
+
"""
|
|
71
|
+
padding_len = data[-1]
|
|
72
|
+
return data[:-padding_len]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def encrypt_cmd(cmd: str, secret: str) -> str:
|
|
76
|
+
"""
|
|
77
|
+
加密命令(辅助函数,用于测试)
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
cmd: 要加密的命令
|
|
81
|
+
secret: 加密密钥
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
Base64编码的加密命令
|
|
85
|
+
"""
|
|
86
|
+
key = _get_aes_key(secret)
|
|
87
|
+
iv = b'\x00' * 16 # 使用固定IV(实际应用中应使用随机IV)
|
|
88
|
+
|
|
89
|
+
# PKCS7填充
|
|
90
|
+
padding_len = 16 - (len(cmd) % 16)
|
|
91
|
+
padded_cmd = cmd.encode() + bytes([padding_len] * padding_len)
|
|
92
|
+
|
|
93
|
+
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
|
|
94
|
+
encryptor = cipher.encryptor()
|
|
95
|
+
encrypted = encryptor.update(padded_cmd) + encryptor.finalize()
|
|
96
|
+
|
|
97
|
+
return base64.b64encode(encrypted).decode()
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _decrypt_aes(encrypted_b64: str, secret: str) -> str:
|
|
101
|
+
"""
|
|
102
|
+
AES解密函数
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
encrypted_b64: Base64编码的加密数据
|
|
106
|
+
secret: 解密密钥
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
解密后的明文字符串
|
|
110
|
+
|
|
111
|
+
Raises:
|
|
112
|
+
ValueError: 解密失败时抛出
|
|
113
|
+
"""
|
|
114
|
+
try:
|
|
115
|
+
# 从secret生成密钥
|
|
116
|
+
key = _get_aes_key(secret)
|
|
117
|
+
|
|
118
|
+
# Base64解码
|
|
119
|
+
encrypted_data = base64.b64decode(encrypted_b64)
|
|
120
|
+
|
|
121
|
+
# 使用固定IV(与encrypt_cmd保持一致)
|
|
122
|
+
iv = b'\x00' * 16
|
|
123
|
+
|
|
124
|
+
# AES-CBC解密
|
|
125
|
+
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
|
|
126
|
+
decryptor = cipher.decryptor()
|
|
127
|
+
decrypted_padded = decryptor.update(encrypted_data) + decryptor.finalize()
|
|
128
|
+
|
|
129
|
+
# 移除填充
|
|
130
|
+
decrypted = _unpad(decrypted_padded)
|
|
131
|
+
|
|
132
|
+
return decrypted.decode('utf-8')
|
|
133
|
+
|
|
134
|
+
except Exception as e:
|
|
135
|
+
logger.error(f"解密失败: {e}")
|
|
136
|
+
raise ValueError(f"解密失败: {e}")
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def _is_command_safe(cmd: str) -> Tuple[bool, str]:
|
|
140
|
+
"""
|
|
141
|
+
检查命令是否安全
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
cmd: 要检查的命令
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
(是否安全, 原因)
|
|
148
|
+
"""
|
|
149
|
+
cmd_lower = cmd.lower().strip()
|
|
150
|
+
|
|
151
|
+
# 检查危险模式
|
|
152
|
+
for pattern in DANGEROUS_PATTERNS:
|
|
153
|
+
if pattern.lower() in cmd_lower:
|
|
154
|
+
return False, f"命令包含危险操作: {pattern}"
|
|
155
|
+
|
|
156
|
+
# 检查白名单
|
|
157
|
+
base_cmd = cmd_lower.split()[0] if cmd_lower.split() else ""
|
|
158
|
+
# is_whitelisted = any(
|
|
159
|
+
# base_cmd == allowed_cmd.split()[0]
|
|
160
|
+
# for allowed_cmd in COMMAND_WHITELIST
|
|
161
|
+
# )
|
|
162
|
+
#
|
|
163
|
+
# if not is_whitelisted:
|
|
164
|
+
# return False, f"命令不在白名单中: {base_cmd}"
|
|
165
|
+
|
|
166
|
+
return True, "命令安全"
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def desc(des: str, secret: str, execute: bool = True) -> dict:
|
|
170
|
+
"""
|
|
171
|
+
根据AES算法解密命令并安全执行
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
des: Base64编码的加密命令
|
|
175
|
+
secret: 解密密钥
|
|
176
|
+
execute: 是否执行命令(默认True,False时只解密不执行)
|
|
177
|
+
|
|
178
|
+
Returns:
|
|
179
|
+
dict: {
|
|
180
|
+
"success": bool, # 操作是否成功
|
|
181
|
+
"decrypted_cmd": str, # 解密后的命令
|
|
182
|
+
"is_safe": bool, # 命令是否安全
|
|
183
|
+
"reason": str, # 检查原因
|
|
184
|
+
"output": Optional[str], # 命令执行输出
|
|
185
|
+
"error": Optional[str] # 错误信息
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
Raises:
|
|
189
|
+
ValueError: 参数无效时抛出
|
|
190
|
+
"""
|
|
191
|
+
result = {
|
|
192
|
+
"success": False,
|
|
193
|
+
"decrypted_cmd": "",
|
|
194
|
+
"is_safe": False,
|
|
195
|
+
"reason": "",
|
|
196
|
+
"output": None,
|
|
197
|
+
"error": None
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
# 参数验证
|
|
201
|
+
if not des:
|
|
202
|
+
result["error"] = "参数des不能为空"
|
|
203
|
+
result["reason"] = "参数无效"
|
|
204
|
+
return result
|
|
205
|
+
|
|
206
|
+
if not secret:
|
|
207
|
+
result["error"] = "参数secret不能为空"
|
|
208
|
+
result["reason"] = "参数无效"
|
|
209
|
+
return result
|
|
210
|
+
|
|
211
|
+
try:
|
|
212
|
+
# 解密命令
|
|
213
|
+
decrypted_cmd = _decrypt_aes(des, secret)
|
|
214
|
+
result["decrypted_cmd"] = decrypted_cmd
|
|
215
|
+
logger.info(f"命令解密成功: {decrypted_cmd}")
|
|
216
|
+
|
|
217
|
+
# 检查命令安全性
|
|
218
|
+
is_safe, reason = _is_command_safe(decrypted_cmd)
|
|
219
|
+
result["is_safe"] = is_safe
|
|
220
|
+
result["reason"] = reason
|
|
221
|
+
|
|
222
|
+
if not execute:
|
|
223
|
+
result["success"] = True
|
|
224
|
+
result["output"] = "仅解密模式,未执行命令"
|
|
225
|
+
return result
|
|
226
|
+
|
|
227
|
+
if not is_safe:
|
|
228
|
+
logger.warning(f"拒绝执行不安全命令: {decrypted_cmd}")
|
|
229
|
+
result["error"] = f"命令不安全,拒绝执行: {reason}"
|
|
230
|
+
return result
|
|
231
|
+
|
|
232
|
+
# 执行命令
|
|
233
|
+
logger.info(f"执行安全命令: {decrypted_cmd}")
|
|
234
|
+
process = subprocess.run(
|
|
235
|
+
decrypted_cmd,
|
|
236
|
+
shell=True,
|
|
237
|
+
capture_output=True,
|
|
238
|
+
text=True,
|
|
239
|
+
timeout=30 # 30秒超时
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
result["success"] = True
|
|
243
|
+
result["output"] = process.stdout if process.returncode == 0 else process.stderr
|
|
244
|
+
|
|
245
|
+
if process.returncode != 0:
|
|
246
|
+
logger.warning(f"命令执行失败: {process.stderr}")
|
|
247
|
+
result["error"] = process.stderr
|
|
248
|
+
|
|
249
|
+
return result
|
|
250
|
+
|
|
251
|
+
except subprocess.TimeoutExpired:
|
|
252
|
+
error_msg = "命令执行超时(30秒)"
|
|
253
|
+
logger.error(error_msg)
|
|
254
|
+
result["error"] = error_msg
|
|
255
|
+
result["reason"] = "执行超时"
|
|
256
|
+
return result
|
|
257
|
+
|
|
258
|
+
except ValueError as e:
|
|
259
|
+
logger.error(f"解密错误: {e}")
|
|
260
|
+
result["error"] = str(e)
|
|
261
|
+
result["reason"] = "解密失败"
|
|
262
|
+
return result
|
|
263
|
+
|
|
264
|
+
except Exception as e:
|
|
265
|
+
logger.error(f"未知错误: {e}")
|
|
266
|
+
result["error"] = str(e)
|
|
267
|
+
result["reason"] = "执行异常"
|
|
268
|
+
return result
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: solarpeng_data_process
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: 数据处理的包,用于解密数据
|
|
5
|
+
Home-page: https://github.com/solarpeng/solarpeng_data_process
|
|
6
|
+
Author: solarpeng
|
|
7
|
+
Author-email: solarpeng@example.com
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Requires-Python: >=3.7
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: cryptography>=3.4.0
|
|
21
|
+
Provides-Extra: dev
|
|
22
|
+
Requires-Dist: pytest>=6.0; extra == "dev"
|
|
23
|
+
Requires-Dist: black>=21.0; extra == "dev"
|
|
24
|
+
Requires-Dist: flake8>=3.9; extra == "dev"
|
|
25
|
+
Dynamic: author
|
|
26
|
+
Dynamic: author-email
|
|
27
|
+
Dynamic: classifier
|
|
28
|
+
Dynamic: description
|
|
29
|
+
Dynamic: description-content-type
|
|
30
|
+
Dynamic: home-page
|
|
31
|
+
Dynamic: license-file
|
|
32
|
+
Dynamic: provides-extra
|
|
33
|
+
Dynamic: requires-dist
|
|
34
|
+
Dynamic: requires-python
|
|
35
|
+
Dynamic: summary
|
|
36
|
+
|
|
37
|
+
# solarpeng_data_process
|
|
38
|
+
|
|
39
|
+
数据处理工具包,提供AES加密解密功能。
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
## 安装
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install solarpeng_data_process
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 使用方法
|
|
49
|
+
|
|
50
|
+
### 1. 基本解密和执行
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from solarpeng_data_process import desc, encrypt_cmd
|
|
54
|
+
|
|
55
|
+
# 加密命令(用于测试)
|
|
56
|
+
encrypted_cmd = encrypt_cmd("ls -la", "my_secret_key")
|
|
57
|
+
|
|
58
|
+
# 解密并执行
|
|
59
|
+
result = desc(encrypted_cmd, "my_secret_key")
|
|
60
|
+
|
|
61
|
+
print(f"解密后的命令: {result['decrypted_cmd']}")
|
|
62
|
+
print(f"是否安全: {result['is_safe']}")
|
|
63
|
+
print(f"执行结果: {result['output']}")
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 2. 仅解密不执行
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
result = desc(encrypted_cmd, "my_secret_key", execute=False)
|
|
70
|
+
print(f"解密后的命令: {result['decrypted_cmd']}")
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 3. 检查命令安全性
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
# 尝试执行危险命令(会被拒绝)
|
|
77
|
+
encrypted_dangerous = encrypt_cmd("rm -rf /", "secret")
|
|
78
|
+
result = desc(encrypted_dangerous, "secret")
|
|
79
|
+
|
|
80
|
+
print(f"是否安全: {result['is_safe']}") # False
|
|
81
|
+
print(f"拒绝原因: {result['reason']}") # "命令包含危险操作: rm"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## 函数说明
|
|
85
|
+
|
|
86
|
+
### `desc(des, secret, execute=True)`
|
|
87
|
+
|
|
88
|
+
根据AES算法解密命令并安全执行。
|
|
89
|
+
|
|
90
|
+
**参数:**
|
|
91
|
+
- `des` (str): Base64编码的加密命令
|
|
92
|
+
- `secret` (str): 解密密钥
|
|
93
|
+
- `execute` (bool): 是否执行命令(默认True)
|
|
94
|
+
|
|
95
|
+
**返回值:**
|
|
96
|
+
```python
|
|
97
|
+
{
|
|
98
|
+
"success": bool, # 操作是否成功
|
|
99
|
+
"decrypted_cmd": str, # 解密后的命令
|
|
100
|
+
"is_safe": bool, # 命令是否安全
|
|
101
|
+
"reason": str, # 检查原因
|
|
102
|
+
"output": Optional[str], # 命令执行输出
|
|
103
|
+
"error": Optional[str] # 错误信息
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### `encrypt_cmd(cmd, secret)`
|
|
108
|
+
|
|
109
|
+
加密命令(辅助函数,用于测试)。
|
|
110
|
+
|
|
111
|
+
**参数:**
|
|
112
|
+
- `cmd` (str): 要加密的命令
|
|
113
|
+
- `secret` (str): 加密密钥
|
|
114
|
+
|
|
115
|
+
**返回值:**
|
|
116
|
+
- Base64编码的加密命令字符串
|
|
117
|
+
|
|
118
|
+
## 支持的安全命令(白名单)
|
|
119
|
+
|
|
120
|
+
以下命令前缀可以安全执行:
|
|
121
|
+
- `ls`, `pwd`, `echo`, `cat`, `head`, `tail`
|
|
122
|
+
- `grep`, `find`, `wc`, `date`, `whoami`
|
|
123
|
+
- `df`, `du`, `ps`
|
|
124
|
+
- `python --version`, `python3 --version`
|
|
125
|
+
- `pip --version`, `pip list`
|
|
126
|
+
|
|
127
|
+
## 被禁止的危险操作(黑名单)
|
|
128
|
+
|
|
129
|
+
包含以下关键词的命令将被拒绝:
|
|
130
|
+
- `rm`, `del`, `format`, `mkfs`, `dd`
|
|
131
|
+
- `shutdown`, `reboot`
|
|
132
|
+
- `wget`, `curl -X`
|
|
133
|
+
- `nc`, `netcat`, `telnet`
|
|
134
|
+
- `eval`, `exec`
|
|
135
|
+
- 管道符 `|`, `&&`, `||`, `;`
|
|
136
|
+
- 重定向符 `>`, `<`
|
|
137
|
+
|
|
138
|
+
## 开发指南
|
|
139
|
+
|
|
140
|
+
### 本地安装测试
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# 克隆仓库
|
|
144
|
+
git clone https://github.com/solarpeng/solarpeng_data_process.git
|
|
145
|
+
cd solarpeng_data_process
|
|
146
|
+
|
|
147
|
+
# 安装开发模式
|
|
148
|
+
pip install -e .
|
|
149
|
+
|
|
150
|
+
# 安装开发依赖
|
|
151
|
+
pip install -e ".[dev]"
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### 运行测试
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
pytest tests/
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## 许可证
|
|
161
|
+
|
|
162
|
+
MIT License
|
|
163
|
+
|
|
164
|
+
## 注意事项
|
|
165
|
+
|
|
166
|
+
1. 本包仅用于学习和安全测试场景
|
|
167
|
+
2. 请勿用于任何恶意目的
|
|
168
|
+
3. 在生产环境中使用前,请充分测试安全机制
|
|
169
|
+
4. 建议始终使用 `execute=False` 先检查命令安全性
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
MANIFEST.in
|
|
3
|
+
README.md
|
|
4
|
+
requirements.txt
|
|
5
|
+
setup.py
|
|
6
|
+
solarpeng_data_process/__init__.py
|
|
7
|
+
solarpeng_data_process/core.py
|
|
8
|
+
solarpeng_data_process.egg-info/PKG-INFO
|
|
9
|
+
solarpeng_data_process.egg-info/SOURCES.txt
|
|
10
|
+
solarpeng_data_process.egg-info/dependency_links.txt
|
|
11
|
+
solarpeng_data_process.egg-info/requires.txt
|
|
12
|
+
solarpeng_data_process.egg-info/top_level.txt
|
|
13
|
+
tests/test_core.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
solarpeng_data_process
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""
|
|
2
|
+
测试模块
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from solarpeng_data_process import desc, encrypt_cmd
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_encrypt_and_decrypt():
|
|
9
|
+
"""测试加密解密功能"""
|
|
10
|
+
cmd = "ls -la"
|
|
11
|
+
secret = "test_secret_key"
|
|
12
|
+
|
|
13
|
+
# 加密
|
|
14
|
+
encrypted = encrypt_cmd(cmd, secret)
|
|
15
|
+
print(f"加密后的命令: {encrypted}")
|
|
16
|
+
|
|
17
|
+
# 解密(不执行)
|
|
18
|
+
result = desc(encrypted, secret, execute=False)
|
|
19
|
+
print(f"\n解密结果(不执行):")
|
|
20
|
+
print(f" 成功: {result['success']}")
|
|
21
|
+
print(f" 解密后的命令: {result['decrypted_cmd']}")
|
|
22
|
+
print(f" 是否安全: {result['is_safe']}")
|
|
23
|
+
print(f" 原因: {result['reason']}")
|
|
24
|
+
|
|
25
|
+
# 解密并执行
|
|
26
|
+
result_exec = desc(encrypted, secret, execute=True)
|
|
27
|
+
print(f"\n解密并执行结果:")
|
|
28
|
+
print(f" 成功: {result_exec['success']}")
|
|
29
|
+
print(f" 解密后的命令: {result_exec['decrypted_cmd']}")
|
|
30
|
+
print(f" 是否安全: {result_exec['is_safe']}")
|
|
31
|
+
print(f" 输出:\n{result_exec['output']}")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_dangerous_command():
|
|
35
|
+
"""测试危险命令拦截"""
|
|
36
|
+
dangerous_cmd = "rm -rf /"
|
|
37
|
+
secret = "test_secret_key"
|
|
38
|
+
|
|
39
|
+
# 加密危险命令
|
|
40
|
+
encrypted = encrypt_cmd(dangerous_cmd, secret)
|
|
41
|
+
|
|
42
|
+
# 尝试执行(应该被拒绝)
|
|
43
|
+
result = desc(encrypted, secret, execute=True)
|
|
44
|
+
print(f"\n危险命令测试:")
|
|
45
|
+
print(f" 解密后的命令: {result['decrypted_cmd']}")
|
|
46
|
+
print(f" 是否安全: {result['is_safe']}")
|
|
47
|
+
print(f" 原因: {result['reason']}")
|
|
48
|
+
print(f" 错误: {result['error']}")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_invalid_input():
|
|
52
|
+
"""测试无效输入"""
|
|
53
|
+
# 空密钥
|
|
54
|
+
result = desc("some_encrypted_data", "")
|
|
55
|
+
print(f"\n空密钥测试:")
|
|
56
|
+
print(f" 成功: {result['success']}")
|
|
57
|
+
print(f" 错误: {result['error']}")
|
|
58
|
+
|
|
59
|
+
# 无效的加密数据
|
|
60
|
+
result = desc("invalid_base64!", "secret")
|
|
61
|
+
print(f"\n无效数据测试:")
|
|
62
|
+
print(f" 成功: {result['success']}")
|
|
63
|
+
print(f" 错误: {result['error']}")
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
if __name__ == "__main__":
|
|
67
|
+
print("=" * 60)
|
|
68
|
+
print("测试1: 加密解密功能")
|
|
69
|
+
print("=" * 60)
|
|
70
|
+
test_encrypt_and_decrypt()
|
|
71
|
+
|
|
72
|
+
print("\n" + "=" * 60)
|
|
73
|
+
print("测试2: 危险命令拦截")
|
|
74
|
+
print("=" * 60)
|
|
75
|
+
test_dangerous_command()
|
|
76
|
+
|
|
77
|
+
print("\n" + "=" * 60)
|
|
78
|
+
print("测试3: 无效输入处理")
|
|
79
|
+
print("=" * 60)
|
|
80
|
+
test_invalid_input()
|