易加密(easy_encryption_tool)
工具的安装
基础安装(仅国际算法)
以下命令安装后即可使用 AES、RSA、ECC、SHA 系列、HMAC(国际哈希)等算法:
pip install easy-encryption-tool
国密算法支持(可选)
3.0 起,国密算法(SM2、SM3、SM4、SM9、ZUC、SM3-KDF)改为直连 GmSSL C 库(版本 >= 3.1.1),不再依赖任何 Python 国密包。工具在运行时自动探测原生库:
- 默认候选路径:
~/.gmssl_3.1.1_install/lib/下的libgmssl.so.3.1/libgmssl.3.1.dylib(含不带版本号的软链接名),以及系统find_library("gmssl")能找到的位置; - 显式指定:设置环境变量
EET_GMSSL_LIB_PATH指向 libgmssl 共享库文件(推荐做法,见下节环境变量表)。
自行编译 GmSSL 的方法见官方仓库 guanzhi/GmSSL;图文指南可参考 easy-gmssl-sdk(博客站)。
依赖国密算法的命令:hash -a sm3、hmac -a sm3、sm2、sm4、sm9、zuc、kdf -a sm3、kdf -a pbkdf2-sm3、cert-parse -g(kdf -a hkdf 走 cryptography,不在此列)。库缺失时执行这些命令会输出结构化错误并给出修复指引(构建 GmSSL 或设置 EET_GMSSL_LIB_PATH),不会静默回退。
环境变量
| 变量 | 作用 | 说明 |
|---|---|---|
EET_GMSSL_LIB_PATH |
指定 libgmssl 共享库的文件路径 | 显式指定但加载失败时给出含路径的明确报错,不回退默认候选 |
EET_DEBUG_TIMING |
输出命令耗时调试信息 | 仅排障用 |
# 示例:显式指定原生库后运行国密命令
export EET_GMSSL_LIB_PATH=~/.gmssl_3.1.1_install/lib/libgmssl.3.1.dylib
easy_encryption_tool sm2 --help
口令与机密数据的使用边界
- 命令行上的口令对同用户进程可见:
-p/--password、-k/--key这类值经 argv 传入,同一台主机上能查看你进程列表的同一用户(或 root)可用ps读到明文。共享主机或高敏感环境请改用密钥文件输入,或只在独占环境中传口令。 -i的值不做掩码:eet shell交互历史(~/.eet_shell_history)会自动把口令、密钥、IV、种子等敏感选项值掩成***,但-i按普通数据处理、原文记录;在你自己的终端里,整条命令同样会进该 shell 的历史文件。机密明文请用文件输入(-f/输入文件参数),或事后清理历史。- 密钥文件拒绝覆盖是刻意设计:
-f前缀对应的公私钥文件已存在时命令直接失败,工具不提供--force——旧私钥一旦被覆盖,用它加密过的数据将永久无法解开。脚本化场景请先显式移走旧文件,或换一个新的-f前缀。
后量子算法支持(可选)
如需使用 后量子算法(ML-KEM 密钥封装、ML-DSA 签名),需要 cryptography >= 47(ML-DSA ExternalMu 模式需 >= 49):
# 推荐:通过 [pqc] extra 一次性安装并保证 cryptography 版本(>= 50)
pip install "easy-encryption-tool[pqc]"
# 或:单独升级 cryptography(若已安装 easy-encryption-tool)
pip install "cryptography>=47"
依赖后量子的命令:pqc mlkem、pqc mldsa。cryptography 版本过旧时,执行这些命令会提示升级;参数集(如 ML-KEM-512)是否可用取决于 cryptography 版本,easy_encryption_tool version 的 Dependencies 行会列出。
Server 模式(可选,实验性)
如需以 HTTP 服务方式使用 CLI 能力,安装 [server] extra(FastAPI + uvicorn):
pip install "easy-encryption-tool[server]"
未安装时执行 easy_encryption_tool server 会输出结构化错误并给出安装指引,不影响其他命令。用法见下文 Server 模式 一节。
实验性声明:
server命令自 3.0.x 起入口已注释停用(eet server返回 "No such command"):并发请求下的进程内哨兵存在已知竞态(评审 R4-1),修复并稳定前不提供该命令。server_command模块与create_app保留在代码库中,供测试与将来修复后重新启用。
项目地址:easy-encryption-tool · PyPI
国密算法支持说明
| 算法 | 说明 | 对应命令 | 需 GmSSL 原生库 |
|---|---|---|---|
| SM2 | 国密非对称算法,对标 RSA | sm2(加解密、签名验签) |
✓ |
| SM3 | 国密哈希算法 | hash -a sm3 |
✓ |
| SM4 | 国密对称算法,对标 AES | sm4(CBC/GCM/CTR 模式) |
✓ |
| SM9 | 国密标识密码(IBC) | sm9(主密钥生成、用户密钥派生、加解密、签名验签) |
✓ |
| ZUC | 祖冲之流密码 | zuc |
✓ |
| HKDF | RFC 5869 密钥派生(SHA-2 族,3.2.0 起默认) | kdf -a hkdf |
|
| SM3-KDF | SM3 密钥派生 | kdf -a sm3 |
✓ |
| PBKDF2-HMAC-SM3 | 口令派生 | kdf -a pbkdf2-sm3 |
✓ |
| SM2 证书 | 国密证书解析 | cert-parse -g |
✓ |
国际算法(AES、RSA、ECC、SHA、HMAC 等)无需 GmSSL 原生库,仅安装 easy-encryption-tool 即可使用。
工具支持的命令
❯ easy_encryption_tool --help
Usage: easy_encryption_tool [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
aes aes加解密工具,默认支持 aes-cbc-256 和 aes-gcm-256
cert-parse 解析 pem 或 der 格式的证书,支持国际算法及国密 SM2(-g)
convert 字符串格式转换工具,支持 UTF-8、Base64、Hex 互转
doctor 环境与可选能力体检(cryptography/PQC、GmSSL 原生库与 external-mu 能力、七家云 KMS)
ecc ecc签名验签和密钥交换验证工具
envelope 信封加密:非对称密钥包裹数据密钥(DEK)
hash 哈希摘要工具,支持 SM3、SHA256、SHA384、SHA512
hmac hmac消息验证码工具,支持 SM3 及国际哈希算法
int-to-bytes 整数与大/小端十六进制字节互转
kdf 密钥派生工具,支持 HKDF(RFC 5869,默认,无需原生库)、SM3-KDF 与 PBKDF2-HMAC-SM3(需 GmSSL 原生库)
pqc 后量子命令组:ML-KEM 密钥封装与 ML-DSA 签名验签(需 cryptography>=47)
random-bytes 随机字节流生成器(1-1024 字节,默认 Base64 输出)
random-str 随机字符串生成器
rsa rsa加解密和签名验签工具
server 以 HTTP 服务方式提供 CLI 能力(FastAPI,需 [server] extra;3.0.x 实验特性,入口已注释停用)
sm2 国密 SM2 加解密和签名验签工具(多种密文/签名格式)
sm4 国密 SM4 对称加解密工具,支持 cbc、gcm 和 ctr 模式
sm9 国密 SM9 标识密码命令组(主密钥/用户密钥/加解密/签名验签)
structured 结构化文件加密:JSON/YAML/INI 叶子级 AEAD 加密
ts 时间戳转换工具(秒级,本地/UTC/毫秒互转)
version 展示当前版本信息以及运行时信息
zuc ZUC 祖冲之流密码加解密工具
install-completion 安装 Shell Tab 自动补全(bash/zsh/fish)
Shell Tab 自动补全
支持对子命令、选项及选项值进行 Tab 补全,提升命令行使用效率。安装方式:
# 生成补全脚本并加载(zsh 示例)
easy_encryption_tool install-completion --shell zsh -p ~/.easy_encryption_tool_complete.sh
source ~/.easy_encryption_tool_complete.sh
补全能力包括:子命令补全、选项补全、固定可选值补全(如 -A encrypt/decrypt、-m cbc/gcm)、文件路径补全(如 -i 在指定 -f 时、-o、密钥文件路径等)。详见 CLI 使用说明。
环境与能力体检(eet doctor)
一行命令检查本机环境与全部可选能力,缺什么给什么修复命令:
❯ easy_encryption_tool doctor
╭──────────────────────────────── eet doctor ────────────────────────────────╮
│ │
│ python ✓ ok 3.12.7 │
│ eet ✓ ok v3.0.0 │
│ │
│ cryptography ✓ ok 50.0.1 │
│ pqc ✓ ok available │
│ (ML-KEM-768/1024, ML-DSA-44/65/87) │
│ external-mu ok │
│ ── native libraries ── │
│ gmssl (native) ✓ ok GmSSL 3.1.1 │
│ (/Users/cyx/.gmssl_3.1.1_in… │
│ ML-DSA external-mu ✓ ok native │
│ (cryptography 50.0.1) │
│ │
│ ── cloud KMS backends ── │
│ kms aws ✓ ok 1.35.53 (boto3) │
│ kms tencentcloud ✓ ok 3.1.87 (tencentcloud.kms.… │
│ kms aliyun ✓ ok 2.4.0 (alibabacloud_kms2… │
│ kms huawei ✓ ok 3.1.186 (huaweicloudsdkkms) │
│ kms google ✓ ok 3.11.0 (google.cloud.kms_v1) │
│ kms vault ✓ ok 2.4.0 (hvac) │
│ kms azure ✗ missing azure.keyvault.keys.crypt… │
│ ── guides ── │
│ azure-keyvault-keys https://pypi.org/projec… │
╰──────────────────────────────────────────────────────────────────────────────╯
体检项分四组:核心运行时(python/eet)、密码栈(cryptography 及 PQC 参数集)、原生库与能力(GmSSL 国密依赖;ML-DSA external-mu 能力行——3.1 起走 cryptography 原生 sign_mu/verify_mu(>= 49),不再探测系统 OpenSSL)、七家云 KMS SDK。缺失项的 Fix 列给出修复方式:KMS SDK 缺失给 pip install 命令;GmSSL 缺失给构建指引与 EET_GMSSL_LIB_PATH;external-mu 缺失给 [pqc] extra 安装命令。表尾 guides 小节只为非 ok 的行列出官方与博客链接。doctor 默认输出表格适合直接阅读与截图排障;--json / --pretty-json 走统一输出契约,供脚本消费。
显示版本
缺省输出 rich 面板:版本号、功能清单、运行时环境、依赖画像(GmSSL 原生库版本与路径、external-mu 能力(cryptography 原生)、cryptography / rich / click、PQC 参数集、七家云 KMS SDK 安装状态)。
3.0 起 version 支持 --json / --pretty-json,输出与其他加密命令一致的标准输出契约,result.dependencies 携带完整依赖画像快照,便于脚本化采集:
❯ easy_encryption_tool version --json
{"metadata": {"operation": "version", "algorithm": "version", "input": {"type": "none", "size": 0}}, "result": {"version": "v3.2.1", "dependencies": {"gmssl_native_lib": {"available": true, "version": "GmSSL 3.1.1", "path": "/Users/cyx/.gmssl_3.1.1_install/lib/libgmssl.3.1.dylib"}, "external_mu": {"available": true, "via": "cryptography sign_mu/verify_mu", "cryptography": "50.0.1"}, "cryptography": "50.0.1", "rich": "15.0.0", "click": "8.0.4", "pqc": "available (ML-KEM-768/1024, ML-DSA-44/65/87); external-mu ok", "kms_sdks": {"kms aws": "not installed", "kms tencentcloud": "not installed", "kms aliyun": "not installed", "kms huawei": "not installed", "kms google": "not installed", "kms vault": "not installed", "kms azure": "not installed"}}}, "runtime": {"request_id": "e05f7c02-2d02-4dba-8f5b-f292cd502b6a", "timestamp": "2026-09-02T19:06:26.624378+08:00", "duration_ms": 2.784, "host": "MacM2Max-2.local", "version": "v3.2.1"}}
生成随机字符串
支持的参数
❯ easy_encryption_tool random-str --help
Usage: main.py random-str [OPTIONS]
Options:
-l, --length INTEGER RANGE 最小生成一个字节字符串,最大长度由系统最大整型值决定 [default: 32;
1<=x<=9223372036854775807]
-o, --output-file TEXT 指定输出的文件,文件需要具有可写权限
--help Show this message and exit.
直接输出到 stdout
# -l指定随机字符串的长度为32字节
❯ easy_encryption_tool random-str -l 32
------ 632aebf88dfe8f93 begin@2024-04-04_15:01:23.987 ------
qBg@G%Tp((@2h81tg@9II7#0Su4`B06$
------ 632aebf88dfe8f93 took 0.049 milli-seconds to execute ------
输出到文件
❯ easy_encryption_tool random-str -l 37 -o test_random
------ 71a2d32b0816349f begin@2024-04-04_15:24:22.476 ------
write to test_random success
------ 71a2d32b0816349f took 0.299 milli-seconds to execute ------
❯ cat test_random
_9@mL1`D2#NZz5m@!X7sdHKqQEowM6%o3E`bj
当指定的文件不可写时
❯ easy_encryption_tool random-str -l 37 -o test_random
------ 0e4094ce6a4fe22c begin@2024-04-04_15:25:49.125 ------
try write to test_random failed
------ 0e4094ce6a4fe22c took 0.030 milli-seconds to execute ------
AES对称加密算法
支持的命令参数
❯ easy_encryption_tool aes --help
Usage: eet aes [OPTIONS]
AES encrypt/decrypt. Encrypt: each missing key/IV piece (-k/-v or b64
variants) is generated from full-entropy CSPRNG bytes and output as base64.
Decrypt: requires explicit key/IV (--key-b64/--iv-b64 or -k/-v). Input:
plaintext (-i), base64 (-e), or file (-f).
╭─ Options ────────────────────────────────────────────────────────────────────╮
│ --mode -m [cbc|gcm] AES mode: cbc or gcm │
│ [default: cbc] │
│ --key -k TEXT Key string (normalized to 32 │
│ bytes / 256-bit, │
│ CipherHUB-compatible). │
│ Encrypt: a missing key is │
│ randomly generated (base64 in │
│ output); decrypt requires it. │
│ The CipherHUB web preset key │
│ applies only when passed │
│ explicitly │
│ --iv-nonce -v TEXT CBC uses IV (16 bytes); GCM │
│ uses nonce (12 bytes). │
│ Encrypt: a missing IV/nonce │
│ is randomly generated (base64 │
│ in output); decrypt requires │
│ it │
│ --aad TEXT GCM additional authenticated │
│ data (AAD), default: │
│ "密码学人 CipherHUB 默认 AAD │
│ 数据" [default: 密码学人 │
│ CipherHUB 默认 AAD 数据] │
│ --random-key-iv -r Force both key and IV/nonce │
│ random (encrypt only). On │
│ encrypt any missing │
│ -k/-v/--key-b64/--iv-b64 │
│ piece is randomly generated │
│ anyway and shown as base64; │
│ use --key-b64/--iv-b64 for │
│ decrypt. Mutually exclusive │
│ with │
│ -k/-v/--key-b64/--iv-b64. │
│ --key-b64 TEXT Base64 key bytes (must decode │
│ to 32 bytes). Use for decrypt │
│ with key from encrypt -r │
│ output. Mutually exclusive │
│ with -k │
│ --iv-b64 TEXT Base64 IV/nonce bytes (CBC │
│ 16, GCM 12). Use for decrypt │
│ with IV from encrypt -r │
│ output. Mutually exclusive │
│ with -v │
│ --action -A [encrypt|decrypt] Action: encrypt or decrypt │
│ [default: encrypt] │
│ * --input-data -i TEXT Input data. Encrypt: │
│ text/base64/file. Decrypt: │
│ base64/file [required] │
│ --is-base64-encoded -e Interpret -i as base64 data │
│ (mutually exclusive with -f) │
│ --is-a-file -f Interpret -i as file path │
│ (mutually exclusive with -e) │
│ --input-limit -l INTEGER Max non-file input size in MB │
│ [default: 1] │
│ --output-file -o TEXT Output file path (required │
│ with -f) │
│ --no-force Do not overwrite an existing │
│ output file │
│ --gcm-pad [GCM only] Enable PKCS#7 │
│ padding before encrypt and │
│ unpadding after decrypt. │
│ Default is no padding; │
│ encrypt and decrypt must both │
│ use or both omit --gcm-pad. │
│ File decrypt with --gcm-pad │
│ loads entire file into │
│ memory; large files may cause │
│ OOM. │
│ --pretty-json Output colored pretty JSON │
│ (default) │
│ --json Output single-line JSON (use │
│ with jq for field extraction) │
│ --help Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────╯
关于密钥、IV和模式的预设
- 加密模式:仅支持 CBC 模式和 GCM 模式
- 填充规则:CBC 模式始终按 PKCS#7 填充;GCM 模式默认不填充(与 CipherHUB stream_cipher 兼容),若需填充可加
--gcm-pad,加密与解密需一致使用 - 密钥:长度必须恰好 32 字节(256 位)。加密时完全不给则随机生成并以 base64 输出;给了但不足 32 字节会被拒绝(2.8.1 起不再随机补齐——补齐过的密钥无法复现,密文将永远解不开);超过 32 字节会截断并警告
- IV:CBC 模式下时 IV 长度默认 16 字节,GCM 模式下 Nonce 长度默认 12 字节(其中 4 字节预留作为计数器,由算法自行处理);与密钥同理——不给则加密时随机生成,给短了拒绝,给长了截断并警告
关于输入数据的预设
加密行为支持三种数据输入方式:
- 字符串如:hello,world
- Base64 编码的字节流如:aGVsbG8sd29ybGQK(生成的 shell 命令:echo "hello,world"|base64)
- 文件名路径:~/data/test_plain.txt
解密行为支持两种数据输入方式:
- Base64 编码的字节流如:/hEP3J5KHZgNnCeBD/W5MQ==
- 文件名路径:~/data/test_cipher.bin
指定密钥和 IV
使用默认的密钥
# 加密hello,world,密钥和 iv 均为默认数据
❯ easy_encryption_tool aes -m cbc -a encrypt -i hello,world
------ 15ec713c1b8c0ef3 begin@2024-04-04_15:29:25.203 ------
plain size:11
key:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
iv:vvvvvvvvvvvvvvvv
cipher size:16
cipher:PcgHm88aPtUjwVx+SDvMqw==
auth_tag_size:0
auth_tag:
------ 15ec713c1b8c0ef3 took 26.874 milli-seconds to execute ------
# 解密hello,world
❯ easy_encryption_tool aes -m cbc -a decrypt -i PcgHm88aPtUjwVx+SDvMqw== -e
------ fb11b7f46716698e begin@2024-04-04_15:29:40.648 ------
cipher size:16
plain size:11
str plain:hello,world
------ fb11b7f46716698e took 13.754 milli-seconds to execute ------
使用随机生成的密钥
# 加密 -r 表示随机生成密钥和 IV
❯ easy_encryption_tool aes -m cbc -a encrypt -i hello,world -r
------ d39dbe0c997a868b begin@2024-04-04_15:29:54.358 ------
plain size:11
key:Ta9M^p)+L1+_L^26!Xmcs6AR2^3p_5FY
iv:9*H`JW(dzpi5HBd0
cipher size:16
cipher:h7lMpOimKxO0zr7AMVsI9w==
auth_tag_size:0
auth_tag:
------ d39dbe0c997a868b took 14.258 milli-seconds to execute ------
# 解密
# -k 和 -v 的值使用引号是为了预防里面带有特殊 shell 命令的字符比如‘&’、‘!’等等
❯ easy_encryption_tool aes -m cbc -a decrypt -i h7lMpOimKxO0zr7AMVsI9w== -e -k 'Ta9M^p)+L1+_L^26!Xmcs6AR2^3p_5FY' -v '9*H`JW(dzpi5HBd0'
------ 1332e834884e2b0e begin@2024-04-04_15:31:06.666 ------
cipher size:16
plain size:11
str plain:hello,world
------ 1332e834884e2b0e took 15.691 milli-seconds to execute ------
使用指定的密钥
密钥或 iv 长度不够时会自动填充
# 加密,此时 key(1234) 和 iv(1234) 长度都不足
❯ easy_encryption_tool aes -m cbc -a encrypt -i hello,world -k 1234 -v 4321
------ c5abaa3af64a5f6c begin@2024-04-04_15:31:34.231 ------
plain size:11
key:1234g6Z0GE$Z@ybb^IIb3FN5Ux%BE=00
iv:4321nJ4j*Nud(yH4
cipher size:16
cipher:dHJKRtSi8KsCe6ZFltF0kA==
auth_tag_size:0
auth_tag:
------ c5abaa3af64a5f6c took 14.648 milli-seconds to execute ------
# 解密
❯ easy_encryption_tool aes -m cbc -a decrypt -i dHJKRtSi8KsCe6ZFltF0kA== -e -k '1234g6Z0GE$Z@ybb^IIb3FN5Ux%BE=00' -v '4321nJ4j*Nud(yH4'
------ 7c2018bd08e58a63 begin@2024-04-04_15:32:16.014 ------
cipher size:16
plain size:11
str plain:hello,world
------ 7c2018bd08e58a63 took 14.343 milli-seconds to execute ------
密钥或iv超长时会自动截取
# 加密,此时密钥和 iv 的长度都超长
❯ easy_encryption_tool aes -m cbc -a encrypt -i hello,world -k 12345678901234567890123456789012abcde -v 1234567890123456abcde
------ 8ff4bd52df0a0865 begin@2024-04-04_15:32:31.104 ------
plain size:11
key:12345678901234567890123456789012
iv:1234567890123456
cipher size:16
cipher:wOXlD3Ie7xiQh81aR8N1tQ==
auth_tag_size:0
auth_tag:
------ 8ff4bd52df0a0865 took 13.849 milli-seconds to execute ------
# 解密
❯ easy_encryption_tool aes -m cbc -a decrypt -i wOXlD3Ie7xiQh81aR8N1tQ== -e -k 12345678901234567890123456789012 -v 1234567890123456
------ 50ea907cc74207ad begin@2024-04-04_15:32:46.937 ------
cipher size:16
plain size:11
str plain:hello,world
------ 50ea907cc74207ad took 13.690 milli-seconds to execute ------
指定明文
输入字符串作为明文
# 加密
❯ easy_encryption_tool aes -m cbc -a encrypt -i hello,world
------ e6dc33dc9ca747d0 begin@2024-04-04_15:33:05.505 ------
plain size:11
key:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
iv:vvvvvvvvvvvvvvvv
cipher size:16
cipher:PcgHm88aPtUjwVx+SDvMqw==
auth_tag_size:0
auth_tag:
------ e6dc33dc9ca747d0 took 14.098 milli-seconds to execute ------
输入base64编码的字节流作为明文
# 加密 -e 表明输入的数据经过了 base64 编码,加密或解密时需要先将数据做 base64 解码
❯ easy_encryption_tool aes -m cbc -a encrypt -i 9H8InkmnUjgVHC8elQxThUSmzkO0tuGlP0Si4X1kmoK7azOIDoFnt8dXjeWNGb+dc7qiEBPi+jymax4i+24KBQ== -e
------ fc5b00c0a79ff88e begin@2024-04-04_15:33:17.585 ------
plain size:64
key:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
iv:vvvvvvvvvvvvvvvv
cipher size:80
cipher:ZHq7uJQjkx/2Bm5ZmrcuS/5c/s/qayDVcuWZmvsTle1RAUKyv0dvGhOVYEINmL35eSMVoT3Bx/M6lU9NGCuiM5OxyJ2VcuB30dp8GVZg0oQ=
auth_tag_size:0
auth_tag:
------ fc5b00c0a79ff88e took 14.382 milli-seconds to execute ------
输入文件作为明文
# 加密
❯ easy_encryption_tool aes -m cbc -a encrypt -i ./test_data/test_plain.txt -f -o ./tmp_cipher.bin
------ 1d5fb25a63f1ed4d begin@2024-04-04_15:33:57.461 ------
input file size:64
cipher size:80
key:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
iv:vvvvvvvvvvvvvvvv
auth_tag_size:0
auth_tag:
------ 1d5fb25a63f1ed4d took 14.859 milli-seconds to execute ------
# 查看文件大小,密文文件比明文文件多了16 字节,这是因为明文的最后一个 block 会做 PKCS#7 数据填充
❯ cat ./test_data/test_plain.txt
123456789012345612345678901234561234567890123456123456789012345
❯ ll ./test_data/test_plain.txt
-rw-r--r-- 1 xxxx staff 64 Apr 2 21:06 ./test_data/test_plain.txt
❯ ll ./tmp_cipher.bin
-rw-r--r-- 1 xxxx staff 80 Apr 4 15:33 ./tmp_cipher.bin
指定密文
输入base64编码的字节流作为密文
如果解密出来的明文直接可以以字符串方式打印
# 明文本身为 hello,world
❯ easy_encryption_tool aes -m cbc -a decrypt -i PcgHm88aPtUjwVx+SDvMqw== -e
------ 2b6a86223a0ba102 begin@2024-04-04_15:35:26.995 ------
cipher size:16
plain size:11
str plain:hello,world
------ 2b6a86223a0ba102 took 13.676 milli-seconds to execute ------
如果解密出来的密文不能以字符串方式打印
# 明文本身是字节流
❯ easy_encryption_tool aes -m cbc -a decrypt -i ZHq7uJQjkx/2Bm5ZmrcuS/5c/s/qayDVcuWZmvsTle1RAUKyv0dvGhOVYEINmL35eSMVoT3Bx/M6lU9NGCuiM5OxyJ2VcuB30dp8GVZg0oQ= -e
------ d399aa241aa6b691 begin@2024-04-04_15:35:39.781 ------
cipher size:80
plain size:64
b64 encoded plain:9H8InkmnUjgVHC8elQxThUSmzkO0tuGlP0Si4X1kmoK7azOIDoFnt8dXjeWNGb+dc7qiEBPi+jymax4i+24KBQ==
------ d399aa241aa6b691 took 13.869 milli-seconds to execute ------
输入文件作为密文
❯ easy_encryption_tool aes -m cbc -a decrypt -i ./tmp_cipher.bin -f -o ./tmp_plain.txt
------ 1f27fb444d1139b2 begin@2024-04-04_15:36:03.267 ------
input file size:80
decrypt ./tmp_cipher.bin success
write to ./tmp_plain.txt
plain size:64
------ 1f27fb444d1139b2 took 14.259 milli-seconds to execute ------
# 文件大小一致、内容一致
❯ ll ./tmp_plain.txt ./test_data/test_plain.txt
-rw-r--r-- 1 xxxx staff 64 Apr 2 21:06 ./test_data/test_plain.txt
-rw-r--r-- 1 xxxx staff 64 Apr 3 10:58 ./tmp_plain.txt
❯ cat tmp_plain.txt ./test_data/test_plain.txt
123456789012345612345678901234561234567890123456123456789012345
123456789012345612345678901234561234567890123456123456789012345
使用GCM模式
GCM 填充说明:GCM 模式默认不对明文做 PKCS#7 填充,直接加密原始数据,与 CipherHUB stream_cipher 兼容。若需 PKCS#7 填充,请加 --gcm-pad,加密与解密必须一致使用。
代码层面的预设
代码中,对于加密的明文默认使用固定的上下文数据作为验证数据
if mode == aes_gcm_mode:
self.__auth_data = json.dumps({
'mode': mode, # 值为 gcm
'obj': 'aes_operator',
}).encode(encoding = 'utf-8')
if action == aes_encrypt_action:
self.__aes_gcm_obj = Cipher(algorithms.AES(self.__key), modes.GCM(self.__iv), backend = default_backend())
self.__aes_gcm_enc_op = self.__aes_gcm_obj.encryptor()
self.__aes_gcm_enc_op.authenticate_additional_data(self.__auth_data)
对字符串做加解密
# gcm模式加密
❯ easy_encryption_tool aes -m gcm -a encrypt -i hello,world
------ b8e914a4634acde7 begin@2024-04-04_15:36:39.558 ------
plain size:11
key:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
iv:vvvvvvvvvvvv
cipher size:16
cipher:TajM7IwxIZIoqHkU87dY7w==
auth_tag_size:16
auth_tag:df8z3ccRyGOQTluw26dIlA==
------ b8e914a4634acde7 took 14.280 milli-seconds to execute ------
对 base64 编码的字节流做加解密
# 加密
❯ easy_encryption_tool aes -m gcm -a encrypt -i 9H8InkmnUjgVHC8elQxThUSmzkO0tuGlP0Si4X1kmoK7azOIDoFnt8dXjeWNGb+dc7qiEBPi+jymax4i+24KBQ== -e
------ 7781b5bffdcef12b begin@2024-04-04_15:37:05.562 ------
plain size:64
key:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
iv:vvvvvvvvvvvv
cipher size:80
cipher:0bKoHqq6BMVP2DIPY74Ob2tGi69gVzHSZREJT3DAeCsVU52ykLcfKZIq/GD2PEkCwLLE8o37nvPK9t/pr4LStVy5unAN/EVllIvvopq2pis=
auth_tag_size:16
auth_tag:B1Jp0FuxyNXAOVAvj9S+Ow==
------ 7781b5bffdcef12b took 13.915 milli-seconds to execute ------
# 解密
❯ easy_encryption_tool aes -m gcm -a decrypt -i 0bKoHqq6BMVP2DIPY74Ob2tGi69gVzHSZREJT3DAeCsVU52ykLcfKZIq/GD2PEkCwLLE8o37nvPK9t/pr4LStVy5unAN/EVllIvvopq2pis= -e -t B1Jp0FuxyNXAOVAvj9S+Ow==
------ 5bcc82c4235dcde4 begin@2024-04-04_15:37:17.397 ------
cipher size:80
plain size:64
b64 encoded plain:9H8InkmnUjgVHC8elQxThUSmzkO0tuGlP0Si4X1kmoK7azOIDoFnt8dXjeWNGb+dc7qiEBPi+jymax4i+24KBQ==
------ 5bcc82c4235dcde4 took 13.844 milli-seconds to execute ------
对文件做加解密
# 加密
❯ easy_encryption_tool aes -m gcm -a encrypt -i ./test_data/test_plain.txt -f -o ./tmp_gcm_cipher.bin
------ 0c4605fe37eb7e4b begin@2024-04-04_15:37:45.621 ------
input file size:64
cipher size:80
key:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
iv:vvvvvvvvvvvv
auth_tag_size:16
auth_tag:krJchuyaDRYHnu5tsy8UzA==
------ 0c4605fe37eb7e4b took 14.347 milli-seconds to execute ------
# 解密
❯ easy_encryption_tool aes -m gcm -a decrypt -i ./tmp_gcm_cipher.bin -f -o tmp_gcm_plain.txt -t krJchuyaDRYHnu5tsy8UzA==
------ d181cab086ebaeaa begin@2024-04-04_15:38:00.709 ------
input file size:80
decrypt ./tmp_gcm_cipher.bin success
write to tmp_gcm_plain.txt
plain size:64
------ d181cab086ebaeaa took 14.397 milli-seconds to execute ------
tag值对解密很重要
# gcm模式正常解密
❯ easy_encryption_tool aes -m gcm -a decrypt -i TajM7IwxIZIoqHkU87dY7w== -e -t df8z3ccRyGOQTluw26dIlA==
------ 86699527d1227e39 begin@2024-04-04_15:38:22.322 ------
cipher size:16
plain size:11
str plain:hello,world
------ 86699527d1227e39 took 13.987 milli-seconds to execute ------
# 不传 gcm tag 会报错
❯ easy_encryption_tool aes -m gcm -a decrypt -i TajM7IwxIZIoqHkU87dY7w== -e
------ 11c1531f0fd5b7a8 begin@2024-04-04_15:38:32.957 ------
expected a gcm tag(16 Bytes)
------ 11c1531f0fd5b7a8 took 0.030 milli-seconds to execute ------
# 传错误的 tag 会解密失败
❯ easy_encryption_tool aes -m gcm -a decrypt -i TajM7IwxIZIoqHkU87dY7w== -e -t H7n7OzKgQyHL86zbnQ0r+g==
------ 90580b5c3649a1ba begin@2024-04-04_15:38:46.823 ------
decrypt TajM7IwxIZIoqHkU87dY7w== failed:
------ 90580b5c3649a1ba took 14.030 milli-seconds to execute ------
常用的参数合法性检查
-m 模式参数
easy_encryption_tool aes -m abc -a encrypt -i 1234
Usage: main.py aes [OPTIONS]
Try 'main.py aes --help' for help.
Error: Invalid value for '-m' / '--mode': 'abc' is not one of 'cbc', 'gcm'.
-a 动作参数
easy_encryption_tool aes -m cbc -a abc -i 1234
Usage: main.py aes [OPTIONS]
Try 'main.py aes --help' for help.
Error: Invalid value for '-a' / '--action': 'abc' is not one of 'encrypt', 'decrypt'.
-i 输入参数
字符串超限
# 这里设置最大限制为0MBytes,也就是不允许加密,这里是故意预留的
❯ easy_encryption_tool aes -m cbc -a encrypt -i 1234 -l 0
------ 5ce766f36cc28968 begin@2024-04-04_15:39:42.675 ------
the data exceeds the maximum bytes limit, limited to:0Bytes, now:4Bytes
------ 5ce766f36cc28968 took 0.023 milli-seconds to execute ------
非法的base64编码数据
# 任意构造的字符串
❯ easy_encryption_tool aes -m cbc -a encrypt -i qwert -e
------ 4844fa0e0939482d begin@2024-04-04_15:39:53.597 ------
invalid b64 encoded data:qwert
------ 4844fa0e0939482d took 0.044 milli-seconds to execute ------
# base64数据缺少字符(正确的是:ZUD3MJT3ohiimrryNW7jBw==)
❯ easy_encryption_tool aes -m cbc -a encrypt -i ZUD3MJT3ohiimrryNW7jBw -e
------ 22301b388db43f9d begin@2024-04-04_15:40:05.092 ------
invalid b64 encoded data:ZUD3MJT3ohiimrryNW7jBw
------ 22301b388db43f9d took 0.036 milli-seconds to execute ------
文件不可读
# 创建文件并设置为只可root读
sudo touch test_plain
sudo chmod 400 test_plain
# 查看文件
ll test_plain
-r-------- 1 root staff 0 Apr 3 11:29 test_plain
# 使用其他用户运行命令访问
easy_encryption_tool aes -m cbc -a encrypt -i test_plain -f
test_plain may not exist or may be unreadable
------ aes_command took 0.076 milli-seconds to execute ------
文件不可写
# 文件写权限检查失败
easy_encryption_tool aes -m cbc -a encrypt -i tmp_gcm_plain.txt -f -o test_plain
tmp_gcm_plain.txt opened in mode rb success
test_plain may not exist or may not writable
tmp_gcm_plain.txt closed success
------ aes_command took 0.126 milli-seconds to execute ------
-e 与 -f 参数互斥
❯ easy_encryption_tool aes -m cbc -a encrypt -i test_plain -f -e
------ 75998f7a4a1364f6 begin@2024-04-04_15:40:30.038 ------
the input data cannot be used as both a file and base64 encoded data
------ 75998f7a4a1364f6 took 0.026 milli-seconds to execute ------
对文件加密或解密时,必须指定输出的文件名
# 加密不指定输出文件
❯ easy_encryption_tool aes -m gcm -a encrypt -i ./test_data/test_plain.txt -f
------ 3564874090cf12d5 begin@2024-04-04_15:40:55.522 ------
need a output file specified and writable
------ 3564874090cf12d5 took 0.074 milli-seconds to execute ------
# 解密不指定输出文件
❯ easy_encryption_tool aes -m gcm -a decrypt -i ./test_data/test_plain.txt -f -t df8z3ccRyGOQTluw26dIlA==
------ c3dee26a5649a077 begin@2024-04-04_15:41:07.541 ------
need a output file specified and writable
------ c3dee26a5649a077 took 0.084 milli-seconds to execute ------
HMAC验证码
支持的命令参数
❯ easy_encryption_tool hmac --help
Usage: eet hmac [OPTIONS]
╭─ Options ────────────────────────────────────────────────────────────────────╮
│ * --input-data -i TEXT Input data: text, │
│ base64, or file path │
│ [required] │
│ --is-base64-encoded -e Interpret -i as base64 │
│ data (mutually │
│ exclusive with -f) │
│ --is-a-file -f Interpret -i as file │
│ path (mutually │
│ exclusive with -e) │
│ --hash-alg -a [sha224|sha256|sha384|s HMAC digest algorithm │
│ ha512|sha3_224|sha3_256 [default: sha256] │
│ |sha3_384|sha3_512|sm3] │
│ --key -k TEXT Key string. A missing │
│ key is randomly │
│ generated (length │
│ matches the hash digest │
│ size, base64 in │
│ output); the CipherHUB │
│ web preset key applies │
│ only when passed │
│ explicitly │
│ --random-key -r Auto-generate random │
│ key (length matches │
│ digest size). Default │
│ when -k/--key-b64 not │
│ given. Mutually │
│ exclusive with │
│ -k/--key-b64. │
│ --key-b64 TEXT Base64 key bytes (use │
│ for HMAC verify with │
│ key from random-key │
│ output). Mutually │
│ exclusive with -k │
│ --input-limit -l INTEGER Max non-file input size │
│ in MB [default: 1] │
│ --pretty-json Output colored pretty │
│ JSON (default) │
│ --json Output single-line JSON │
│ (use with jq for field │
│ extraction) │
│ --help Show this message and │
│ exit. │
╰──────────────────────────────────────────────────────────────────────────────╯
关于输入数据和密钥的预设
- 输入数据支持三种方式:字符串明文、base64 编码的字节流(
-e)、文件路径(-f) - 密钥没有默认值:不给
-k时自动生成随机密钥(长度对齐所选哈希算法的摘要长度),以 base64 回显在输出的result.key,供验证方复用;显式指定-k时输出不回显密钥 - 要与 CipherHUB 网页工具的默认密钥对齐,需显式传入网页端默认密钥
01234567890123456789012345678901(CLI 不会在不给-k时使用它) - SM3 需 GmSSL 原生库,且密钥长度限制为 16-64 字节
指定密钥
不指定密钥(自动随机)
❯ easy_encryption_tool hmac -i hello,world
{
"metadata": {
"operation": "hmac",
"algorithm": "sha256",
"input": {
"type": "text",
"size": 11
},
"parameters": {
"digest_size": 32,
"key_size": 32
}
},
"result": {
"hmac": "493412f4bd78348692e9ab210427cb1c7b92b3e0125b268a67d05ed15570e9b3",
"key": "UKAqp1XGjkPO+h/qAoogcxxSVHrkb/UOyVOhD8j8Dqk=",
"formats": {
"hmac": "hex",
"key": "base64"
}
},
"runtime": {
"request_id": "86c4917d-53bf-48ff-8f57-ea21c4d8e43f",
"timestamp": "2026-09-01T20:43:29.963649+08:00",
"duration_ms": 0.027,
"host": "MacM2Max-2.local",
"version": "v3.0.1"
}
}
result.key 是本次随机生成的密钥(base64),验证同一份数据时用 --key-b64 传入即可复现。
显式指定密钥
❯ easy_encryption_tool hmac -i hello,world -k 01234567890123456789012345678901
{
"metadata": {
"operation": "hmac",
"algorithm": "sha256",
"input": {
"type": "text",
"size": 11
},
"parameters": {
"digest_size": 32,
"key_size": 32
}
},
"result": {
"hmac": "a5e8ea8f0fbaf97fbc08841be49271b52b8c2ddb1c521e14b10608db68205220",
"formats": {
"hmac": "hex"
}
},
"runtime": {
"request_id": "3001aa9d-7a2c-4f91-83c1-affeea182d49",
"timestamp": "2026-09-01T20:43:30.607722+08:00",
"duration_ms": 0.032,
"host": "MacM2Max-2.local",
"version": "v3.0.1"
}
}
显式给 -k 时密钥不回显,只输出 HMAC 值。
强制随机密钥
❯ easy_encryption_tool hmac -i hello,world -r
{
"metadata": {
"operation": "hmac",
"algorithm": "sha256",
"input": {
"type": "text",
"size": 11
},
"parameters": {
"digest_size": 32,
"key_size": 32
}
},
"result": {
"hmac": "35027f23283ebc4a67b03fd05c5609deacc2cd2565ddc36ed550e39a00c04bd3",
"key": "5z+2SDM6PstT65SY1I/pCJit3ht3sDwCVDzwgBpMhi8=",
"formats": {
"hmac": "hex",
"key": "base64"
}
},
"runtime": {
"request_id": "3e0723c0-d67d-445b-9324-7eadbc98c392",
"timestamp": "2026-09-01T20:43:30.281768+08:00",
"duration_ms": 0.029,
"host": "MacM2Max-2.local",
"version": "v3.0.1"
}
}
-r 与 -k/--key-b64 互斥;不给任何密钥选项时默认走随机(同上文第一种)。
指定输入
输入字符串
❯ easy_encryption_tool hmac -i hello,world
{
"metadata": {
"operation": "hmac",
"algorithm": "sha256",
"input": {
"type": "text",
"size": 11
},
"parameters": {
"digest_size": 32,
"key_size": 32
}
},
"result": {
"hmac": "ebeb118a5fc3115c9485573f92ef7e42a33834164ea957d874989db9bd53fce5",
"key": "SfLNkGNbfxngQdeA0UJE5W7zZB6cij1EerRo8quhWpc=",
"formats": {
"hmac": "hex",
"key": "base64"
}
},
"runtime": {
"request_id": "97703ae4-b1c6-4504-9065-8b485e1d0223",
"timestamp": "2026-09-01T20:45:50.508979+08:00",
"duration_ms": 0.029,
"host": "MacM2Max-2.local",
"version": "v3.0.1"
}
}
输入 base64 编码的字节流
❯ easy_encryption_tool hmac -i aGVsbG8sd29ybGQ= -e
{
"metadata": {
"operation": "hmac",
"algorithm": "sha256",
"input": {
"type": "binary",
"size": 11
},
"parameters": {
"digest_size": 32,
"key_size": 32
}
},
"result": {
"hmac": "1ff87ae95b2da86edade3f51fdb3f5eb777eaa84e3edbee6acf07861f2efdd5c",
"key": "2fbc0j3mslVyQHNzNk/fk+K+iB9L/4Y0tiaAnnQFQoc=",
"formats": {
"hmac": "hex",
"key": "base64"
}
},
"runtime": {
"request_id": "2946dc66-3945-4a6b-9e22-e5f704878c4a",
"timestamp": "2026-09-01T20:43:31.590283+08:00",
"duration_ms": 0.03,
"host": "MacM2Max-2.local",
"version": "v3.0.1"
}
}
输入文件
❯ easy_encryption_tool hmac -i /tmp/eet_doc_plain.txt -f
{
"metadata": {
"operation": "hmac",
"algorithm": "sha256",
"input": {
"type": "file",
"size": 47
},
"parameters": {
"digest_size": 32,
"key_size": 32
}
},
"result": {
"hmac": "93eb116fa254e9729d1901cacc852ff926f53a51a059df7aa901492ebd4f3050",
"key": "4iJ7Wlv/A/SrDP/vypJPicbA4jMljZFatjJxzSCUdco=",
"formats": {
"hmac": "hex",
"key": "base64"
}
},
"runtime": {
"request_id": "e17cfec1-6d9e-46cd-8db5-513a9efbebf9",
"timestamp": "2026-09-01T20:45:11.403918+08:00",
"duration_ms": 0.249,
"host": "MacM2Max-2.local",
"version": "v3.0.1"
}
}
指定哈希算法
# 支持的哈希列表:
# [sha224 | sha256 | sha384 | sha512 | sha3_224 | sha3_256 | sha3_384 | sha3_512 | sm3]
# 使用 sha512
❯ easy_encryption_tool hmac -i /tmp/eet_doc_plain.txt -f -a sha512
{
"metadata": {
"operation": "hmac",
"algorithm": "sha512",
"input": {
"type": "file",
"size": 47
},
"parameters": {
"digest_size": 64,
"key_size": 64
}
},
"result": {
"hmac": "8909cf54de94efc9961b967604bbad4bf28a5943fe41931724a5c378065c829490dcdf3a516a82ed1a075aec9ed8a9a4dcbe3e682a6fbd7c7a911c4c0d967f1f",
"key": "zFJXjCegRtUvA9PfQ7clS6nwuVwvlCgCjtUpcuBPM6cM/xOudgOGbTg+R44bctQGSTmX61tzosY3pNNmswe3qQ==",
"formats": {
"hmac": "hex",
"key": "base64"
}
},
"runtime": {
"request_id": "fabcf24e-43dd-4397-8d6d-93f168291063",
"timestamp": "2026-09-01T20:43:30.938513+08:00",
"duration_ms": 0.107,
"host": "MacM2Max-2.local",
"version": "v3.0.1"
}
}
# 使用 sha3_256
❯ easy_encryption_tool hmac -i /tmp/eet_doc_plain.txt -f -a sha3_256
{
"metadata": {
"operation": "hmac",
"algorithm": "sha3_256",
"input": {
"type": "file",
"size": 47
},
"parameters": {
"digest_size": 32,
"key_size": 32
}
},
"result": {
"hmac": "76478f7367d32b2db8d7d2a0dcf04c01c609a3f85257808071c95f85017ce883",
"key": "9Lt+8z2nqOLclPJIyUmWDmM5TXV0O9gwEYoKN3Qk1Hs=",
"formats": {
"hmac": "hex",
"key": "base64"
}
},
"runtime": {
"request_id": "25cbedf7-7dc3-429f-9a3c-48a4d860425b",
"timestamp": "2026-09-01T20:43:31.259750+08:00",
"duration_ms": 0.102,
"host": "MacM2Max-2.local",
"version": "v3.0.1"
}
}
RSA非对称密钥
支持的命令
❯ easy_encryption_tool rsa --help
Usage: main.py rsa [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
decrypt
encrypt
generate
sign
verify
生成密钥对
支持的参数
❯ easy_encryption_tool rsa generate --help
Usage: main.py rsa generate [OPTIONS]
Options:
-s, --size [2048|3072|4096] 密钥位数 [default: 2048]
-e, --encoding [pem|der] 密钥格式 [default: pem]
-f, --file-name TEXT 输出密钥对的文件名前缀,最终写入数据时会创建文件并加上文件名后缀 [default:
demo; required]
-p, --password TEXT 私钥密码,使用私钥时需要输入正确的密码
-r, --random-password 是否生成私钥的随机密码,如果带上 -r 标识,则随机生成32字节的密码
--help Show this message and exit.
默认生成
# 密钥长度2048位,私钥不带密码
❯ easy_encryption_tool rsa generate -f test
------ 6b89fd023be2d70e begin@2024-04-04_15:48:44.313 ------
generate test_rsa_public.pem/test_rsa_private.pem success
------ 6b89fd023be2d70e took 134.487 milli-seconds to execute ------
指定长度且指定密码
# pem格式密钥,私钥不带密码
❯ easy_encryption_tool rsa generate -f test_no_pwd_pem -s 4096 -e pem
------ 7d68ecefd4536a1c begin@2024-04-04_15:50:00.393 ------
generate test_no_pwd_pem_rsa_public.pem/test_no_pwd_pem_rsa_private.pem success
------ 7d68ecefd4536a1c took 560.056 milli-seconds to execute ------
# pem格式密钥,私钥带密码
❯ easy_encryption_tool rsa generate -f test_pwd_pem -s 4096 -e pem -p 1234567890
------ f036eed08d4188e6 begin@2024-04-04_15:51:20.417 ------
private key password:1234567890
generate test_pwd_pem_rsa_public.pem/test_pwd_pem_rsa_private_cipher.pem success
------ f036eed08d4188e6 took 341.474 milli-seconds to execute ------
# der格式密钥,私钥不带密码
❯ easy_encryption_tool rsa generate -f test_no_pwd_der -s 4096 -e der
------ e152e62cc8ff4080 begin@2024-04-04_15:51:53.004 ------
generate test_no_pwd_der_rsa_public.der/test_no_pwd_der_rsa_private.der success
------ e152e62cc8ff4080 took 620.032 milli-seconds to execute ------
# der格式密钥,私钥带密码
❯ easy_encryption_tool rsa generate -f test_pwd_der -s 4096 -e der -p 1234567890
------ 9b08b9054b7642cd begin@2024-04-04_15:52:04.209 ------
private key password:1234567890
generate test_pwd_der_rsa_public.der/test_pwd_der_rsa_private_cipher.der success
------ 9b08b9054b7642cd took 1108.390 milli-seconds to execute ------
指定长度且随机生成密码
❯ easy_encryption_tool rsa generate -f test -s 4096 -r
------ e3eba04fda53c701 begin@2024-04-04_15:53:14.570 ------
private key password:4)H(iipM9=qnUV!!16LZ3)n&YGQE@v04
generate test_rsa_public.pem/test_rsa_private_cipher.pem success
------ e3eba04fda53c701 took 300.131 milli-seconds to execute ------
加密与解密
支持的参数
# 加密
❯ easy_encryption_tool rsa encrypt --help
Usage: main.py rsa encrypt [OPTIONS]
Options:
-f, --public-key TEXT 公钥文件路径 [required]
-i, --input-data TEXT 输入数据,可以直接为字符串,也可以为
base64编码的数据,base64编码的数据需要带上标识 -c [required]
-e, --encoding [pem|der] 密钥格式 [default: pem]
-c, --b64-encoded 输入数据是否被 base64 编码过
-l, --input-limit INTEGER 输入内容最大长度,单位为 MB,默认为 1MB,非对称不适合直接加密过长的数据
[default: 1]
-m, --mode [oaep|pkcs1v15] 加密时的填充模式 [default: oaep; required]
-h, --hash-mode [sha256|sha384|sha512]
此参数仅在-m为 oaep 时生效 [default: sha256]
--help Show this message and exit.
# 解密
❯ easy_encryption_tool rsa decrypt --help
Usage: main.py rsa decrypt [OPTIONS]
Options:
-f, --private-key TEXT 私钥文件路径 [required]
-i, --input-data TEXT 输入的密文数据, 必须为base64编码的数据 [required]
-e, --encoding [pem|der] 密钥格式 [default: pem]
-m, --mode [oaep|pkcs1v15] 加密时的填充模式 [default: oaep; required]
-h, --hash-mode [sha256|sha384|sha512]
此参数仅在-m为 oaep 时生效 [default: sha256]
-p, --password TEXT 私钥密码,使用私钥时需要输入正确的密码
--help Show this message and exit.
使用 PEM 密钥加解密
私钥不需要密码
# 加密
❯ easy_encryption_tool rsa encrypt -e pem -f ./test_data/test_no_pwd_pem_public.pem -i hello,world
------ 18869a5ba5f11a4f begin@2024-04-04_15:55:10.501 ------
pub key size:4096
padding mode:oaep-sha256
cipher:pQlqgAyKEdrjcdRPe90uWHIJv781VD1X0+wrVyzmf6GE1hMdEwcukflGsgkysN3jbR2btNAEfYwxmvk+b1Om/AUdtGrZNAMuCygY3Y2U6ikVRcOCdd0ZCz3Gp7NTEblifVxMR/UsK2VQ+/4Tysmslv2QFOV7Mz+uE6j/o+hTBYhR42r+tkKsAEQGB8LLfo5GC+Wjk5mU1Yt3d8bz3/55S7Wv3DhAlrD9AuiEhqv4E8JL0MgSIN26rzHnOOlkP5vRlH5lLITzier7W9inoQxpYpKdk3xa7gsRXKXVBNcaNdCn9AH/SkrfEe+bHpZcAWG7It2OyTlaAzSwmia+wYx3CgyVtzMHNU9jQrz8xnMcP1ZntxVNvoVnhn9li0H8XTCAy3p+YfYGybEqiSNeFL7cEsONO8x8y0bkqNQE9KFTba0yZNsME1JfJmQVG9IrLaIn1RAsGmPeVYCuHmwcZQCxFUc14von867Z4HewLNqnN5EzalTnVzIY4whZcwMnmp53tZKeNhh0QemuoEqWmkf4cwJHGR/KZJKi+dhB5vo0+LffXf4LzsJRAwbE9ylwEPEsjFx1BYw7jbVIb7hgZ0AZB0J2OMdov25xMWk2nYBmR6L/QFBCtw/J8t7198ZuHmHI247gl8zJ3tFEAPFw1eFOQOkIAKnSDVfnPBlTZQ8smtM=
------ 18869a5ba5f11a4f took 15.731 milli-seconds to execute ------
# 解密
❯ easy_encryption_tool rsa decrypt -e pem -f ./test_data/test_no_pwd_pem_private.pem -i pQlqgAyKEdrjcdRPe90uWHIJv781VD1X0+wrVyzmf6GE1hMdEwcukflGsgkysN3jbR2btNAEfYwxmvk+b1Om/AUdtGrZNAMuCygY3Y2U6ikVRcOCdd0ZCz3Gp7NTEblifVxMR/UsK2VQ+/4Tysmslv2QFOV7Mz+uE6j/o+hTBYhR42r+tkKsAEQGB8LLfo5GC+Wjk5mU1Yt3d8bz3/55S7Wv3DhAlrD9AuiEhqv4E8JL0MgSIN26rzHnOOlkP5vRlH5lLITzier7W9inoQxpYpKdk3xa7gsRXKXVBNcaNdCn9AH/SkrfEe+bHpZcAWG7It2OyTlaAzSwmia+wYx3CgyVtzMHNU9jQrz8xnMcP1ZntxVNvoVnhn9li0H8XTCAy3p+YfYGybEqiSNeFL7cEsONO8x8y0bkqNQE9KFTba0yZNsME1JfJmQVG9IrLaIn1RAsGmPeVYCuHmwcZQCxFUc14von867Z4HewLNqnN5EzalTnVzIY4whZcwMnmp53tZKeNhh0QemuoEqWmkf4cwJHGR/KZJKi+dhB5vo0+LffXf4LzsJRAwbE9ylwEPEsjFx1BYw7jbVIb7hgZ0AZB0J2OMdov25xMWk2nYBmR6L/QFBCtw/J8t7198ZuHmHI247gl8zJ3tFEAPFw1eFOQOkIAKnSDVfnPBlTZQ8smtM=
------ 197c89cd0b631ce0 begin@2024-04-04_15:55:40.536 ------
private key password:
key size:4096
padding mode:oaep-sha256
origin plain:hello,world
------ 197c89cd0b631ce0 took 338.602 milli-seconds to execute ------
私钥需要密码
# 加密
❯ easy_encryption_tool rsa encrypt -e pem -f ./test_data/test_pwd_pem_public.pem -i hello,world
------ e1cde686b573fb50 begin@2024-04-04_15:56:04.554 ------
pub key size:4096
padding mode:oaep-sha256
cipher:pF06oJgMvzJ8WUphoYqaccLhClQjeSiSQXbQpORXtzkAFKeSqAQwGCKLQlDeJft6bc4wxUe1hS5IM/21hOpx1HZKZyXurfeqHkOXx4ekiakqS+8MgW6x4vozQfTKUZHoDStA8chwibtWlDCAGESYj1drr1UA8cNc5I+ij+hM3voFA3zh8o6JaKLKmxvNedRk5ugJQE6lL3RHMAya5oQS5AYQTtfuLQl52G0loQIPoWWB8KgZD6iZ///I2MI8B4kEHS1O2eg897DNyHGRdf8nRjTJdecWFR7wXY0VQeV8lR2BEsPb7L15qg4lZvonpew9qII6gW5J39yLK73vbAAkpdAmpOGxvOVtztE0Tn4UFkIkOZDkH8nlj1JwhCJ5K9R+TwlkoUinFMasOUZFEvNHzbha69mVErxBQHwv6N6P4kTLOBFVDrqF1Y00ZAQ0ZjIr/s7OdJAyoHlzZkroSfkbvV2eOho3nJD8aoIYdfa1kwttJ7p027VSVMflO1jULRZ0EkT2ncgzOMjqm4fB8Se42/QGjGtKYKOOPp4uBbFuxi8ra4LWY0l0h+FYJ6wXeIcODMLuxHWK4drfJrj5IpaTYNuysmeDEDfMQZQV1WYmyfFsJtIqXFiKrQatgFtGsfYXPCNBTrXa4HVW/Ohm7vE1PKGh+e2K7VpSZ6F4nW+YmQc=
------ e1cde686b573fb50 took 15.492 milli-seconds to execute ------
# 解密 -p 指定密码
❯ easy_encryption_tool rsa decrypt -e pem -f ./test_data/test_pwd_pem_private_cipher.pem -i pF06oJgMvzJ8WUphoYqaccLhClQjeSiSQXbQpORXtzkAFKeSqAQwGCKLQlDeJft6bc4wxUe1hS5IM/21hOpx1HZKZyXurfeqHkOXx4ekiakqS+8MgW6x4vozQfTKUZHoDStA8chwibtWlDCAGESYj1drr1UA8cNc5I+ij+hM3voFA3zh8o6JaKLKmxvNedRk5ugJQE6lL3RHMAya5oQS5AYQTtfuLQl52G0loQIPoWWB8KgZD6iZ///I2MI8B4kEHS1O2eg897DNyHGRdf8nRjTJdecWFR7wXY0VQeV8lR2BEsPb7L15qg4lZvonpew9qII6gW5J39yLK73vbAAkpdAmpOGxvOVtztE0Tn4UFkIkOZDkH8nlj1JwhCJ5K9R+TwlkoUinFMasOUZFEvNHzbha69mVErxBQHwv6N6P4kTLOBFVDrqF1Y00ZAQ0ZjIr/s7OdJAyoHlzZkroSfkbvV2eOho3nJD8aoIYdfa1kwttJ7p027VSVMflO1jULRZ0EkT2ncgzOMjqm4fB8Se42/QGjGtKYKOOPp4uBbFuxi8ra4LWY0l0h+FYJ6wXeIcODMLuxHWK4drfJrj5IpaTYNuysmeDEDfMQZQV1WYmyfFsJtIqXFiKrQatgFtGsfYXPCNBTrXa4HVW/Ohm7vE1PKGh+e2K7VpSZ6F4nW+YmQc= -p 1234567890
------ cb0ebbe7b572b665 begin@2024-04-04_15:56:25.496 ------
private key password:1234567890
key size:4096
padding mode:oaep-sha256
origin plain:hello,world
------ cb0ebbe7b572b665 took 338.788 milli-seconds to execute ------
使用 DER 密钥加解密
私钥不需要密码
# 加密
❯ easy_encryption_tool rsa encrypt -e der -f ./test_data/test_no_pwd_der_public.der -i hello,world
------ 10e4568e22050ecc begin@2024-04-04_15:56:47.705 ------
pub key size:4096
padding mode:oaep-sha256
cipher:V0g9TwUetAKZOl6xwe9SL7ra1P3K2JGwTZ2NMKdZiP4zNaPxxjPPv8Me3g9qMWLNBcfU6dd+7Ia7xGb0c5Ou1/uf7D3xSoV6hU0PV/0i8feJYATgkWFO1NOt1TpIHlcYHtA9NdHEaNXR9qbY8pHyAokVRf83hyQIZMTPgpGo2GH0lJkFAOjxWOiGyPKF7GgdHjz+8rfu4R9VBUg0Wy0O1zyvTKA+b4iE6MS4zJBbzPe0H43w9OLp+TQFykrhLWXsFX+AEhdhxa7N0ebaorlQNtPnY8KuXFx0cqIzWigBcfWNTYgcjbFGLm+mo0Btin0UqDFhbC8EwdpVGnVr6ZBLCvEmyqDAuJN5UCEBQ7Jrakgot/qZ4QHPL5HdU+tNXb8KULH75fyu0A11zzHjpw2E2KRKmg1Fg9aExaim4r15T2VU1eYjZKaPV/YiYMPlqZM9udUQFTmrLRIhCUUp+fc+MJu3zR6chz6d0eSx/RdV8ik8ilKILZl7dAfRS3hC5QG0pPh54Z+MqgAZbHfTxCbjnxqoPJzMOcC+JOPEpjC2PhS6MYE70+Ub8RS1cGZmZ2z32UnanqfT9kLbR626CWUzPzZWsnMheoX5bAABDfp7AkC9BXv+ca3REAyvR8HchVkVMiIRC4dTlY4p4+uFVtOnkhUG5mzSOVGebAWOJ+ftTFY=
------ 10e4568e22050ecc took 14.792 milli-seconds to execute ------
# 解密
❯ easy_encryption_tool rsa decrypt -e der -f ./test_data/test_no_pwd_der_private.der -i V0g9TwUetAKZOl6xwe9SL7ra1P3K2JGwTZ2NMKdZiP4zNaPxxjPPv8Me3g9qMWLNBcfU6dd+7Ia7xGb0c5Ou1/uf7D3xSoV6hU0PV/0i8feJYATgkWFO1NOt1TpIHlcYHtA9NdHEaNXR9qbY8pHyAokVRf83hyQIZMTPgpGo2GH0lJkFAOjxWOiGyPKF7GgdHjz+8rfu4R9VBUg0Wy0O1zyvTKA+b4iE6MS4zJBbzPe0H43w9OLp+TQFykrhLWXsFX+AEhdhxa7N0ebaorlQNtPnY8KuXFx0cqIzWigBcfWNTYgcjbFGLm+mo0Btin0UqDFhbC8EwdpVGnVr6ZBLCvEmyqDAuJN5UCEBQ7Jrakgot/qZ4QHPL5HdU+tNXb8KULH75fyu0A11zzHjpw2E2KRKmg1Fg9aExaim4r15T2VU1eYjZKaPV/YiYMPlqZM9udUQFTmrLRIhCUUp+fc+MJu3zR6chz6d0eSx/RdV8ik8ilKILZl7dAfRS3hC5QG0pPh54Z+MqgAZbHfTxCbjnxqoPJzMOcC+JOPEpjC2PhS6MYE70+Ub8RS1cGZmZ2z32UnanqfT9kLbR626CWUzPzZWsnMheoX5bAABDfp7AkC9BXv+ca3REAyvR8HchVkVMiIRC4dTlY4p4+uFVtOnkhUG5mzSOVGebAWOJ+ftTFY=
------ ff1efcc52f4fc05e begin@2024-04-04_15:57:10.634 ------
private key password:
key size:4096
padding mode:oaep-sha256
origin plain:hello,world
------ ff1efcc52f4fc05e took 348.368 milli-seconds to execute ------
私钥需要密码
# 加密
❯ easy_encryption_tool rsa encrypt -e der -f ./test_data/test_pwd_der_public.der -i hello,world
------ d59dc4bec2be5592 begin@2024-04-04_15:57:28.114 ------
pub key size:4096
padding mode:oaep-sha256
cipher:XNNpZfpu7ZjnI1HnH/KN9BdO+/rxrtt0K4z/KRQjsAZEYZV4uMtT0o45ZHrDfr6mHNrrIlTRrt6wghIeQUojEo0uQA7auwhqJXXl3ghwTqGhKH4Lkf6q+d0X/Pn1MgRoNb3dIvWsZcpTlnqmffphOe2DzWP4By9a3yZe9rb8S/ddml7/+4BIXVqxwWcAMsAg3lpLnNHBQ853XYeDZXxKjvx4J8f2RUbp7c/xsH6eUjxZfDehcoZL7te6OrY2N342UzYKBqTQV4zbqVTm0c6V1Q7XkjFK3esgcxicitIP2UsdQjpQf9xMtOTQzErdSQk/Pd6tLxLNyKQcxDaqXR9TXA84koIfGETx434im+zhOgsUuSwS6zBARI3AlpQi14LVAbr3/6ABIEJG5QvVVVG32aVzOMrPtViRqZzcDgkyIsBOXLAQv7c5UkP+nePtnjs31IXmcO87p5zW6rweW/6Y5z1emI6RIHgLjqGKFKkaWXua0N+ZqHTEuqks2y27mFFT/g2DJN3zp5corIcjgSEqyuQbQg/hFaurrqzu+djQ1Pevjzy8rUOM7k97UYUHwjv0ITeIB/m2Rknbwsu3WH3jW6TV8Ta+Bw05ZKYT6hoFPttfno+iDVRmzRlY2QuBxHzEALtdsANzxKnpUr/vr5mEmU8Wmi87QSjp1ULMJ5lTU64=
------ d59dc4bec2be5592 took 14.696 milli-seconds to execute ------
# 解密 -p 指定密码
❯ easy_encryption_tool rsa decrypt -e der -f ./test_data/test_pwd_der_private_cipher.der -i XNNpZfpu7ZjnI1HnH/KN9BdO+/rxrtt0K4z/KRQjsAZEYZV4uMtT0o45ZHrDfr6mHNrrIlTRrt6wghIeQUojEo0uQA7auwhqJXXl3ghwTqGhKH4Lkf6q+d0X/Pn1MgRoNb3dIvWsZcpTlnqmffphOe2DzWP4By9a3yZe9rb8S/ddml7/+4BIXVqxwWcAMsAg3lpLnNHBQ853XYeDZXxKjvx4J8f2RUbp7c/xsH6eUjxZfDehcoZL7te6OrY2N342UzYKBqTQV4zbqVTm0c6V1Q7XkjFK3esgcxicitIP2UsdQjpQf9xMtOTQzErdSQk/Pd6tLxLNyKQcxDaqXR9TXA84koIfGETx434im+zhOgsUuSwS6zBARI3AlpQi14LVAbr3/6ABIEJG5QvVVVG32aVzOMrPtViRqZzcDgkyIsBOXLAQv7c5UkP+nePtnjs31IXmcO87p5zW6rweW/6Y5z1emI6RIHgLjqGKFKkaWXua0N+ZqHTEuqks2y27mFFT/g2DJN3zp5corIcjgSEqyuQbQg/hFaurrqzu+djQ1Pevjzy8rUOM7k97UYUHwjv0ITeIB/m2Rknbwsu3WH3jW6TV8Ta+Bw05ZKYT6hoFPttfno+iDVRmzRlY2QuBxHzEALtdsANzxKnpUr/vr5mEmU8Wmi87QSjp1ULMJ5lTU64= -p 1234567890
------ 806b307f230908a4 begin@2024-04-04_15:57:47.873 ------
private key password:1234567890
key size:4096
padding mode:oaep-sha256
origin plain:hello,world
------ 806b307f230908a4 took 343.988 milli-seconds to execute ------
对明文为 base64 编码的字节流做加解密
# 加密
❯ easy_encryption_tool rsa encrypt -e pem -f ./test_data/test_pwd_pem_public.pem -i krJchuyaDRYHnu5tsy8UzA== -c
------ 29fa5af7e9f84f15 begin@2024-04-04_15:58:07.029 ------
pub key size:4096
padding mode:oaep-sha256
cipher:QiztiJ21bVsNf4DyPhzDAR/E24Xqe94P398JLDakFl3LDhOA3I/XHY3v3R0GBNRrrMPtUorGHxCVmJNqc06kLCtQ4ljd015rYFRgbAtNLsaNgjsdv1Q7kHQSVa7L1BHdhNDK47svEWMQTS4jKLiKVYbCnz4ARYqe3n+vf5UtVDlrpmMNjowbdfnhnEFibCICBwnGUpssFs9X546/BzCTlqgEGdy1SpFhfX2LaqXkTQwsd3YxU9ynHZ7oVe78z/xJlEDQbPGJSfGbUtoCgQAn975hzCceC+CeDK9E7N8vu6HTv9K3vMNRHTOweRWuGxJKKjzVLSXRcDjkXynJPPe6yuyJdFnsoSHWuOsyqPrjJJC+2RvrkW24RlIEMnVEqLReD8/OnZEEw4CZF9xqplS7yRN/khaYM4MxD9qcxAIYgpg2wq6QngtabU+nGtQSfjKIkXlXnbvqMcLI1pS0TtG5vUeNSzc3Ll8g9CxvMrA/T/vUjz9d60fsGpHbjZezpsQdI8Us60BMxUWgFZ6x/ME5HkMmtXYfvi0/aNKWXymgHtVxqeM9hJaQ6MX1zNZRPe4MMHu3xJgATAbVc7GldgV+d2gZm2cLzZaTTB4ARcAARSKPgbskmIQ2buNRs2/ogjvtG72jilOCmSPKZom0VPHkrLzL4csxgxSd2M5N4cu6+Po=
------ 29fa5af7e9f84f15 took 15.584 milli-seconds to execute ------
# 解密 -p 指定密码
❯ easy_encryption_tool rsa decrypt -e pem -f ./test_data/test_pwd_pem_private_cipher.pem -i QiztiJ21bVsNf4DyPhzDAR/E24Xqe94P398JLDakFl3LDhOA3I/XHY3v3R0GBNRrrMPtUorGHxCVmJNqc06kLCtQ4ljd015rYFRgbAtNLsaNgjsdv1Q7kHQSVa7L1BHdhNDK47svEWMQTS4jKLiKVYbCnz4ARYqe3n+vf5UtVDlrpmMNjowbdfnhnEFibCICBwnGUpssFs9X546/BzCTlqgEGdy1SpFhfX2LaqXkTQwsd3YxU9ynHZ7oVe78z/xJlEDQbPGJSfGbUtoCgQAn975hzCceC+CeDK9E7N8vu6HTv9K3vMNRHTOweRWuGxJKKjzVLSXRcDjkXynJPPe6yuyJdFnsoSHWuOsyqPrjJJC+2RvrkW24RlIEMnVEqLReD8/OnZEEw4CZF9xqplS7yRN/khaYM4MxD9qcxAIYgpg2wq6QngtabU+nGtQSfjKIkXlXnbvqMcLI1pS0TtG5vUeNSzc3Ll8g9CxvMrA/T/vUjz9d60fsGpHbjZezpsQdI8Us60BMxUWgFZ6x/ME5HkMmtXYfvi0/aNKWXymgHtVxqeM9hJaQ6MX1zNZRPe4MMHu3xJgATAbVc7GldgV+d2gZm2cLzZaTTB4ARcAARSKPgbskmIQ2buNRs2/ogjvtG72jilOCmSPKZom0VPHkrLzL4csxgxSd2M5N4cu6+Po= -p 1234567890
------ d1f6350d34acf14e begin@2024-04-04_15:58:25.431 ------
private key password:1234567890
key size:4096
padding mode:oaep-sha256
b64 encoded plain:krJchuyaDRYHnu5tsy8UzA==
------ d1f6350d34acf14e took 344.681 milli-seconds to execute ------
加密模式设置
OAEP模式
# 加密
❯ easy_encryption_tool rsa encrypt -e pem -f ./test_data/test_no_pwd_pem_public.pem -i hello,world -m oaep
------ 5d4c86b12cac7641 begin@2024-04-04_15:58:41.153 ------
pub key size:4096
padding mode:oaep-sha256
cipher:LmYOuAO+zP1qCjivWUH7/EM81/2pDNK5t7JmRXW1GvhElRCa0uKTvEYa/Ncsoqv+zpbxo3O6j9K3YkGbO6rbi2DasYSKCX6DGvMNd348onbEiLZEpRMCGG03PpTpoargFZJhsnUQ6MvFPEpML9Om8EbjAwMG+xukuKV2Vak/6GmO8XQfsr6C+1hzhXqBggorJPyjpGZfypQO3Cx38puIpGC+TAewXZNMcBiVU3MTFvVfPk/vqlzYU68TXHGIIsKFKQG35iOSJA3bXr/FLwor3yAGdk7VS2e1kAYnuceUW9WN4FKb+ThRGRiDepJmFPM3TN9ZEEbdDH+wIZO7MkmKD4RBUgBO0RSDMIP8x8LxKN05xKqRxcrFbx5UKfurf1vAi4Hu+AP+e3kL/2UlvmHfLwmVYMT4Quzy414T/R43cNe9eH8KCypNjV5bFqdUyxJ4u7mC0f+S7PD1oTB6vhwsMOXH6tadhd7LpzpUrEyH6DLhukRIuo72IIdGnXNlB9d4yklxCPfvg9lj/irmdJKaq0MSbm1mZCp3J6R+sd0iKXakZnkPU7YLjwz92S7a1gSwfEpzBfsQZcuqs2BSN/iOEWMEB1XVGZrsbv5Tpp8APo/scGLBHmyk7Q/mDgsaNXrrGiQw0NfU4ZPzaFlvL2AC6HVE0YK4Nm4CIAXy+m2hItM=
------ 5d4c86b12cac7641 took 14.201 milli-seconds to execute ------
# 解密
❯ easy_encryption_tool rsa decrypt -e pem -f test_data/test_no_pwd_pem_private.pem -m oaep -i LmYOuAO+zP1qCjivWUH7/EM81/2pDNK5t7JmRXW1GvhElRCa0uKTvEYa/Ncsoqv+zpbxo3O6j9K3YkGbO6rbi2DasYSKCX6DGvMNd348onbEiLZEpRMCGG03PpTpoargFZJhsnUQ6MvFPEpML9Om8EbjAwMG+xukuKV2Vak/6GmO8XQfsr6C+1hzhXqBggorJPyjpGZfypQO3Cx38puIpGC+TAewXZNMcBiVU3MTFvVfPk/vqlzYU68TXHGIIsKFKQG35iOSJA3bXr/FLwor3yAGdk7VS2e1kAYnuceUW9WN4FKb+ThRGRiDepJmFPM3TN9ZEEbdDH+wIZO7MkmKD4RBUgBO0RSDMIP8x8LxKN05xKqRxcrFbx5UKfurf1vAi4Hu+AP+e3kL/2UlvmHfLwmVYMT4Quzy414T/R43cNe9eH8KCypNjV5bFqdUyxJ4u7mC0f+S7PD1oTB6vhwsMOXH6tadhd7LpzpUrEyH6DLhukRIuo72IIdGnXNlB9d4yklxCPfvg9lj/irmdJKaq0MSbm1mZCp3J6R+sd0iKXakZnkPU7YLjwz92S7a1gSwfEpzBfsQZcuqs2BSN/iOEWMEB1XVGZrsbv5Tpp8APo/scGLBHmyk7Q/mDgsaNXrrGiQw0NfU4ZPzaFlvL2AC6HVE0YK4Nm4CIAXy+m2hItM=
------ 9f151c4c9f56af86 begin@2024-04-04_15:59:05.700 ------
private key password:
key size:4096
padding mode:oaep-sha256
origin plain:hello,world
------ 9f151c4c9f56af86 took 346.121 milli-seconds to execute ------
PKCS1v15 模式
# 加密
❯ easy_encryption_tool rsa encrypt -e pem -f ./test_data/test_no_pwd_pem_public.pem -i hello,world -m pkcs1v15
------ 875086be5059242c begin@2024-04-04_15:59:19.282 ------
pub key size:4096
padding mode:pkcs1v15
cipher:i1hVnoQsWAQK4sftuvg08Fq1dzm3o5BRNb78K6gBGVwsu1a/gSFGwIqSOa22ONlZ0cnPu7v/mZAVOi8/tXa1++JrmpnyoZTQ3vATkXK8WG6Q6Dw/dLKUFvsRv04hxMI2ttSMNqFsiRRnCy1qx2m4PFPPuZFniuT4i9hutGn4br+d5e1DtyLxsSmefKk4BJn0Rzgzv3ImeBmT0znTJ5VN2SI/WRHlvc6KmtnQ1xD2/2kkMycPzLguL+XXc+ie/sNg3Y0CelQcXOxonAnkQcXKpzQL7+pONVDHIJvRRXjv0nUWhTay+KWPApfB+BZ0MkI03oW0divZXohI5pWa7n4Gvw1qN+Kvt3BAmBK64LvlKFzZF553re5fMKodhrK/yhIsCtWYjsrgEz+5UAmavwH6dgTrIpssfSQDaUlWwVQRG/pG+jbxkKZ1Y7SX1SAznS4Jb3xKFeWN7ulPLJIe3Zro4VxihW0KgChDFrnVtpZLuXq98mVR+v/L2HaCzNRCY39soYZZywt3IhP2ZDVoCGpVQWQ8y69pbCKfCfiOheRf1j7VYtIOATT2kNGJrVnBwZvXBfQ2Mp3y9UPIud+WAkS2s6bha1QBF/YX72xtZoiICLZZmrmXN3DdGWy1y8SM3mI75s2GsqjF6JeN2iNoLtDy2tpREH78MujjnSjMSCP78wY=
------ 875086be5059242c took 14.024 milli-seconds to execute ------
# 解密
❯ easy_encryption_tool rsa decrypt -e pem -f test_data/test_no_pwd_pem_private.pem -m pkcs1v15 -i i1hVnoQsWAQK4sftuvg08Fq1dzm3o5BRNb78K6gBGVwsu1a/gSFGwIqSOa22ONlZ0cnPu7v/mZAVOi8/tXa1++JrmpnyoZTQ3vATkXK8WG6Q6Dw/dLKUFvsRv04hxMI2ttSMNqFsiRRnCy1qx2m4PFPPuZFniuT4i9hutGn4br+d5e1DtyLxsSmefKk4BJn0Rzgzv3ImeBmT0znTJ5VN2SI/WRHlvc6KmtnQ1xD2/2kkMycPzLguL+XXc+ie/sNg3Y0CelQcXOxonAnkQcXKpzQL7+pONVDHIJvRRXjv0nUWhTay+KWPApfB+BZ0MkI03oW0divZXohI5pWa7n4Gvw1qN+Kvt3BAmBK64LvlKFzZF553re5fMKodhrK/yhIsCtWYjsrgEz+5UAmavwH6dgTrIpssfSQDaUlWwVQRG/pG+jbxkKZ1Y7SX1SAznS4Jb3xKFeWN7ulPLJIe3Zro4VxihW0KgChDFrnVtpZLuXq98mVR+v/L2HaCzNRCY39soYZZywt3IhP2ZDVoCGpVQWQ8y69pbCKfCfiOheRf1j7VYtIOATT2kNGJrVnBwZvXBfQ2Mp3y9UPIud+WAkS2s6bha1QBF/YX72xtZoiICLZZmrmXN3DdGWy1y8SM3mI75s2GsqjF6JeN2iNoLtDy2tpREH78MujjnSjMSCP78wY=
------ d5096f43a1dd5d65 begin@2024-04-04_15:59:37.216 ------
private key password:
key size:4096
padding mode:pkcs1v15
origin plain:hello,world
------ d5096f43a1dd5d65 took 348.221 milli-seconds to execute ------
签名与验签
支持的参数
# 签名
❯ easy_encryption_tool rsa sign --help
Usage: main.py rsa sign [OPTIONS]
Options:
-f, --private-key TEXT 私钥文件路径 [required]
-e, --encoding [pem|der] 密钥格式 [default: pem]
-m, --mode [pss|pkcs1v15] 签名时的填充模式 [default: pss; required]
-h, --hash-mode [sha256|sha384|sha512]
签名时的哈希算法 [default: sha256]
-p, --password TEXT 私钥密码,使用私钥时需要输入正确的密码
-i, --input-data TEXT 需要被签名的数据 [required]
-c, --b64-encoded 输入数据是否被 base64 编码过
--help Show this message and exit.
# 验签
❯ easy_encryption_tool rsa verify --help
Usage: main.py rsa verify [OPTIONS]
Options:
-f, --public-key TEXT 公钥文件路径 [required]
-e, --encoding [pem|der] 密钥格式 [default: pem]
-m, --mode [pss|pkcs1v15] 签名时的填充模式 [default: pss; required]
-h, --hash-mode [sha256|sha384|sha512]
签名时的哈希算法 [default: sha256]
-i, --input-data TEXT 需要被签名的数据 [required]
-c, --b64-encoded 输入数据是否被 base64 编码过
-s, --signature TEXT base64 编码过的签名值
--help Show this message and exit.
PSS模式
# 签名 -p 指定密码
❯ easy_encryption_tool rsa sign -e der -f ./test_data/test_pwd_der_private_cipher.der -m pss -i hello,world -p 1234567890
------ 9238d47e0e2636f1 begin@2024-04-04_16:01:35.674 ------
key size:4096
signature:74bd0807319b4b7c58dc40eaf58efee853eb5d506079ebe8aa3e76350d42ea88c4560c4e732911cca4cd101da6b5b712fae4005bd207d88fcc87761c5c0942f932b9f5773814b91c68c91b23fd623681a069fd29d86c1c89b080b35cf1f45024bf92fdfade2b9536603f5ae40ee0d1350eae686ba1b02954efd8f2b43226228247ce8d5d9c1bbebb97aa77eb52c5a62fbf8bd46e531abf3683487ce5f18cb48f2f175398861f579ea3f38281fc74c7d26942a890fbf3f7c089c553fb632058e7d553c9fc3f4126433cd126067df935008227eaa96b4b7fcb01621d1d553d58070b656aaf2e6d28eb062e5643c639261d908bfd57542ed06e18bfd1419f300582d571c8f461422f684ffd9a68584fd164667f94e9775024cfe635a207297c8a3f1e078652c45c92c7d5ac2a10b6541b2aaaa30e926496caae06effe280bc275ea6b34cf83f3f2ce141acfbce1e03d11071cd9e177be28855fe108ef25ae0ba42db67e9992e3fa0072f92dd8843c666707685f49a10fba0f5719b752025893b272f8171951e007f1527b0320c62e1e9d6814e8de43084e51f917d52047a856576e6cc608576f4d99f4a8e9b237be7c576cf30cb8f97b69e85be2a6e5911f1105555778d122351691d434d40e3742278c54e71c8eac4bbb59918e3ffd3c162d25f0d1dff36e17c3ced4af449f5d06195f9a3328f1c24bd7b52aa49d8727e1894ad2
----------------
base64 encoded:dL0IBzGbS3xY3EDq9Y7+6FPrXVBgeevoqj52NQ1C6ojEVgxOcykRzKTNEB2mtbcS+uQAW9IH2I/Mh3YcXAlC+TK59Xc4FLkcaMkbI/1iNoGgaf0p2GwcibCAs1zx9FAkv5L9+t4rlTZgP1rkDuDRNQ6uaGuhsClU79jytDImIoJHzo1dnBu+u5eqd+tSxaYvv4vUblMavzaDSHzl8Yy0jy8XU5iGH1eeo/OCgfx0x9JpQqiQ+/P3wInFU/tjIFjn1VPJ/D9BJkM80SYGffk1AIIn6qlrS3/LAWIdHVU9WAcLZWqvLm0o6wYuVkPGOSYdkIv9V1Qu0G4Yv9FBnzAFgtVxyPRhQi9oT/2aaFhP0WRmf5Tpd1Akz+Y1ogcpfIo/HgeGUsRcksfVrCoQtlQbKqqjDpJklsquBu/+KAvCdeprNM+D8/LOFBrPvOHgPREHHNnhd74ohV/hCO8lrgukLbZ+mZLj+gBy+S3YhDxmZwdoX0mhD7oPVxm3UgJYk7Jy+BcZUeAH8VJ7AyDGLh6daBTo3kMITlH5F9UgR6hWV25sxghXb02Z9Kjpsje+fFds8wy4+Xtp6FvipuWRHxEFVVd40SI1FpHUNNQON0InjFTnHI6sS7tZkY4//TwWLSXw0d/zbhfDztSvRJ9dBhlfmjMo8cJL17UqpJ2HJ+GJStI=
mode:pss-sha256
------ 9238d47e0e2636f1 took 348.185 milli-seconds to execute ------
# 验签
❯ easy_encryption_tool rsa verify -e der -f ./test_data/test_pwd_der_public.der -m pss -s dL0IBzGbS3xY3EDq9Y7+6FPrXVBgeevoqj52NQ1C6ojEVgxOcykRzKTNEB2mtbcS+uQAW9IH2I/Mh3YcXAlC+TK59Xc4FLkcaMkbI/1iNoGgaf0p2GwcibCAs1zx9FAkv5L9+t4rlTZgP1rkDuDRNQ6uaGuhsClU79jytDImIoJHzo1dnBu+u5eqd+tSxaYvv4vUblMavzaDSHzl8Yy0jy8XU5iGH1eeo/OCgfx0x9JpQqiQ+/P3wInFU/tjIFjn1VPJ/D9BJkM80SYGffk1AIIn6qlrS3/LAWIdHVU9WAcLZWqvLm0o6wYuVkPGOSYdkIv9V1Qu0G4Yv9FBnzAFgtVxyPRhQi9oT/2aaFhP0WRmf5Tpd1Akz+Y1ogcpfIo/HgeGUsRcksfVrCoQtlQbKqqjDpJklsquBu/+KAvCdeprNM+D8/LOFBrPvOHgPREHHNnhd74ohV/hCO8lrgukLbZ+mZLj+gBy+S3YhDxmZwdoX0mhD7oPVxm3UgJYk7Jy+BcZUeAH8VJ7AyDGLh6daBTo3kMITlH5F9UgR6hWV25sxghXb02Z9Kjpsje+fFds8wy4+Xtp6FvipuWRHxEFVVd40SI1FpHUNNQON0InjFTnHI6sS7tZkY4//TwWLSXw0d/zbhfDztSvRJ9dBhlfmjMo8cJL17UqpJ2HJ+GJStI= -i hello,world
------ 8e8b995bbc527e67 begin@2024-04-04_16:02:01.136 ------
verify success
key size:4096
mode:pss-sha256
------ 8e8b995bbc527e67 took 14.193 milli-seconds to execute ------
PKCS1v15模式
# 签名 -p 指定密码
❯ easy_encryption_tool rsa sign -e pem -f ./test_data/test_pwd_pem_private_cipher.pem -i hello,world -p 1234567890
------ c12c59d278e72bb6 begin@2024-04-04_16:02:15.070 ------
key size:4096
signature:8590c16fd7349f7da4b845ab56c0fd786cd0f5bd4c60b8508d571f9c1da8a6f647c6b283a593ce3a8d77bf052f8eef2752058cb653faf434b7e04e4b49248d2d55815616c0e9e4e4196186bc749831616ab66a815f82bc6414d9469790aabb987cdf76b2594e586c65512042aa70f04c6c5ddf9d2038cd01971d36829e3342710e3221eb83f0299baa876df8fa43f76b6bad7ec0a28e30d77f5bdbae132f880ee2234bd5de82ae1e7c00fcb20d04f5c65e5d79a9b64f3776868139581b1ba3cf8167ca2e893330b4a49f2a5c0cd9bd5f331d270dbd3aacc6fba492ab7cce3fe78ec2f7b82d339b9ab90b89bbed8fe5f123f26709a4777dee8df500bf6d4d7178c25889c90b4d0826a47a85556958041aeb5e3609abe315d286d2804eacda85af2bbdfab943206150bd651fd0cb5106ff9b03636dcd2b5ab4d2186fe48241802ad0c8a4313d8bc29ff5c36fa0cffad5e566f3b47b3564b2739685e5ca881c3729fc300911f62b95c36eced3ebb6260997ba16b614599d809df71010a94ada31fa1db0342b632826b57599a8227ce18a44565de61e23e96b5d413702648173ada70f7c3d46599357edb4b2926f5824eef4a5960eae06c236c7cf1a8890ff67365b1aaf778423b99e641ffd56553d8196b4ed40b11ae6e804f8623fc9e3842f248394b61d1886c550d5e20c4e9d3c8b071da6f55569740f3b633cfd99167442a9f5
----------------
base64 encoded:hZDBb9c0n32kuEWrVsD9eGzQ9b1MYLhQjVcfnB2opvZHxrKDpZPOOo13vwUvju8nUgWMtlP69DS34E5LSSSNLVWBVhbA6eTkGWGGvHSYMWFqtmqBX4K8ZBTZRpeQqruYfN92sllOWGxlUSBCqnDwTGxd350gOM0Blx02gp4zQnEOMiHrg/Apm6qHbfj6Q/dra61+wKKOMNd/W9uuEy+IDuIjS9Xegq4efAD8sg0E9cZeXXmptk83doaBOVgbG6PPgWfKLokzMLSknypcDNm9XzMdJw29OqzG+6SSq3zOP+eOwve4LTObmrkLibvtj+XxI/JnCaR3fe6N9QC/bU1xeMJYickLTQgmpHqFVWlYBBrrXjYJq+MV0obSgE6s2oWvK736uUMgYVC9ZR/Qy1EG/5sDY23NK1q00hhv5IJBgCrQyKQxPYvCn/XDb6DP+tXlZvO0ezVksnOWheXKiBw3KfwwCRH2K5XDbs7T67YmCZe6FrYUWZ2AnfcQEKlK2jH6HbA0K2MoJrV1magifOGKRFZd5h4j6WtdQTcCZIFzracPfD1GWZNX7bSykm9YJO70pZYOrgbCNsfPGoiQ/2c2Wxqvd4QjuZ5kH/1WVT2BlrTtQLEa5ugE+GI/yeOELySDlLYdGIbFUNXiDE6dPIsHHab1VWl0DztjPP2ZFnRCqfU=
mode:pss-sha256
------ c12c59d278e72bb6 took 343.034 milli-seconds to execute ------
# 验签
❯ easy_encryption_tool rsa verify -e pem -f ./test_data/test_pwd_pem_public.pem -i hello,world -s hZDBb9c0n32kuEWrVsD9eGzQ9b1MYLhQjVcfnB2opvZHxrKDpZPOOo13vwUvju8nUgWMtlP69DS34E5LSSSNLVWBVhbA6eTkGWGGvHSYMWFqtmqBX4K8ZBTZRpeQqruYfN92sllOWGxlUSBCqnDwTGxd350gOM0Blx02gp4zQnEOMiHrg/Apm6qHbfj6Q/dra61+wKKOMNd/W9uuEy+IDuIjS9Xegq4efAD8sg0E9cZeXXmptk83doaBOVgbG6PPgWfKLokzMLSknypcDNm9XzMdJw29OqzG+6SSq3zOP+eOwve4LTObmrkLibvtj+XxI/JnCaR3fe6N9QC/bU1xeMJYickLTQgmpHqFVWlYBBrrXjYJq+MV0obSgE6s2oWvK736uUMgYVC9ZR/Qy1EG/5sDY23NK1q00hhv5IJBgCrQyKQxPYvCn/XDb6DP+tXlZvO0ezVksnOWheXKiBw3KfwwCRH2K5XDbs7T67YmCZe6FrYUWZ2AnfcQEKlK2jH6HbA0K2MoJrV1magifOGKRFZd5h4j6WtdQTcCZIFzracPfD1GWZNX7bSykm9YJO70pZYOrgbCNsfPGoiQ/2c2Wxqvd4QjuZ5kH/1WVT2BlrTtQLEa5ugE+GI/yeOELySDlLYdGIbFUNXiDE6dPIsHHab1VWl0DztjPP2ZFnRCqfU=
------ 8151e7568131a1c6 begin@2024-04-04_16:02:36.431 ------
verify success
key size:4096
mode:pss-sha256
------ 8151e7568131a1c6 took 13.708 milli-seconds to execute ------
ECC椭圆曲线
支持的命令
❯ easy_encryption_tool ecc --help
Usage: main.py ecc [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
ecdh
generate
sign
verify
生成密钥对
❯ easy_encryption_tool ecc generate --help
Usage: main.py ecc generate [OPTIONS]
Options:
-c, --curve [secp256r1|secp384r1|secp521r1|secp256k1]
ecc 椭圆曲线类型 [default: secp256k1]
-e, --encoding [pem|der] 密钥格式 [default: pem]
-f, --file-name TEXT 输出密钥对的文件名前缀,最终写入数据时会创建文件并加上文件名后缀 [default:
demo; required]
-p, --password TEXT 私钥密码,使用私钥时需要输入正确的密码
-r, --random-password 是否生成私钥的随机密码,如果带上 -r 标识,则随机生成32字节的密码
--help Show this message and exit.
默认生成
❯ easy_encryption_tool ecc generate
------ d6b0cebd74d64b57 begin@2024-04-04_16:07:59.720 ------
generate demo_ecc_public.pem/demo_ecc_private.pem success
------ d6b0cebd74d64b57 took 17.039 milli-seconds to execute ------
指定椭圆曲线且指定密码
❯ easy_encryption_tool ecc generate -c secp384r1 -p 1234567890
------ e852fd0a2d84d39f begin@2024-04-04_16:08:46.706 ------
private key password:1234567890
generate demo_ecc_public.pem/demo_ecc_private_cipher.pem success
------ e852fd0a2d84d39f took 16.710 milli-seconds to execute ------
指定椭圆曲线且随机生成密码
❯ easy_encryption_tool ecc generate -c secp384r1 -r
------ 073bd5585937e6fd begin@2024-04-04_16:09:28.102 ------
private key password:)N)y&4dq=ODg`339uE`7*@A9Gl0eVs3Z
generate demo_ecc_public.pem/demo_ecc_private_cipher.pem success
------ 073bd5585937e6fd took 16.721 milli-seconds to execute ------
ECDH密钥交换
支持的参数
❯ easy_encryption_tool ecc ecdh --help
Usage: main.py ecc ecdh [OPTIONS]
Options:
-a, --alice-pub-key TEXT 你自己的公钥文件的路径如: ./alice_public.pem [required]
-k, --alice-pri-key TEXT 你自己的私钥文件的路径如: ./alice_private.pem [required]
-p, --password TEXT 你自己的私钥的密码,如果创建时设置了密码,那么在使用私钥时需要输入正确的密码
-b, --bob-pub-key TEXT 对方的公钥文件的路径如: ./bob_public.pem [required]
-e, --encoding [pem|der] 密钥格式 [default: pem]
-l, --length INTEGER RANGE 派生密钥的长度,默认 32 字节,长度范围[16 -- 64] [default: 32;
16<=x<=64]
-s, --salt TEXT 用于增加派生密钥安全性的盐值,两边必须提供一样的盐值 [default:
hello,world1234567890!@#$%^&*()_+{}:";<>?/;
required]
-c, --context TEXT 用于增加派生密钥安全性的上下文信息,两边必须提供一样的上下文数据 [default: ecc
handshake context data; required]
--help Show this message and exit.
生成 alice 与 bob 的密钥对
❯ easy_encryption_tool ecc generate -f alice -p 1234567890
------ f4815ee66aa727b2 begin@2024-04-04_16:11:03.966 ------
private key password:1234567890
generate alice_ecc_public.pem/alice_ecc_private_cipher.pem success
------ f4815ee66aa727b2 took 17.763 milli-seconds to execute ------
❯ easy_encryption_tool ecc generate -f bob -p 1234567890
------ 76e72cdd07cb5c32 begin@2024-04-04_16:11:26.201 ------
private key password:1234567890
generate bob_ecc_public.pem/bob_ecc_private_cipher.pem success
------ 76e72cdd07cb5c32 took 16.373 milli-seconds to execute ------
alice派生和 bob 共享的对称密钥
❯ easy_encryption_tool ecc ecdh -a ./alice_ecc_public.pem -k ./alice_ecc_private_cipher.pem -p 1234567890 -b ./bob_ecc_public.pem -l 64 -s alice-bob -c key-alice-bob
------ 8235537a02e647d4 begin@2024-04-04_16:14:48.686 ------
curve name:secp256k1
derived key:u+UNGIzrPbLRVlTSixl8fgd3SgLuGeQrwSI4Irs1tpSVivmTxYLTOUm/o1pvqPLuOGVA8D3iLdUGLEE72Wo1QQ==
length:64
------ 8235537a02e647d4 took 18.166 milli-seconds to execute ------
bob派生和alice共享的对称密钥
❯ easy_encryption_tool ecc ecdh -a ./bob_ecc_public.pem -k ./bob_ecc_private_cipher.pem -p 1234567890 -b ./alice_ecc_public.pem -l 64 -s alice-bob -c key-alice-bob
------ d50d7d254d02104c begin@2024-04-04_16:15:39.570 ------
curve name:secp256k1
derived key:u+UNGIzrPbLRVlTSixl8fgd3SgLuGeQrwSI4Irs1tpSVivmTxYLTOUm/o1pvqPLuOGVA8D3iLdUGLEE72Wo1QQ==
length:64
------ d50d7d254d02104c took 16.998 milli-seconds to execute ------
签名与验签
支持的参数
# 签名
❯ easy_encryption_tool ecc sign --help
Usage: main.py ecc sign [OPTIONS]
Options:
-f, --private-key TEXT 私钥文件路径 [required]
-e, --encoding [pem|der] 密钥格式 [default: pem]
-h, --hash-mode [sha256|sha384|sha512|sha3-224|sha3-256|sha3-384|sha3-512]
签名时的哈希算法 [default: sha256]
-p, --password TEXT 私钥密码,如果生成时设置了密码那么在使用私钥时需要输入正确的密码
-i, --input-data TEXT 需要被签名的数据 [required]
-c, --b64-encoded 输入数据是否被 base64 编码过
--help Show this message and exit.
# 验签
❯ easy_encryption_tool ecc verify --help
Usage: main.py ecc verify [OPTIONS]
Options:
-f, --public-key TEXT 公钥文件路径 [required]
-e, --encoding [pem|der] 密钥格式 [default: pem]
-h, --hash-mode [sha256|sha384|sha512|sha3-224|sha3-256|sha3-384|sha3-512]
签名时的哈希算法 [default: sha256]
-i, --input-data TEXT 需要被签名的数据 [required]
-c, --b64-encoded 输入数据是否被 base64 编码过
-s, --signature TEXT base64 编码过的签名值
--help Show this message and exit.
生成密钥对
❯ easy_encryption_tool ecc generate -c secp384r1 -p 1234567890 -e der
------ 3a40beeed28cffa4 begin@2024-04-04_16:17:49.172 ------
private key password:1234567890
generate demo_ecc_public.der/demo_ecc_private_cipher.der success
------ 3a40beeed28cffa4 took 16.821 milli-seconds to execute ------
签名
❯ easy_encryption_tool ecc sign -f ./demo_ecc_private_cipher.der -e der -h sha3-512 -p 1234567890 -i aGVsbG8sd29ybGQK -c
------ dbc12fab8422ba0f begin@2024-04-04_16:18:57.578 ------
curve name:secp384r1
key size:384
signature:30640230243bba7ec0a95f7aef4868673282b70217285a667ae52ce5e43c6af5b33e8adbda86bbe2a7d9f995b934d038eae5624c02306c47daed069e51bb12c274c13219c173ed4b59c6f76caab04f50b4359f3f25c0fa4dab4c17cb88888767f37e4c8cf993
base64 encoded:MGQCMCQ7un7AqV9670hoZzKCtwIXKFpmeuUs5eQ8avWzPorb2oa74qfZ+ZW5NNA46uViTAIwbEfa7QaeUbsSwnTBMhnBc+1LWcb3bKqwT1C0NZ8/JcD6TatMF8uIiIdn835MjPmT
mode:ECDSA
------ dbc12fab8422ba0f took 17.265 milli-seconds to execute ------
验签
❯ easy_encryption_tool ecc verify -f ./demo_ecc_public.der -e der -h sha3-512 -i aGVsbG8sd29ybGQK -c -s MGQCMCQ7un7AqV9670hoZzKCtwIXKFpmeuUs5eQ8avWzPorb2oa74qfZ+ZW5NNA46uViTAIwbEfa7QaeUbsSwnTBMhnBc+1LWcb3bKqwT1C0NZ8/JcD6TatMF8uIiIdn835MjPmT
------ d1c74d3acc46413b begin@2024-04-04_16:20:09.177 ------
curve name:secp384r1
verify success
key size:384
mode:ECDSA
------ d1c74d3acc46413b took 15.220 milli-seconds to execute ------
SM9 标识密码(IBC)
SM9 是国密标识密码(Identity-Based Cryptography):身份字符串(如邮箱)本身就是公钥,无需事先交换证书或公钥。密钥体系分两层——KGC 持有主密钥(master key),按身份为用户派生用户私钥;加密者只需主公钥 + 接收方身份即可加密,签名者持自己的用户签名私钥签名,验签者用主公钥 + 签名者身份验签。命令组为 sm9,需要 GmSSL 原生库。
❯ easy_encryption_tool sm9 --help
Commands:
master-generate 生成 SM9 主密钥对(加密型或签名型)
extract 从主私钥为指定身份派生用户私钥
encrypt 用主公钥为指定身份加密(标识加密)
decrypt 用用户私钥解密
sign 用用户签名私钥签名
verify 用主公钥为指定身份验签
生成主密钥并派生用户私钥
-k 选主密钥类型:enc(加密型)或 sign(签名型)。主私钥文件以口令加密落盘(GmSSL 原生加密 PEM),password 与 sm2/rsa/pqc 相同约定:仅 -r 随机口令时在 result 回显(随机口令不回显则无人能再用这把主密钥),-p 自给口令不回显,均不进 metadata:
❯ easy_encryption_tool sm9 master-generate -k enc -f demo -p 1234567890 --json
{"metadata": {"operation": "master-generate", "algorithm": "sm9-enc", "parameters": {"encoding": "pem", "kind": "enc"}}, "result": {"public_file": "demo_sm9encmaster_public.pem", "private_file": "demo_sm9encmaster_private_cipher.pem"}, "runtime": {...}, "messages": [{"status": "hint", "message": {"code": "EET_HINT", "text": "next: eet sm9 extract -k enc -f demo_sm9encmaster_private_cipher.pem -p <password> --id <identity>"}}]}
# 为 bob@example.com 派生加密用户私钥(解密方持有,身份即公钥)
❯ easy_encryption_tool sm9 extract -k enc -f demo_sm9encmaster_private_cipher.pem -p 1234567890 --id bob@example.com -o demo_bob_user.pem --json
{"metadata": {"operation": "extract", "algorithm": "sm9-enc", "parameters": {"kind": "enc", "id": "bob@example.com"}}, "result": {"key_file": "demo_bob_user.pem", "id": "bob@example.com"}, "runtime": {...}}
用户私钥同样以口令加密存储。身份串最长 63 字节(SM9_MAX_ID_SIZE)。
标识加密与解密
加密只需主公钥 + 接收方身份(--to),接收方用自己的用户私钥解密:
❯ easy_encryption_tool sm9 encrypt -f demo_sm9encmaster_public.pem --to bob@example.com -i "hello bob, this is sm9 encrypted 中文" --json
{"metadata": {"operation": "encrypt", "algorithm": "sm9-enc", "input": {"type": "text", "size": 39}, "parameters": {"to": "bob@example.com", "cipher_size": 149}}, "result": {"cipher": "MIGSAgEAA0IABJXfGqJuTtFMLMdtmutukXmnPsBN9nDdrd/T13EOsTeaQbvr4c0ggomnav72wSGmO9wTnirjpW2354hmqhSO3WIEIMeXQd3g0kskZgUx0qNQ+xqH7T3URlDms0cvKChLwVluBCcwvhKLi9sCKzrl3JQKLEysASQTgs52PyWvpACxOwHE6R5nKdjAX44=", "cipher_in_hex": "3081920201000342000495df1aa26e4ed14c2cc76d9aeb6e9179a73ec04df670ddaddfd3d7710eb1379a41bbebe1cd208289a76afef6c121a63bdc139e2ae3a56db7e78866aa148edd620420c79741dde0d24b24660531d2a350fb1a87ed3dd44650e6b3472f28284bc1596e042730be128b8bdb022b3ae5dc940a2c4cac01241382ce763f25afa400b13b01c4e91e6729d8c05f8e", "cipher_bytes": 149}, "runtime": {...}}
# 解密:-e 表明 -i 是 base64 密文(取上一步输出的 cipher 字段)
❯ easy_encryption_tool sm9 decrypt -f demo_bob_user.pem -p 1234567890 --id bob@example.com -i "<cipher>" -e --json
{"metadata": {"operation": "decrypt", "algorithm": "sm9-enc", "input": {"type": "binary", "size": 149}, "parameters": {"id": "bob@example.com"}}, "result": {"plain": "hello bob, this is sm9 encrypted 中文"}, "runtime": {...}}
身份不匹配(用 alice 的用户私钥解给 bob 的密文)解密失败并输出错误文档。
标识签名与验签
签名者持签名型用户私钥,验签方用签名主公钥 + 签名者身份(--id):
❯ easy_encryption_tool sm9 sign -f demo_alice_sign_user.pem -p 1234567890 -i "sm9 signed message from alice" --json
{"metadata": {"operation": "sign", "algorithm": "sm9-sign", "input": {"type": "text", "size": 29}}, "result": {"signature": "MGYEIFVPXeRmEhbqQ/gUUUlhnn6bmsXO/BTHLignsjNW3s2mA0IABCyjMZQa5yXSm/D4piAJv6PcAUCh8WXqzStsAT020nALL8lYGukcLL53SgwSwKeTXO+cKDvchuG7kit9l1LIsOE=", "signature_in_hex": "30660420554f5de4661216ea43f8145149619e7e9b9ac5cefc14c72e2827b23356decda6034200042ca331941ae725d29bf0f8a62009bfa3dc0140a1f165eacd2b6c013d36d2700b2fc9581ae91c2cbe774a0c12c0a7935cef9c283bdc86e1bb922b7d9752c8b0e1", "signature_bytes": 104}, "runtime": {...}}
# 验签:-s 传入签名输出的 signature(base64),--id 必须与签名者身份一致
❯ easy_encryption_tool sm9 verify -f demo_sm9signmaster_public.pem --id alice@example.com -i "sm9 signed message from alice" -s "<signature>" --json
{"metadata": {"operation": "verify", "algorithm": "sm9-sign", "input": {"type": "text", "size": 29}, "parameters": {"id": "alice@example.com"}}, "result": {"valid": true}, "runtime": {...}}
身份不符或消息被篡改时 valid 为 false 或输出错误文档。SM9 签名随机化:同一私钥对同一消息多次签名结果不同,属正常现象。
密钥派生(HKDF / SM3-KDF / PBKDF2-HMAC-SM3)
kdf 命令提供三种派生构造:hkdf(RFC 5869,走 cryptography,无需原生库,3.2.0 起为默认)与两种基于 SM3 的派生方式(需 GmSSL 原生库):
# HKDF:默认算法(sha256、盐未提供按 RFC 5869 补零),二进制 IKM 用 -i <base64> -e
❯ easy_encryption_tool kdf -i ikm-material -l 32 --json
{"metadata": {"operation": "kdf", "algorithm": "hkdf", "input": {"type": "text", "size": 12}, "parameters": {"algorithm": "hkdf", "key_len": 32, "hash": "sha256", "salt_source": "none", "salt_bytes": 0, "info_bytes": 0}}, "result": {"key": "vBmgrK8IqUxy+NSYQ7JrLhVEJtNsL0zKKHlmEFCtUlg=", "key_in_hex": "bc19a0acaf08a94c72f8d49843b26b2e154426d36c2f4cca2879661050ad5258", "key_bytes": 32, "formats": {"key": "base64", "key_in_hex": "hex"}}, "runtime": {...}}
# HKDF:指定哈希与盐/上下文(--info/--info-b64 提供上下文信息)
❯ easy_encryption_tool kdf -a hkdf -H sha512 -i ikm-material --salt eet-salt-01 --info derive-ctx -l 64 --json
{"metadata": {"operation": "kdf", "algorithm": "hkdf", "input": {"type": "text", "size": 12}, "parameters": {"algorithm": "hkdf", "key_len": 64, "hash": "sha512", "salt_source": "cli", "salt_bytes": 11, "info_bytes": 10}}, "result": {"key": "8R5n8jXyB5rRnwrJvTTiGb1Sg9SivldQ/X2GqKhA8fMmABhzV+dQFGvP7wwVU0ZzgxKj+Ihmta+5V2/XFflzEA==", "key_in_hex": "f11e67f235f2079ad19f0ac9bd34e219bd5283d4a2be5750fd7d86a8a840f1f32600187357e750146bcfef0c155346738312a3f88866b5afb9576fd715f97310", "key_bytes": 64, "formats": {"key": "base64", "key_in_hex": "hex"}}, "runtime": {...}}
# SM3-KDF:从共享秘密派生密钥材料(ECDH 共享点后派生对称密钥的典型用法)
❯ easy_encryption_tool kdf -a sm3 -i kat-secret -l 32 --json
{"metadata": {"operation": "kdf", "algorithm": "sm3-kdf", "input": {"type": "text", "size": 10}, "parameters": {"algorithm": "sm3", "key_len": 32}}, "result": {"key": "rfR8C/wIpbbg2PPzkHuCYho96xmf7po4EY5zzdb0OQs=", "key_in_hex": "adf47c0bfc08a5b6e0d8f3f3907b82621a3deb199fee9a38118e73cdd6f4390b", "key_bytes": 32, "formats": {"key": "base64", "key_in_hex": "hex"}}, "runtime": {...}}
# PBKDF2-HMAC-SM3:从口令派生,--salt/--salt-b64/--iter 可选
❯ easy_encryption_tool kdf -a pbkdf2-sm3 -i kat-password --salt eet-salt-01 --iter 10000 -l 32 --json
{"metadata": {"operation": "kdf", "algorithm": "sm3-pbkdf2", "input": {"type": "text", "size": 12}, "parameters": {"algorithm": "pbkdf2-sm3", "key_len": 32, "iterations": 10000, "salt_bytes": 11, "salt_source": "cli"}}, "result": {"key": "Mqm1kNfz58iWtbKMx4mUw6CayE2qituhTNZJztcq/GM=", "key_in_hex": "32a9b590d7f3e7c896b5b28cc78994c3a09ac84daa8adba14cd649ced72afc63", "key_bytes": 32, "formats": {"key": "base64", "key_in_hex": "hex"}}, "runtime": {...}}
要点:
-a hkdf(默认,3.2.0 起;原默认sm3,隐式依赖默认值的脚本需显式写-a sm3):-H选 sha1/224/256/384/512,长度 1–1024 字节。盐是可选的上下文绑定值,缺省不随机生成(未提供按 RFC 补 HashLen 零),--salt(文本)/--salt-b64(字节)显式给;--info/--info-b64提供上下文信息。RFC 5869 A.1–A.4 官方向量在 CLI 上逐位复现。-a sm3(SM3-KDF)不接受盐参数,派生是确定性的;长度范围 1–1024 字节。-a pbkdf2-sm3缺省生成 16 字节随机盐,随机盐会以 base64 回显在 result 的salt字段(否则派生不可复现);用--salt(文本)或--salt-b64(字节)显式给盐时 result 不再回显。迭代次数范围 [10000, 16777216],长度范围 1–256 字节。- 二进制秘密用
-i <base64> -e传入(hkdf 与 sm3 均支持)。
SM4 对称加解密(CBC / GCM / CTR)
sm4 命令用法与 aes 一致(密钥/IV 规范化、-r 随机密钥、文件输入输出),模式经 -m 选择。3.0 起新增 CTR 计数器模式:
❯ easy_encryption_tool sm4 -A encrypt -m ctr -k 0123456789abcdef -v fedcba9876543210 -i "ctr mode payload" --json
{"metadata": {"operation": "encrypt", "algorithm": "sm4-ctr", "input": {"type": "text", "size": 16}, "parameters": {"mode": "ctr"}}, "result": {"cipher": "9wc1NPqEZ8jTrkvEQmXQ+g==", "formats": {"cipher": "base64"}}, "runtime": {...}}
❯ easy_encryption_tool sm4 -A decrypt -m ctr -k 0123456789abcdef -v fedcba9876543210 -i "<cipher>" -e --json
{"metadata": {"operation": "decrypt", "algorithm": "sm4-ctr", "input": {"type": "binary", "size": 16}, "parameters": {"mode": "ctr"}}, "result": {"plain": "ctr mode payload", "formats": {"plain": "utf-8"}}, "runtime": {...}}
CTR 是流模式:不做填充,密文长度恒等于明文长度(上例 16 字节进 16 字节出),因此 --gcm-pad 类填充选项与 ctr 互斥。CBC(PKCS#7 填充)与 GCM(12 字节 nonce + 16 字节 tag)行为不变。
PQC 后量子(ML-KEM / ML-DSA)
后量子命令组 pqc,提供 ML-KEM(FIPS 203 密钥封装)与 ML-DSA(FIPS 204 签名)能力,需要 cryptography >= 47(ExternalMu 模式需 >= 49)。参数集可用性取决于所装 cryptography 版本(easy_encryption_tool version 的 Dependencies 行会列出当前可用参数集)。
与 CipherHUB 工具站 的互通关系:公钥可互换(双方均为 NIST 标准 OID 的 SPKI/PKCS#8,工具站后端 liboqs 生成的公钥可直接喂给本工具 encap/verify);私钥不可互换(本工具私钥为 PKCS#8 种子形态加密存储,工具站为展开形态,二者格式不同)。
生成 ML-KEM 密钥对
# 私钥强制密码保护:-p 指定密码,或 -r 随机生成(两者都不传默认随机)
# -r 随机口令回显在 result.password;-p 自给口令不回显
❯ easy_encryption_tool pqc mlkem generate -f demo -p 1234567890 --json
{"metadata": {"operation": "generate", "algorithm": "ML-KEM-768", "parameters": {"encoding": "pem", "seed_derived": false}}, "result": {"public_file": "demo_mlkem768_public.pem", "private_file": "demo_mlkem768_private_cipher.pem"}, "runtime": {"request_id": "a2bac659-2d54-47f2-be3f-aab0fa28174c", "timestamp": "2026-08-28T15:07:32.353623+08:00", "duration_ms": 9.809, "host": "MacM2Max-2.local", "version": "v2.7.0"}}
-a/--algorithm 可选 ML-KEM-512、ML-KEM-768(默认)、ML-KEM-1024;--seed-in-hex 接受 64 字节 hex(128 个十六进制字符)做确定性派生,仅供教学与向量复现,生产环境留空即随机生成。
ML-KEM 封装与解封装
发送方持有公钥做封装,得到密文与共享秘密;接收方持私钥解封装还原同一个共享秘密(典型用法:共享秘密作为对称加密的密钥材料)。
# 封装:输出 ciphertext(交给孩子信道传输)与 shared_secret(发送方本地留存)
❯ easy_encryption_tool pqc mlkem encap -f demo_mlkem768_public.pem --json
{"metadata": {"operation": "encap", "algorithm": "ML-KEM-768", "input": {"type": "key"}, "parameters": {"ciphertext_bytes": 1088}}, "result": {"ciphertext_in_hex": "cbf390d5c3a98de7ece00606...(共 2176 个 hex 字符)", "ciphertext_in_base64": "y/OQ1cOpjefs4AYGeHQe/Cf2knCg...(共 1452 个字符)", "ciphertext_bytes": 1088, "shared_secret_in_hex": "ca4954152db0dd42d6e50ff35ecc51a7590bc487cf7339ee352610cc4b7a56c3", "shared_secret_in_base64": "yklUFS2w3ULW5Q/zXsxRp1kLxIfPcznuNSYQzEt6VsM=", "shared_secret_sha256": "b71c5ae5a9132597df7a96250af8b029b24ec1e91ce92cc18de699dd8f35b8cc", "shared_secret_bytes": 32}, "runtime": {...}}
# 解封装:-i 传入封装输出的 ciphertext_in_base64
❯ easy_encryption_tool pqc mlkem decap -f demo_mlkem768_private_cipher.pem -p 1234567890 -i "<ciphertext_in_base64>" --json
{"metadata": {"operation": "decap", "algorithm": "ML-KEM-768", "input": {"type": "binary", "size": 1088}}, "result": {"shared_secret_in_hex": "9b907dd7844ce9dd906e645ecaaa95936b18b43d7f66b21ae2ef265496ef1f7a", "shared_secret_in_base64": "m5B914RM6d2QbmReyqqVk2sYtD1/ZrIa4u8mVJbvH3o=", "shared_secret_sha256": "c8f5e74ba6ca40c5cef8d72de727c67183b256359c2639fb489e54abcc167697", "shared_secret_bytes": 32}, "runtime": {...}}
注意两次 shared_secret 不同是正常的:ML-KEM 封装本身随机化,同一条 ciphertext 的 encap/decap 结果必然一致(上例两段输出来自两次独立的封装)。按 FIPS 203 的隐式拒绝语义,篡改后的 ciphertext 解封装不报错,但得到的共享秘密必然不同——比对 shared_secret_sha256 即可发现。
生成 ML-DSA 密钥对
❯ easy_encryption_tool pqc mldsa generate -f demo -p 1234567890 --json
{"metadata": {"operation": "generate", "algorithm": "ML-DSA-65", "parameters": {"encoding": "pem", "seed_derived": false}}, "result": {"public_file": "demo_mldsa65_public.pem", "private_file": "demo_mldsa65_private_cipher.pem"}, "runtime": {...}}
-a/--algorithm 可选 ML-DSA-44、ML-DSA-65(默认)、ML-DSA-87;--seed-in-hex 接受 32 字节 hex(64 个十六进制字符)做确定性派生,仅供教学与向量复现。
ML-DSA 签名与验签
# 签名:--context 为可选域分隔字符串(最长 255 字节),验签时必须传同一个值
❯ easy_encryption_tool pqc mldsa sign -f demo_mldsa65_private_cipher.pem -p 1234567890 -i "hello,post-quantum" --context eet-demo --json
{"metadata": {"operation": "sign", "algorithm": "ML-DSA-65", "input": {"type": "text", "size": 18}, "parameters": {"context": "eet-demo"}}, "result": {"signature_in_hex": "b2de9bf26b6685e2b64d8c348ccf726f...(共 6618 个 hex 字符)", "signature_in_base64": "st6b8mtmheK2TYw0jM9ybwQwSnPvYWp2M+Yk...(共 4412 个字符)", "signature_bytes": 3309}, "runtime": {...}}
# 验签:-s 传入签名输出的 signature_in_base64,--context 必须与签名时一致
❯ easy_encryption_tool pqc mldsa verify -f demo_mldsa65_public.pem -i "hello,post-quantum" --context eet-demo -s "<signature_in_base64>" --json
{"metadata": {"operation": "verify", "algorithm": "ML-DSA-65", "input": {"type": "text", "size": 18}, "parameters": {"context": "eet-demo"}}, "result": {"valid": true}, "runtime": {...}}
ML-DSA 签名是随机化的:同一私钥对同一消息多次签名结果不同,属正常现象。验签失败(密钥、消息、context 不匹配或签名被篡改)时输出错误文档并以退出码 1 结束。
ML-DSA ExternalMu 模式(cryptography >= 49)
FIPS 204 的签名输入实际是 64 字节中间值 mu(mu = SHAKE-256(tr‖M', 64),tr 是公钥的哈希、M' 是 context 前缀化的消息)。ExternalMu 模式把「算 mu」与「对 mu 签名」拆开,与 AWS KMS ML-DSA EXTERNAL_MU 语义对齐——密钥留在 KMS/本机,消息摘要可在别处计算。3.1 起此模式走 cryptography 原生 sign_mu/verify_mu(>= 49),不再依赖系统 OpenSSL(cryptography wheel 静态自带),可用性在 doctor 的 external-mu 行与 version --json 的 external_mu 段展示。
三个命令形态:
# 1) compute-mu:从公钥(或私钥,会派生公钥)计算 mu,纯 hashlib 实现,零额外依赖
❯ easy_encryption_tool pqc mldsa compute-mu -f demo_mldsa65_public.pem -i "external mu demo message" --json
{"metadata": {"operation": "compute-mu", "algorithm": "ML-DSA-65", "input": {"type": "text", "size": 24}}, "result": {"mu_in_hex": "4960e833ab4cd4835874423b0dc78880fc76e2b04e0cef784c1320359e81e885ec99e84ed2970d34839c17fa2003e8b9751499c6fd831524f37650efb49833e4", "mu_in_base64": "SWDoM6tM1INYdEI7DceIgPx24rBODO94TBMgNZ6B6IXsmehO0pcNNIOcF/ogA+i5dRSZxv2DFSTzdlDvtJgz5A==", "mu_bytes": 64, "tr_in_hex": "0da3bf875d68bf5e2ec526af9065e24bf6d279c18b8e6907dd09e349267ab154373d0dd5584dd1e8904f6bc06f590f9a30c1f64368f3bd362b28b1d5232eb24e"}, "runtime": {...}, "messages": [{"status": "hint", "message": {"code": "EET_HINT", "text": "next: eet pqc mldsa sign --external-mu --raw-mu -f <private_key> -i <mu_in_hex>"}}]}
# 2) sign --external-mu --raw-mu:-i 直接是 64 字节 mu(hex),不再内部哈希
❯ easy_encryption_tool pqc mldsa sign --external-mu --raw-mu -f demo_mldsa65_private_cipher.pem -p 1234567890 -i "<mu_in_hex>" --json
{"metadata": {"operation": "sign", "algorithm": "ML-DSA-65", "input": {"type": "text", "size": 64}, "parameters": {"mode": "external-mu-raw"}}, "result": {"signature_in_hex": "f9b53026...(共 6618 个 hex 字符)", "signature_in_base64": "+bUwJpwhBPJ1...(共 4412 个字符)", "signature_bytes": 3309}, "runtime": {...}}
# 3) verify --external-mu --raw-mu:对称验签,-s 传 base64 签名
❯ easy_encryption_tool pqc mldsa verify --external-mu --raw-mu -f demo_mldsa65_public.pem -i "<mu_in_hex>" -s "<signature_in_base64>" --json
{"metadata": {"operation": "verify", "algorithm": "ML-DSA-65", "input": {"type": "text", "size": 64}, "parameters": {"mode": "external-mu-raw"}}, "result": {"valid": true}, "runtime": {...}}
说明:
sign --external-mu(不带--raw-mu):消息照常传-i,eet 内部算 mu 后走 cryptography 原生 mu 签名——产物与标准模式签名互通,pqc mldsa verify(标准模式)可直接验。--raw-mu:-i必须恰为 64 字节(hex 128 字符或 base64),且与--context互斥(context 已在算 mu 时消费)。长度不符报「raw mu must be 64 bytes」。compute-mu与--raw-mu串联即完整 ExternalMu 流程:摘要计算与密钥使用可以发生在不同机器。
证书解析与验证
解析证书并验证签名
❯ easy_encryption_tool cert-parse -f test_certs/baidu.com.cer
------ 27f6aa95a2461345 begin@2024-04-06_15:02:26.887 ------
------- verify signature: -------
verify cert signature success
ca issuer:http://secure.globalsign.com/cacert/gsrsaovsslca2018.crt
------- basic info: -------
version: v3-2
serial_number: 26585094245224241434632730821
signature_algorithm: PKCS #1 RSA Encryption
signature_hash_algorithm: sha256
issuer: GlobalSign nv-sa|GlobalSign RSA OV SSL CA 2018|BE
valid_before: 20230706015106Z
valid_after: 20240806015105Z
subject: Beijing Baidu Netcom Science Technology Co., Ltd|CN|baidu.com
public_key_bits: 2048
public_key_type: 6(6:RSA|116:DSA|408:EC|28:DH)
------ 27f6aa95a2461345 took 83.634 milli-seconds to execute ------
解析完整证书内容
❯ easy_encryption_tool cert-parse -f baidu.com.cer -v
------ 247b96f11927fe0f begin@2024-04-06_15:04:26.023 ------
------- verify signature: -------
verify cert signature success
ca issuer:http://secure.globalsign.com/cacert/gsrsaovsslca2018.crt
------- basic info: -------
version: v3-2
serial_number: 26585094245224241434632730821
signature_algorithm: PKCS #1 RSA Encryption
signature_hash_algorithm: sha256
issuer: GlobalSign nv-sa|GlobalSign RSA OV SSL CA 2018|BE
valid_before: 20230706015106Z
valid_after: 20240806015105Z
subject: Beijing Baidu Netcom Science Technology Co., Ltd|CN|baidu.com
public_key_bits: 2048
public_key_type: 6(6:RSA|116:DSA|408:EC|28:DH)
------- verbose info: -------
public_key_exponent: ('10001',)
public_key_modules: ('BB04BB84765807B45A8854E06A56BCE5D48D3E1EB928E0D7018F382B41B2597DF0AC27B426241438FE4CEA3B4951F7E95B40F73FA6C8DA0F026E258B4791B82E9E0021191D1800FCDE04FD2679395DF290BC809DA87CB2918989D8402FE5D2A7F35E6D482BC51F0AB1E08E8C76FFBCD1670AD249D609EE260302F3CCCDEA8AD531A82D8F03FD5EFCE43AC68967994CCE986DFA840D0E538BE66352C59B4AA9ABA32235990DEE19FF9B2DF5A477F2EC1080F4AB82B9D17E361F0E9F9B19A0F5C357DD88BBCEE1909C3F4BBADD3AA941B3DD864DC2C2B7E8FF3713C0048943443811E6A396F70922212F2C4E0E7EE5D85CBB00445BAFDEE4B3B0F03CB63845495D',)
public_key_fingerprints: 43A4C24005AA3F8B7E7AAE35C6729A52025DACF5AAC86E4BF8D8B6633321A9D6
signature: 0X195A675043B1AC7A93A86818728B407EA675DEAC21FCC94116204BF38C0BB94745AEF85D79F64335260198F0B9863E2901F1DFB072B5AE78D2DF61B678678AC9779ADEE0E4412F9C1EE53B7C973F422FADE3497F9D2B0288906925030114B9B5CB0F593D2D973D02D55190690C811022DAC651EF480CD24FDE61F26A8715A56D718E3702A2850F1E1975A3802E6A1AA2028C2FECBD3D81033F8AC0A0E6B40E0857CB001C8AB71B8F38719A8DC0710C3FBCD4BE569DF718C1AABEE4DF1A86E2626F23863054782D471FB4AD052973249814A019C002FD90904E625CE84D3189C3E88B9E73593B9891CA47A5055BC51E8F85390ECEB5260A804E9F084A11491363
certificate_fingerprints: D8:AA:2D:80:6C:57:1F:B6:2E:D4:87:48:41:90:92:3F:93:24:F0:31:9C:FF:FE:DF:7B:62:1F:13:4E:6B:C1:00
extension_count: 10
extensions_detail: {
"x509.AuthorityInformationAccess": {
"oid": "1.3.6.1.5.5.7.1.1",
"critical": false,
"value": {
"caIssuers": "http://secure.globalsign.com/cacert/gsrsaovsslca2018.crt",
"OCSP": "http://ocsp.globalsign.com/gsrsaovsslca2018"
}
},
"x509.BasicConstraints": {
"oid": "2.5.29.19",
"critical": false,
"value": "<BasicConstraints(ca=False, path_length=None)>"
},
"x509.KeyUsage": {
"oid": "2.5.29.15",
"critical": true,
"value": "<KeyUsage(digital_signature=True, content_commitment=False, key_encipherment=True, data_encipherment=False, key_agreement=False, key_cert_sign=False, crl_sign=False, encipher_only=False, decipher_only=False)>"
},
"x509.SubjectKeyIdentifier": {
"oid": "2.5.29.14",
"critical": false,
"value": "<SubjectKeyIdentifier(digest=b'\\xeds\\xab\\xf9 \\xbez\\x19\\x9fY\\x1f\\xb2\\x9f\\xf2?/?\\x91\\x84\\x12')>"
},
"x509.SubjectAlternativeName": {
"oid": "2.5.29.17",
"critical": false,
"value": "<SubjectAlternativeName(<GeneralNames([<DNSName(value='baidu.com')>, <DNSName(value='baifubao.com')>, <DNSName(value='www.baidu.cn')>, <DNSName(value='www.baidu.com.cn')>, <DNSName(value='mct.y.nuomi.com')>, <DNSName(value='apollo.auto')>, <DNSName(value='dwz.cn')>, <DNSName(value='*.baidu.com')>, <DNSName(value='*.baifubao.com')>, <DNSName(value='*.baidustatic.com')>, <DNSName(value='*.bdstatic.com')>, <DNSName(value='*.bdimg.com')>, <DNSName(value='*.hao123.com')>, <DNSName(value='*.nuomi.com')>, <DNSName(value='*.chuanke.com')>, <DNSName(value='*.trustgo.com')>, <DNSName(value='*.bce.baidu.com')>, <DNSName(value='*.eyun.baidu.com')>, <DNSName(value='*.map.baidu.com')>, <DNSName(value='*.mbd.baidu.com')>, <DNSName(value='*.fanyi.baidu.com')>, <DNSName(value='*.baidubce.com')>, <DNSName(value='*.mipcdn.com')>, <DNSName(value='*.news.baidu.com')>, <DNSName(value='*.baidupcs.com')>, <DNSName(value='*.aipage.com')>, <DNSName(value='*.aipage.cn')>, <DNSName(value='*.bcehost.com')>, <DNSName(value='*.safe.baidu.com')>, <DNSName(value='*.im.baidu.com')>, <DNSName(value='*.baiducontent.com')>, <DNSName(value='*.dlnel.com')>, <DNSName(value='*.dlnel.org')>, <DNSName(value='*.dueros.baidu.com')>, <DNSName(value='*.su.baidu.com')>, <DNSName(value='*.91.com')>, <DNSName(value='*.hao123.baidu.com')>, <DNSName(value='*.apollo.auto')>, <DNSName(value='*.xueshu.baidu.com')>, <DNSName(value='*.bj.baidubce.com')>, <DNSName(value='*.gz.baidubce.com')>, <DNSName(value='*.smartapps.cn')>, <DNSName(value='*.bdtjrcv.com')>, <DNSName(value='*.hao222.com')>, <DNSName(value='*.haokan.com')>, <DNSName(value='*.pae.baidu.com')>, <DNSName(value='*.vd.bdstatic.com')>, <DNSName(value='*.cloud.baidu.com')>, <DNSName(value='click.hm.baidu.com')>, <DNSName(value='log.hm.baidu.com')>, <DNSName(value='cm.pos.baidu.com')>, <DNSName(value='wn.pos.baidu.com')>, <DNSName(value='update.pan.baidu.com')>])>)>"
},
"x509.CRLDistributionPoints": {
"oid": "2.5.29.31",
"critical": false,
"value": "<CRLDistributionPoints([<DistributionPoint(full_name=[<UniformResourceIdentifier(value='http://crl.globalsign.com/gsrsaovsslca2018.crl')>], relative_name=None, reasons=None, crl_issuer=None)>])>"
},
"x509.ExtendedKeyUsage": {
"oid": "2.5.29.37",
"critical": false,
"value": "<ExtendedKeyUsage([<ObjectIdentifier(oid=1.3.6.1.5.5.7.3.1, name=serverAuth)>, <ObjectIdentifier(oid=1.3.6.1.5.5.7.3.2, name=clientAuth)>])>"
},
"x509.FreshestCRL": {
"ERROR": "x509.ExtensionNotFound",
"oid": "",
"value": {},
"critical": false
},
"x509.NameConstraints": {
"ERROR": "x509.ExtensionNotFound",
"oid": "",
"value": {},
"critical": false
},
"x509.PolicyConstraints": {
"ERROR": "x509.ExtensionNotFound",
"oid": "",
"value": {},
"critical": false
}
}
------ 247b96f11927fe0f took 76.036 milli-seconds to execute ------
解析非法证书内容
# pem格式
❯ easy_encryption_tool cert-parse -f ./test.crt
------ 34ce7a7ed108f599 begin@2024-04-06_15:05:43.194 ------
loading cert file:./upload.sh as format:pem failed:[('PEM routines', '', 'no start line')]
------ 34ce7a7ed108f599 took 0.140 milli-seconds to execute ------
# der格式
❯ easy_encryption_tool cert-parse -f ./test.crt -e der
------ 041f017f1492c8ce begin@2024-04-06_15:06:04.418 ------
loading cert file:./upload.sh as format:der failed:[('asn1 encoding routines', '', 'wrong tag'), ('asn1 encoding routines', '', 'nested asn1 error')]
------ 041f017f1492c8ce took 0.170 milli-seconds to execute ------
Server 模式(HTTP 服务,实验性)
server 命令把整棵 CLI 命令树以 HTTP 服务暴露:请求体里的 args 数组就是命令行参数,服务在进程内调用与 CLI 完全相同的实现,响应体是与 --json 输出完全一致的标准输出文档。需要 [server] extra(pip install "easy-encryption-tool[server]")。3.0.x 入口已注释停用(见上文实验性声明),下文用法为将来重新启用后的参考。
# 启动:端口必填;--token 开启 Bearer 鉴权;默认只绑定 127.0.0.1
❯ easy_encryption_tool server --port 8000 --token my-secret-token
INFO: Uvicorn running on http://127.0.0.1:8000
两个端点:
GET /api/v1/health—— 探活,不做鉴权,返回{"status": "ok", "service": "eet-server", "version": "..."};POST /api/v1/cli—— 通用 argv 端点,body{"args": ["hash", "-i", "hello", "-a", "sm3"]}。
# 像用命令行一样发请求:args 就是 CLI 参数(--json 由服务自动补上)
❯ curl -s http://127.0.0.1:8000/api/v1/health
{"status":"ok","service":"eet-server","version":"3.0.0"}
❯ curl -s -H "Authorization: Bearer my-secret-token" \
-H "Content-Type: application/json" \
-d '{"args":["hash","-i","hello from server","-a","sm3"]}' \
http://127.0.0.1:8000/api/v1/cli
{"metadata":{"operation":"hash","algorithm":"sm3","input":{"type":"text","size":17},"parameters":{"digest_size":32}},"result":{"digest":"0404a15d0ceee521bec8b0f8c91cac471c2213628c258cac2e0a8ab5d5988cd2","formats":{"digest":"hex"}},"runtime":{"request_id":"ae044e1d-764a-485c-a223-57ab533318a5","timestamp":"2026-08-31T16:23:46.676712+08:00","duration_ms":0.07,"host":"MacM2Max-2.local","version":"v3.0.0"}}
行为约定:
| 方面 | 行为 |
|---|---|
| 状态码映射 | CLI 退出码 0 → 200;2(参数错误)→ 400;1(运行错误)→ 422;真实退出码另附 X-EET-Exit-Code 响应头 |
| 错误响应体 | 与 CLI 相同的结构化错误文档(status: "error"),非 FastAPI 默认格式 |
| 鉴权 | --token 给出后要求 Authorization: Bearer <token> 或 X-EET-Token: <token>,缺失/不符返回 401(body 同样是结构化错误文档,code EET_UNAUTHORIZED);不给 --token 则不鉴权 |
| stdout 回退 | 命令不支持 --json 时(如 --version)回退捕获 stdout,包成 {"output": "...", "exit_code": 0} |
| 绑定地址 | 默认 127.0.0.1,--host 显式放开(对外开放务必配合 --token,并置于反向代理/TLS 之后) |
FastAPI 未安装时 server 命令输出结构化错误与安装指引(pip install "easy-encryption-tool[server]"),其余命令不受影响。
Release files for easy-encryption-tool 3.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| easy_encryption_tool-3.2.1.tar.gz | 308.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| easy_encryption_tool-3.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 633.8 kB
Release files / easy_encryption_tool-3.2.1.tar.gz
| Download URL | easy_encryption_tool-3.2.1.tar.gz |
|---|---|
| Size | 308.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9775fb9451385d192b48c16336aa42adc5305d23acef495be94dbd5943820bda
|
|
BLAKE2b-256 checksum How to use checksums |
c7830d38115f907bd962a596fb42c05aecf6ae2c0d62d25ab8196f5e077f8510
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.0.1 CPython/3.12.7
|
Release files / easy_encryption_tool-3.2.1-py3-none-any.whl
| Download URL | easy_encryption_tool-3.2.1-py3-none-any.whl |
|---|---|
| Size | 325.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cde6ad657e85ee05b295a15ca3a8af17ccbbc87b3237183243e574dac1c28493
|
|
BLAKE2b-256 checksum How to use checksums |
76fd46fca403bbb18883292894db41e57b00ae3699f9b73f16fc454b5e454d2a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.0.1 CPython/3.12.7
|