encryption-tool


Nameencryption-tool JSON
Version 1.0.1 PyPI version JSON
download
home_pagehttps://cloud.tencent.com/developer/article/2155922
SummaryNone
upload_time2024-04-04 09:03:40
maintainerNone
docs_urlNone
authorbowenerchen
requires_pythonNone
licenseMIT
keywords encryption cli tool security aes hmac ecc rsa
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 加密工具功能测试和使用说明

## 工具支持的命令

本文中默认将 python3 简写为 py3。

```python
❯ py3 main.py --help

Usage: main.py [OPTIONS] COMMAND [ARGS]...

Options:
  --help  Show this message and exit.

Commands:
  aes         aes encryption && decryption tool
  ecc         ecc encryption && decryption && sign && verify tool
  hmac        hmac tool
  random-str  random string tool
  rsa         rsa encryption && decryption && sign && verify tool
  version     show version
```

## 显示版本

```python
# 展示版本信息,包括:
# 工具版本
# python解释器版本
# 操作系统
# cpu
# 字节序
# 作者信息
❯ py3 main.py version

------ 7906e795524f2b7c begin@2024-04-04_15:02:59.590 ------
tool-version:v1.0.0
python:3.11.4 (main, Jul  5 2023, 08:54:11) [Clang 14.0.6 ]
os:darwin
chip:macOS-14.3.1-arm64-arm-64bit
byte-order:little
------ 7906e795524f2b7c took 0.007 milli-seconds to execute ------

```

## 生成随机字符串

### 支持的参数

```python
❯ py3 main.py 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

```python
# -l指定随机字符串的长度为32字节
❯ py3 main.py 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 ------
```

### 输出到文件

```python
❯ py3 main.py 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
```

### 当指定的文件不可写时

```python
❯ py3 main.py 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对称加密算法

### 支持的命令参数

```python
❯ py3 main.py aes --help
Usage: main.py aes [OPTIONS]

Options:
  -m, --mode [cbc|gcm]            aes mode,默认为 cbc 模式,可选 cbc 或 gcm 模式
                                  [default: cbc]
  -k, --key TEXT                  key 默认 32 字节,即 256 位,只允许输入可见字符,
                                  长度不够则自动补齐,长度超出则自动截取  [default:
                                  kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk]
  -v, --iv-nonce TEXT             cbc 模式下,iv 默认 16 字节即 128 位,gcm 模式下 nonce 默认
                                  12 字节即 96 位,长度不够则自动补齐,长度超出则自动截取  [default:
                                  vvvvvvvvvvvvvvvv]
  -r, --random-key-iv             是否自动生成随机的密钥和 iv/nonce,如果随机生成,则密钥长度默认 32
                                  字节,iv 默认为 16 字节, nonce 默认为 12 字节
  -a, --action [encrypt|decrypt]  加密(encrypt)或 解密(decrypt),加密后输出 base64 编码的字符串
                                  [default: encrypt]
  -i, --input-data TEXT           输入数据,即被加密或解密的数据,加密时允许输入:字符串、 base64
                                  编码数据、文件路径,解密时允许输入:base64 编码数据、文件路径
                                  [required]
  -e, --is-base64-encoded         如果 -i/--input-data 的值被 base64 编码过,则需要带上 -e
                                  参数,-e 与 -f 互斥  [default: False]
  -f, --is-a-file                 如果 -i/--input-data 的值是一个文件,则需要带上 -f
                                  参数表示当前需要被处理的是一个文件,-e 与 -f 互斥
  -l, --input-limit INTEGER       输入内容最大长度,单位为 MB,默认为 1MB,在 -i 为非文件时生效
                                  [default: 1]
  -o, --output-file TEXT          指定输出文件,当输入时指定了文件,则输出时必须指定
  -t, --gcm-tag TEXT              gcm 模式解密时,则此参数必填
  --help                          Show this message and exit.
```

### 关于密钥、IV和模式的预设

-   加密模式:仅支持 CBC 模式和 GCM 模式,加密时强制按照 PKCS#7 规则进行数据填充(Padding)
-   密钥:默认 32 字节,即 256 位,不足会自动补齐,超过会自动截取
-   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

#### 使用默认的密钥

```shell
# 加密hello,world,密钥和 iv 均为默认数据
❯ py3 main.py 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
❯ py3 main.py 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 ------
```

#### 使用随机生成的密钥

```python
# 加密 -r 表示随机生成密钥和 IV
❯ py3 main.py 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 命令的字符比如‘&’、‘!’等等
❯ py3 main.py 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 长度不够时会自动填充

```python
# 加密,此时 key(1234) 和 iv(1234) 长度都不足
❯ py3 main.py 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 ------
                
# 解密
❯ py3 main.py 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超长时会自动截取

```python
# 加密,此时密钥和 iv 的长度都超长
❯ py3 main.py 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 ------

# 解密
❯ py3 main.py 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 ------
```

### 指定明文

#### 输入字符串作为明文

```python
# 加密
❯ py3 main.py 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编码的字节流作为明文

```python
# 加密 -e 表明输入的数据经过了 base64 编码,加密或解密时需要先将数据做 base64 解码
❯ py3 main.py 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 ------
```

#### 输入文件作为明文

```python
# 加密
❯ py3 main.py 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编码的字节流作为密文

##### 如果解密出来的明文直接可以以字符串方式打印

```python
# 明文本身为 hello,world
❯ py3 main.py 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 ------
```

##### 如果解密出来的密文不能以字符串方式打印

```python
# 明文本身是字节流
❯ py3 main.py 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 ------
```

#### 输入文件作为密文

```python
❯ py3 main.py 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模式

#### 代码层面的预设

代码中,对于加密的明文默认使用固定的上下文数据作为验证数据

```python
        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)
```

#### 对字符串做加解密

```python
# gcm模式加密
❯ py3 main.py 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 编码的字节流做加解密

```python
# 加密
❯ py3 main.py 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 ------


# 解密
❯ py3 main.py 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 ------
```

#### 对文件做加解密

```python
# 加密
❯ py3 main.py 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 ------

# 解密
❯ py3 main.py 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值对解密很重要

```python
# gcm模式正常解密
❯ py3 main.py 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 会报错
❯ py3 main.py 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 会解密失败
❯ py3 main.py 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 模式参数

```python
py3 main.py 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 动作参数

```python
py3 main.py 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 输入参数

##### 字符串超限

```python
# 这里设置最大限制为0MBytes,也就是不允许加密,这里是故意预留的
❯ py3 main.py 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编码数据

```python
# 任意构造的字符串
❯ py3 main.py 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==)
❯ py3 main.py 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 ------
```

##### 文件不可读

```python
# 创建文件并设置为只可root读
sudo touch test_plain
sudo chmod 400 test_plain
# 查看文件
ll test_plain
-r--------  1 root  staff  0 Apr  3 11:29 test_plain

# 使用其他用户运行命令访问
py3 main.py 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 ------
```

##### 文件不可写

```python
# 文件写权限检查失败
py3 main.py 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 参数互斥

```python
❯ py3 main.py 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 ------
```

##### 对文件加密或解密时,必须指定输出的文件名

```python
# 加密不指定输出文件
❯ py3 main.py 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 ------

# 解密不指定输出文件
❯ py3 main.py 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验证码

### 支持的命令参数

```python
❯ py3 main.py hmac --help
Usage: main.py hmac [OPTIONS]

Options:
  -i, --input-data TEXT           输入数据,允许输入:字符串、 base64 编码数据、文件路径  [required]
  -e, --is-base64-encoded         如果 -i/--input-data 的值被 base64 编码过,则需要带上 -e
                                  参数,-e 与 -f 互斥  [default: False]
  -f, --is-a-file                 如果 -i/--input-data 的值是一个文件,则需要带上 -f
                                  参数表示当前需要被处理的是一个文件,-e 与 -f 互斥
  -h, --hash-alg [sha224|sha256|sha384|sha512|sha3_224|sha3_256|sha3_384|sha3_512]
                                  哈希算法  [default: sha256]
  -k, --key TEXT                  key 默认值为 32 字节,即 256 位,只允许输入可见字符  [default:
                                  kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk]
  -r, --random-key                是否自动生成随机的密钥,如果自动生成随机密钥则默认 32 字节长度
  --help                          Show this message and exit.
```

### 关于输入数据和密钥的预设

-   输入数据支持三种方式:字符串明文、base64 编码的字节流、文件
-   密钥默认 32 字节,支持生成随机密钥(长度强制为 32 字节)

### 指定密钥

#### 使用默认密钥

```python
❯ py3 main.py hmac -i hello,world

------ 1daa56484b0a4733 begin@2024-04-04_15:41:52.566 ------
data size:11Bytes
key:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
hmac:dcd5f3d53661434856c4fb1f76072a22c5fb2526bfd8713aa5041cc43aab7675
------ 1daa56484b0a4733 took 0.029 milli-seconds to execute ------
```

#### 自己指定密钥

```python
❯ py3 main.py hmac -i hello,world -k 1234

------ 990d2a043f6fb90a begin@2024-04-04_15:42:03.420 ------
data size:11Bytes
key:1234
hmac:96dd6f73018a6d1911d77a906bc41a6aaae760331eb367ca7134a6b85dbbfdcb
------ 990d2a043f6fb90a took 0.025 milli-seconds to execute ------
```

#### 生成随机密钥

```python
❯ py3 main.py hmac -i hello,world -r

------ 8acd4791042aae7c begin@2024-04-04_15:42:14.518 ------
data size:11Bytes
key:6+98I^y4IsiGGj0p!(1^O+iuoH%CO!s5
hmac:f8f9931c074fd30c9fe60c31beb87600bfd3b51960e91f34d765d339aa9981f8
------ 8acd4791042aae7c took 0.057 milli-seconds to execute ------
```

### 指定输入

#### 输入字符串

```python
❯ py3 main.py hmac -i hello,world

------ 7ad6f172e3498e2a begin@2024-04-04_15:42:33.801 ------
data size:11Bytes
key:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
hmac:dcd5f3d53661434856c4fb1f76072a22c5fb2526bfd8713aa5041cc43aab7675
------ 7ad6f172e3498e2a took 0.028 milli-seconds to execute ------
```

#### 输入 base64 编码的字节流

```python
❯ py3 main.py hmac -i krJchuyaDRYHnu5tsy8UzA== -e

------ 7f8694414df48f4e begin@2024-04-04_15:42:46.859 ------
data size:16Bytes
key:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
hmac:276e565d1e8a65b38463e124c45c60b00e01a8a623995aae360d1035e0d58923
------ 7f8694414df48f4e took 0.035 milli-seconds to execute ------
```

#### 输入文件

```python
❯ py3 main.py hmac -i ./test_data/test_plain.txt -f

------ d9f4d5072cc8d6ee begin@2024-04-04_15:42:57.326 ------
file size:64Bytes
key:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
hmac:5b0ea206c45019e090246cea031ca3a267bab15d39bd53491272473aef75d8b0
------ d9f4d5072cc8d6ee took 0.102 milli-seconds to execute ------

```

### 指定哈希算法

```python
# 支持的 hash 列表:
# [sha224 | sha256 | sha384 | sha512 | sha3_224 | sha3_256 | sha3_384 | sha3_512]

# 使用 sha512
❯ py3 main.py hmac -i ./test_data/test_plain.txt -f -h sha512

------ 440b99b2f7479972 begin@2024-04-04_15:43:10.055 ------
file size:64Bytes
key:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
hmac:3c41a94f15c6517e5774d0878268e33c12d9170136c8d9c972f9294324aca61ee2bc4e0f1c7b4a59525ba40f3ccf7b94ebb1de74881ae85023a187e8c1626e1b
------ 440b99b2f7479972 took 0.107 milli-seconds to execute ------

# 使用sha3_256
❯ py3 main.py hmac -i ./test_data/test_plain.txt -f -h sha3_256

------ c48755f9b49e99b3 begin@2024-04-04_15:43:23.256 ------
file size:64Bytes
key:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
hmac:25494b6effa8df3ad1bff777892e08ceccf3fbaa181608d006400b8da3fef853
------ c48755f9b49e99b3 took 0.087 milli-seconds to execute ------
```

## RSA非对称密钥

### 支持的命令

```python
❯ py3 main.py rsa --help
Usage: main.py rsa [OPTIONS] COMMAND [ARGS]...

Options:
  --help  Show this message and exit.

Commands:
  decrypt
  encrypt
  generate
  sign
  verify
```

### 生成密钥对

#### 支持的参数

```python
❯ py3 main.py 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.
```

#### 默认生成

``` python
# 密钥长度2048位,私钥不带密码
❯ py3 main.py 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 ------
```

#### 指定长度且指定密码

```python
# pem格式密钥,私钥不带密码
❯ py3 main.py 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格式密钥,私钥带密码
❯ py3 main.py 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格式密钥,私钥不带密码
❯ py3 main.py 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格式密钥,私钥带密码
❯ py3 main.py 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 ------

```

#### 指定长度且随机生成密码

```python
❯ py3 main.py 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 ------
```

#### 

### 加密与解密

#### 支持的参数

```python
# 加密
❯ py3 main.py 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.

 # 解密
 ❯ py3 main.py 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 密钥对加解密

##### 私钥不需要密码

```python
# 加密
❯ py3 main.py 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 ------

# 解密
❯ py3 main.py 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 ------
```

##### 私钥需要密码

```python
# 加密
❯ py3 main.py 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 指定密码
❯ py3 main.py 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 密钥对加解密

##### 私钥不需要密码

```python
# 加密
❯ py3 main.py 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 ------


# 解密
❯ py3 main.py 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 ------
```

##### 私钥需要密码

```python
# 加密
❯ py3 main.py 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 指定密码
❯ py3 main.py 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 编码的字节流做加解密

```python
# 加密
❯ py3 main.py 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 指定密码
❯ py3 main.py 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模式

```python
# 加密
❯ py3 main.py 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 ------

# 解密
❯ py3 main.py 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 模式

```python
# 加密
❯ py3 main.py 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 ------

# 解密
❯ py3 main.py 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 ------
```



### 签名与验签

#### 支持的参数

```python
# 签名
❯ py3 main.py 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.

# 验签
❯ py3 main.py 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模式

```python
# 签名 -p 指定密码
❯ py3 main.py 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 ------

# 验签
❯ py3 main.py 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模式

```python
# 签名 -p 指定密码
❯ py3 main.py 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 ------

# 验签
❯ py3 main.py 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椭圆曲线

### 支持的命令

```
❯ py3 main.py ecc --help
Usage: main.py ecc [OPTIONS] COMMAND [ARGS]...

Options:
  --help  Show this message and exit.

Commands:
  ecdh
  generate
  sign
  verify
```

### 生成密钥对

```python
❯ py3 main.py 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.
```

#### 默认生成

```python
❯ py3 main.py 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 ------
```

#### 指定椭圆曲线且指定密码

```python
❯ py3 main.py 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 ------
```

#### 指定椭圆曲线且随机生成密码

```python
❯ py3 main.py 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密钥交换

#### 支持的参数

```python
❯ py3 main.py 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 的密钥对

```python
❯ py3 main.py 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 ------

❯ py3 main.py 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 共享的对称密钥

```python
❯ py3 main.py 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共享的对称密钥

```python
❯ py3 main.py 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 ------
```

### 签名与验签

#### 支持的参数

```python
# 签名
❯ py3 main.py 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.

# 验签
❯ py3 main.py 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.
```

#### 生成密钥对

```python
❯ py3 main.py 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 ------
```

#### 签名

```python
❯ py3 main.py 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 ------
```

#### 验签

```python
❯ py3 main.py 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 ------
```


            

Raw data

            {
    "_id": null,
    "home_page": "https://cloud.tencent.com/developer/article/2155922",
    "name": "encryption-tool",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "encryption cli tool security aes hmac ecc rsa",
    "author": "bowenerchen",
    "author_email": "your-email@example.com",
    "download_url": null,
    "platform": null,
    "description": "# \u52a0\u5bc6\u5de5\u5177\u529f\u80fd\u6d4b\u8bd5\u548c\u4f7f\u7528\u8bf4\u660e\n\n## \u5de5\u5177\u652f\u6301\u7684\u547d\u4ee4\n\n\u672c\u6587\u4e2d\u9ed8\u8ba4\u5c06 python3 \u7b80\u5199\u4e3a py3\u3002\n\n```python\n\u276f py3 main.py --help\n\nUsage: main.py [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --help  Show this message and exit.\n\nCommands:\n  aes         aes encryption && decryption tool\n  ecc         ecc encryption && decryption && sign && verify tool\n  hmac        hmac tool\n  random-str  random string tool\n  rsa         rsa encryption && decryption && sign && verify tool\n  version     show version\n```\n\n## \u663e\u793a\u7248\u672c\n\n```python\n# \u5c55\u793a\u7248\u672c\u4fe1\u606f\uff0c\u5305\u62ec\uff1a\n# \u5de5\u5177\u7248\u672c\n# python\u89e3\u91ca\u5668\u7248\u672c\n# \u64cd\u4f5c\u7cfb\u7edf\n# cpu\n# \u5b57\u8282\u5e8f\n# \u4f5c\u8005\u4fe1\u606f\n\u276f py3 main.py version\n\n------ 7906e795524f2b7c begin@2024-04-04_15:02:59.590 ------\ntool-version:v1.0.0\npython:3.11.4 (main, Jul  5 2023, 08:54:11) [Clang 14.0.6 ]\nos:darwin\nchip:macOS-14.3.1-arm64-arm-64bit\nbyte-order:little\n------ 7906e795524f2b7c took 0.007 milli-seconds to execute ------\n\n```\n\n## \u751f\u6210\u968f\u673a\u5b57\u7b26\u4e32\n\n### \u652f\u6301\u7684\u53c2\u6570\n\n```python\n\u276f py3 main.py random-str --help\nUsage: main.py random-str [OPTIONS]\n\nOptions:\n  -l, --length INTEGER RANGE  \u6700\u5c0f\u751f\u6210\u4e00\u4e2a\u5b57\u8282\u5b57\u7b26\u4e32\uff0c\u6700\u5927\u957f\u5ea6\u7531\u7cfb\u7edf\u6700\u5927\u6574\u578b\u503c\u51b3\u5b9a  [default: 32;\n                              1<=x<=9223372036854775807]\n  -o, --output-file TEXT      \u6307\u5b9a\u8f93\u51fa\u7684\u6587\u4ef6\uff0c\u6587\u4ef6\u9700\u8981\u5177\u6709\u53ef\u5199\u6743\u9650\n  --help                      Show this message and exit.\n```\n\n### \u76f4\u63a5\u8f93\u51fa\u5230 stdout\n\n```python\n# -l\u6307\u5b9a\u968f\u673a\u5b57\u7b26\u4e32\u7684\u957f\u5ea6\u4e3a32\u5b57\u8282\n\u276f py3 main.py random-str -l 32\n\n------ 632aebf88dfe8f93 begin@2024-04-04_15:01:23.987 ------\nqBg@G%Tp((@2h81tg@9II7#0Su4`B06$\n------ 632aebf88dfe8f93 took 0.049 milli-seconds to execute ------\n```\n\n### \u8f93\u51fa\u5230\u6587\u4ef6\n\n```python\n\u276f py3 main.py random-str -l 37 -o test_random\n\n------ 71a2d32b0816349f begin@2024-04-04_15:24:22.476 ------\nwrite to test_random success\n------ 71a2d32b0816349f took 0.299 milli-seconds to execute ------\n\n\u276f cat test_random\n_9@mL1`D2#NZz5m@!X7sdHKqQEowM6%o3E`bj\n```\n\n### \u5f53\u6307\u5b9a\u7684\u6587\u4ef6\u4e0d\u53ef\u5199\u65f6\n\n```python\n\u276f py3 main.py random-str -l 37 -o test_random\n\n------ 0e4094ce6a4fe22c begin@2024-04-04_15:25:49.125 ------\ntry write to test_random failed\n------ 0e4094ce6a4fe22c took 0.030 milli-seconds to execute ------\n\n```\n\n## AES\u5bf9\u79f0\u52a0\u5bc6\u7b97\u6cd5\n\n### \u652f\u6301\u7684\u547d\u4ee4\u53c2\u6570\n\n```python\n\u276f py3 main.py aes --help\nUsage: main.py aes [OPTIONS]\n\nOptions:\n  -m, --mode [cbc|gcm]            aes mode\uff0c\u9ed8\u8ba4\u4e3a cbc \u6a21\u5f0f\uff0c\u53ef\u9009 cbc \u6216 gcm \u6a21\u5f0f\n                                  [default: cbc]\n  -k, --key TEXT                  key \u9ed8\u8ba4 32 \u5b57\u8282\uff0c\u5373 256 \u4f4d\uff0c\u53ea\u5141\u8bb8\u8f93\u5165\u53ef\u89c1\u5b57\u7b26,\n                                  \u957f\u5ea6\u4e0d\u591f\u5219\u81ea\u52a8\u8865\u9f50\uff0c\u957f\u5ea6\u8d85\u51fa\u5219\u81ea\u52a8\u622a\u53d6  [default:\n                                  kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk]\n  -v, --iv-nonce TEXT             cbc \u6a21\u5f0f\u4e0b\uff0civ \u9ed8\u8ba4 16 \u5b57\u8282\u5373 128 \u4f4d\uff0cgcm \u6a21\u5f0f\u4e0b nonce \u9ed8\u8ba4\n                                  12 \u5b57\u8282\u5373 96 \u4f4d\uff0c\u957f\u5ea6\u4e0d\u591f\u5219\u81ea\u52a8\u8865\u9f50\uff0c\u957f\u5ea6\u8d85\u51fa\u5219\u81ea\u52a8\u622a\u53d6  [default:\n                                  vvvvvvvvvvvvvvvv]\n  -r, --random-key-iv             \u662f\u5426\u81ea\u52a8\u751f\u6210\u968f\u673a\u7684\u5bc6\u94a5\u548c iv/nonce\uff0c\u5982\u679c\u968f\u673a\u751f\u6210\uff0c\u5219\u5bc6\u94a5\u957f\u5ea6\u9ed8\u8ba4 32\n                                  \u5b57\u8282\uff0civ \u9ed8\u8ba4\u4e3a 16 \u5b57\u8282\uff0c nonce \u9ed8\u8ba4\u4e3a 12 \u5b57\u8282\n  -a, --action [encrypt|decrypt]  \u52a0\u5bc6\uff08encrypt\uff09\u6216 \u89e3\u5bc6\uff08decrypt\uff09\uff0c\u52a0\u5bc6\u540e\u8f93\u51fa base64 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\n                                  [default: encrypt]\n  -i, --input-data TEXT           \u8f93\u5165\u6570\u636e\uff0c\u5373\u88ab\u52a0\u5bc6\u6216\u89e3\u5bc6\u7684\u6570\u636e\uff0c\u52a0\u5bc6\u65f6\u5141\u8bb8\u8f93\u5165\uff1a\u5b57\u7b26\u4e32\u3001 base64\n                                  \u7f16\u7801\u6570\u636e\u3001\u6587\u4ef6\u8def\u5f84\uff0c\u89e3\u5bc6\u65f6\u5141\u8bb8\u8f93\u5165\uff1abase64 \u7f16\u7801\u6570\u636e\u3001\u6587\u4ef6\u8def\u5f84\n                                  [required]\n  -e, --is-base64-encoded         \u5982\u679c -i/--input-data \u7684\u503c\u88ab base64 \u7f16\u7801\u8fc7\uff0c\u5219\u9700\u8981\u5e26\u4e0a -e\n                                  \u53c2\u6570\uff0c-e \u4e0e -f \u4e92\u65a5  [default: False]\n  -f, --is-a-file                 \u5982\u679c -i/--input-data \u7684\u503c\u662f\u4e00\u4e2a\u6587\u4ef6\uff0c\u5219\u9700\u8981\u5e26\u4e0a -f\n                                  \u53c2\u6570\u8868\u793a\u5f53\u524d\u9700\u8981\u88ab\u5904\u7406\u7684\u662f\u4e00\u4e2a\u6587\u4ef6\uff0c-e \u4e0e -f \u4e92\u65a5\n  -l, --input-limit INTEGER       \u8f93\u5165\u5185\u5bb9\u6700\u5927\u957f\u5ea6\uff0c\u5355\u4f4d\u4e3a MB\uff0c\u9ed8\u8ba4\u4e3a 1MB\uff0c\u5728 -i \u4e3a\u975e\u6587\u4ef6\u65f6\u751f\u6548\n                                  [default: 1]\n  -o, --output-file TEXT          \u6307\u5b9a\u8f93\u51fa\u6587\u4ef6\uff0c\u5f53\u8f93\u5165\u65f6\u6307\u5b9a\u4e86\u6587\u4ef6\uff0c\u5219\u8f93\u51fa\u65f6\u5fc5\u987b\u6307\u5b9a\n  -t, --gcm-tag TEXT              gcm \u6a21\u5f0f\u89e3\u5bc6\u65f6\uff0c\u5219\u6b64\u53c2\u6570\u5fc5\u586b\n  --help                          Show this message and exit.\n```\n\n### \u5173\u4e8e\u5bc6\u94a5\u3001IV\u548c\u6a21\u5f0f\u7684\u9884\u8bbe\n\n-   \u52a0\u5bc6\u6a21\u5f0f\uff1a\u4ec5\u652f\u6301 CBC \u6a21\u5f0f\u548c GCM \u6a21\u5f0f\uff0c\u52a0\u5bc6\u65f6\u5f3a\u5236\u6309\u7167 PKCS#7 \u89c4\u5219\u8fdb\u884c\u6570\u636e\u586b\u5145\uff08Padding\uff09\n-   \u5bc6\u94a5\uff1a\u9ed8\u8ba4 32 \u5b57\u8282\uff0c\u5373 256 \u4f4d\uff0c\u4e0d\u8db3\u4f1a\u81ea\u52a8\u8865\u9f50\uff0c\u8d85\u8fc7\u4f1a\u81ea\u52a8\u622a\u53d6\n-   IV\uff1aCBC \u6a21\u5f0f\u4e0b\u65f6 IV \u957f\u5ea6\u9ed8\u8ba4 16 \u5b57\u8282\uff0cGCM \u6a21\u5f0f\u4e0b Nonce \u957f\u5ea6\u9ed8\u8ba4 12 \u5b57\u8282\uff08\u5176\u4e2d 4 \u5b57\u8282\u9884\u7559\u4f5c\u4e3a\u8ba1\u6570\u5668\uff0c\u7531\u7b97\u6cd5\u81ea\u884c\u5904\u7406\uff09\n\n### \u5173\u4e8e\u8f93\u5165\u6570\u636e\u7684\u9884\u8bbe\n\n\u52a0\u5bc6\u884c\u4e3a\u652f\u6301\u4e09\u79cd\u6570\u636e\u8f93\u5165\u65b9\u5f0f\uff1a\n\n-   \u5b57\u7b26\u4e32\u5982\uff1ahello,world\n-   Base64 \u7f16\u7801\u7684\u5b57\u8282\u6d41\u5982\uff1aaGVsbG8sd29ybGQK\uff08\u751f\u6210\u7684 shell \u547d\u4ee4\uff1aecho \"hello,world\"|base64\uff09\n-   \u6587\u4ef6\u540d\u8def\u5f84\uff1a~/data/test_plain.txt\n\n\u89e3\u5bc6\u884c\u4e3a\u652f\u6301\u4e24\u79cd\u6570\u636e\u8f93\u5165\u65b9\u5f0f\uff1a\n\n-   Base64 \u7f16\u7801\u7684\u5b57\u8282\u6d41\u5982\uff1a/hEP3J5KHZgNnCeBD/W5MQ==\n-   \u6587\u4ef6\u540d\u8def\u5f84\uff1a~/data/test_cipher.bin\n\n### \u6307\u5b9a\u5bc6\u94a5\u548c IV\n\n#### \u4f7f\u7528\u9ed8\u8ba4\u7684\u5bc6\u94a5\n\n```shell\n# \u52a0\u5bc6hello,world\uff0c\u5bc6\u94a5\u548c iv \u5747\u4e3a\u9ed8\u8ba4\u6570\u636e\n\u276f py3 main.py aes -m cbc -a encrypt -i hello,world\n\n------ 15ec713c1b8c0ef3 begin@2024-04-04_15:29:25.203 ------\nplain size:11\nkey:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\niv:vvvvvvvvvvvvvvvv\ncipher size:16\ncipher:PcgHm88aPtUjwVx+SDvMqw==\nauth_tag_size:0\nauth_tag:\n------ 15ec713c1b8c0ef3 took 26.874 milli-seconds to execute ------\n\n# \u89e3\u5bc6hello,world\n\u276f py3 main.py aes -m cbc -a decrypt -i PcgHm88aPtUjwVx+SDvMqw== -e\n\n------ fb11b7f46716698e begin@2024-04-04_15:29:40.648 ------\ncipher size:16\nplain size:11\nstr plain:hello,world\n------ fb11b7f46716698e took 13.754 milli-seconds to execute ------\n```\n\n#### \u4f7f\u7528\u968f\u673a\u751f\u6210\u7684\u5bc6\u94a5\n\n```python\n# \u52a0\u5bc6 -r \u8868\u793a\u968f\u673a\u751f\u6210\u5bc6\u94a5\u548c IV\n\u276f py3 main.py aes -m cbc -a encrypt -i hello,world -r\n\n------ d39dbe0c997a868b begin@2024-04-04_15:29:54.358 ------\nplain size:11\nkey:Ta9M^p)+L1+_L^26!Xmcs6AR2^3p_5FY\niv:9*H`JW(dzpi5HBd0\ncipher size:16\ncipher:h7lMpOimKxO0zr7AMVsI9w==\nauth_tag_size:0\nauth_tag:\n------ d39dbe0c997a868b took 14.258 milli-seconds to execute ------\n\n# \u89e3\u5bc6\n# -k \u548c -v \u7684\u503c\u4f7f\u7528\u5f15\u53f7\u662f\u4e3a\u4e86\u9884\u9632\u91cc\u9762\u5e26\u6709\u7279\u6b8a shell \u547d\u4ee4\u7684\u5b57\u7b26\u6bd4\u5982\u2018&\u2019\u3001\u2018!\u2019\u7b49\u7b49\n\u276f py3 main.py aes -m cbc -a decrypt -i h7lMpOimKxO0zr7AMVsI9w== -e -k 'Ta9M^p)+L1+_L^26!Xmcs6AR2^3p_5FY' -v '9*H`JW(dzpi5HBd0'\n\n------ 1332e834884e2b0e begin@2024-04-04_15:31:06.666 ------\ncipher size:16\nplain size:11\nstr plain:hello,world\n------ 1332e834884e2b0e took 15.691 milli-seconds to execute ------\n```\n\n#### \u4f7f\u7528\u6307\u5b9a\u7684\u5bc6\u94a5\n\n##### \u5bc6\u94a5\u6216 iv \u957f\u5ea6\u4e0d\u591f\u65f6\u4f1a\u81ea\u52a8\u586b\u5145\n\n```python\n# \u52a0\u5bc6\uff0c\u6b64\u65f6 key(1234) \u548c iv(1234) \u957f\u5ea6\u90fd\u4e0d\u8db3\n\u276f py3 main.py aes -m cbc -a encrypt -i hello,world -k 1234 -v 4321\n\n------ c5abaa3af64a5f6c begin@2024-04-04_15:31:34.231 ------\nplain size:11\nkey:1234g6Z0GE$Z@ybb^IIb3FN5Ux%BE=00\niv:4321nJ4j*Nud(yH4\ncipher size:16\ncipher:dHJKRtSi8KsCe6ZFltF0kA==\nauth_tag_size:0\nauth_tag:\n------ c5abaa3af64a5f6c took 14.648 milli-seconds to execute ------\n                \n# \u89e3\u5bc6\n\u276f py3 main.py aes -m cbc -a decrypt -i dHJKRtSi8KsCe6ZFltF0kA== -e -k '1234g6Z0GE$Z@ybb^IIb3FN5Ux%BE=00' -v '4321nJ4j*Nud(yH4'\n\n------ 7c2018bd08e58a63 begin@2024-04-04_15:32:16.014 ------\ncipher size:16\nplain size:11\nstr plain:hello,world\n------ 7c2018bd08e58a63 took 14.343 milli-seconds to execute ------\n```\n\n##### \u5bc6\u94a5\u6216iv\u8d85\u957f\u65f6\u4f1a\u81ea\u52a8\u622a\u53d6\n\n```python\n# \u52a0\u5bc6\uff0c\u6b64\u65f6\u5bc6\u94a5\u548c iv \u7684\u957f\u5ea6\u90fd\u8d85\u957f\n\u276f py3 main.py aes -m cbc -a encrypt -i hello,world -k 12345678901234567890123456789012abcde -v 1234567890123456abcde\n\n------ 8ff4bd52df0a0865 begin@2024-04-04_15:32:31.104 ------\nplain size:11\nkey:12345678901234567890123456789012\niv:1234567890123456\ncipher size:16\ncipher:wOXlD3Ie7xiQh81aR8N1tQ==\nauth_tag_size:0\nauth_tag:\n------ 8ff4bd52df0a0865 took 13.849 milli-seconds to execute ------\n\n# \u89e3\u5bc6\n\u276f py3 main.py aes -m cbc -a decrypt -i wOXlD3Ie7xiQh81aR8N1tQ== -e -k 12345678901234567890123456789012 -v 1234567890123456\n\n------ 50ea907cc74207ad begin@2024-04-04_15:32:46.937 ------\ncipher size:16\nplain size:11\nstr plain:hello,world\n------ 50ea907cc74207ad took 13.690 milli-seconds to execute ------\n```\n\n### \u6307\u5b9a\u660e\u6587\n\n#### \u8f93\u5165\u5b57\u7b26\u4e32\u4f5c\u4e3a\u660e\u6587\n\n```python\n# \u52a0\u5bc6\n\u276f py3 main.py aes -m cbc -a encrypt -i hello,world\n\n------ e6dc33dc9ca747d0 begin@2024-04-04_15:33:05.505 ------\nplain size:11\nkey:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\niv:vvvvvvvvvvvvvvvv\ncipher size:16\ncipher:PcgHm88aPtUjwVx+SDvMqw==\nauth_tag_size:0\nauth_tag:\n------ e6dc33dc9ca747d0 took 14.098 milli-seconds to execute ------\n```\n\n#### \u8f93\u5165base64\u7f16\u7801\u7684\u5b57\u8282\u6d41\u4f5c\u4e3a\u660e\u6587\n\n```python\n# \u52a0\u5bc6 -e \u8868\u660e\u8f93\u5165\u7684\u6570\u636e\u7ecf\u8fc7\u4e86 base64 \u7f16\u7801\uff0c\u52a0\u5bc6\u6216\u89e3\u5bc6\u65f6\u9700\u8981\u5148\u5c06\u6570\u636e\u505a base64 \u89e3\u7801\n\u276f py3 main.py aes -m cbc -a encrypt -i 9H8InkmnUjgVHC8elQxThUSmzkO0tuGlP0Si4X1kmoK7azOIDoFnt8dXjeWNGb+dc7qiEBPi+jymax4i+24KBQ== -e\n\n------ fc5b00c0a79ff88e begin@2024-04-04_15:33:17.585 ------\nplain size:64\nkey:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\niv:vvvvvvvvvvvvvvvv\ncipher size:80\ncipher:ZHq7uJQjkx/2Bm5ZmrcuS/5c/s/qayDVcuWZmvsTle1RAUKyv0dvGhOVYEINmL35eSMVoT3Bx/M6lU9NGCuiM5OxyJ2VcuB30dp8GVZg0oQ=\nauth_tag_size:0\nauth_tag:\n------ fc5b00c0a79ff88e took 14.382 milli-seconds to execute ------\n```\n\n#### \u8f93\u5165\u6587\u4ef6\u4f5c\u4e3a\u660e\u6587\n\n```python\n# \u52a0\u5bc6\n\u276f py3 main.py aes -m cbc -a encrypt -i ./test_data/test_plain.txt -f -o ./tmp_cipher.bin\n\n------ 1d5fb25a63f1ed4d begin@2024-04-04_15:33:57.461 ------\ninput file size:64\ncipher size:80\nkey:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\niv:vvvvvvvvvvvvvvvv\nauth_tag_size:0\nauth_tag:\n------ 1d5fb25a63f1ed4d took 14.859 milli-seconds to execute ------\n\n# \u67e5\u770b\u6587\u4ef6\u5927\u5c0f\uff0c\u5bc6\u6587\u6587\u4ef6\u6bd4\u660e\u6587\u6587\u4ef6\u591a\u4e8616 \u5b57\u8282\uff0c\u8fd9\u662f\u56e0\u4e3a\u660e\u6587\u7684\u6700\u540e\u4e00\u4e2a block \u4f1a\u505a PKCS#7 \u6570\u636e\u586b\u5145\n\u276f cat ./test_data/test_plain.txt\n123456789012345612345678901234561234567890123456123456789012345\n\u276f ll ./test_data/test_plain.txt\n-rw-r--r--  1 xxxx  staff  64 Apr  2 21:06 ./test_data/test_plain.txt\n\u276f ll ./tmp_cipher.bin\n-rw-r--r--  1 xxxx  staff  80 Apr  4 15:33 ./tmp_cipher.bin\n```\n\n### \u6307\u5b9a\u5bc6\u6587\n\n#### \u8f93\u5165base64\u7f16\u7801\u7684\u5b57\u8282\u6d41\u4f5c\u4e3a\u5bc6\u6587\n\n##### \u5982\u679c\u89e3\u5bc6\u51fa\u6765\u7684\u660e\u6587\u76f4\u63a5\u53ef\u4ee5\u4ee5\u5b57\u7b26\u4e32\u65b9\u5f0f\u6253\u5370\n\n```python\n# \u660e\u6587\u672c\u8eab\u4e3a hello,world\n\u276f py3 main.py aes -m cbc -a decrypt -i PcgHm88aPtUjwVx+SDvMqw== -e\n\n------ 2b6a86223a0ba102 begin@2024-04-04_15:35:26.995 ------\ncipher size:16\nplain size:11\nstr plain:hello,world\n------ 2b6a86223a0ba102 took 13.676 milli-seconds to execute ------\n```\n\n##### \u5982\u679c\u89e3\u5bc6\u51fa\u6765\u7684\u5bc6\u6587\u4e0d\u80fd\u4ee5\u5b57\u7b26\u4e32\u65b9\u5f0f\u6253\u5370\n\n```python\n# \u660e\u6587\u672c\u8eab\u662f\u5b57\u8282\u6d41\n\u276f py3 main.py aes -m cbc -a decrypt -i ZHq7uJQjkx/2Bm5ZmrcuS/5c/s/qayDVcuWZmvsTle1RAUKyv0dvGhOVYEINmL35eSMVoT3Bx/M6lU9NGCuiM5OxyJ2VcuB30dp8GVZg0oQ= -e\n\n------ d399aa241aa6b691 begin@2024-04-04_15:35:39.781 ------\ncipher size:80\nplain size:64\nb64 encoded plain:9H8InkmnUjgVHC8elQxThUSmzkO0tuGlP0Si4X1kmoK7azOIDoFnt8dXjeWNGb+dc7qiEBPi+jymax4i+24KBQ==\n------ d399aa241aa6b691 took 13.869 milli-seconds to execute ------\n```\n\n#### \u8f93\u5165\u6587\u4ef6\u4f5c\u4e3a\u5bc6\u6587\n\n```python\n\u276f py3 main.py aes -m cbc -a decrypt -i ./tmp_cipher.bin -f -o ./tmp_plain.txt\n\n------ 1f27fb444d1139b2 begin@2024-04-04_15:36:03.267 ------\ninput file size:80\ndecrypt ./tmp_cipher.bin success\nwrite to ./tmp_plain.txt\nplain size:64\n------ 1f27fb444d1139b2 took 14.259 milli-seconds to execute ------\n\n# \u6587\u4ef6\u5927\u5c0f\u4e00\u81f4\u3001\u5185\u5bb9\u4e00\u81f4\n\u276f ll ./tmp_plain.txt ./test_data/test_plain.txt\n-rw-r--r--  1 xxxx  staff  64 Apr  2 21:06 ./test_data/test_plain.txt\n-rw-r--r--  1 xxxx  staff  64 Apr  3 10:58 ./tmp_plain.txt\n\u276f cat tmp_plain.txt ./test_data/test_plain.txt\n123456789012345612345678901234561234567890123456123456789012345\n123456789012345612345678901234561234567890123456123456789012345\n```\n\n### \u4f7f\u7528GCM\u6a21\u5f0f\n\n#### \u4ee3\u7801\u5c42\u9762\u7684\u9884\u8bbe\n\n\u4ee3\u7801\u4e2d\uff0c\u5bf9\u4e8e\u52a0\u5bc6\u7684\u660e\u6587\u9ed8\u8ba4\u4f7f\u7528\u56fa\u5b9a\u7684\u4e0a\u4e0b\u6587\u6570\u636e\u4f5c\u4e3a\u9a8c\u8bc1\u6570\u636e\n\n```python\n        if mode == aes_gcm_mode:\n            self.__auth_data = json.dumps({\n                'mode': mode, # \u503c\u4e3a gcm\n                'obj': 'aes_operator',\n            }).encode(encoding = 'utf-8')\n            if action == aes_encrypt_action:\n                self.__aes_gcm_obj = Cipher(algorithms.AES(self.__key), modes.GCM(self.__iv), backend = default_backend())\n                self.__aes_gcm_enc_op = self.__aes_gcm_obj.encryptor()\n                self.__aes_gcm_enc_op.authenticate_additional_data(self.__auth_data)\n```\n\n#### \u5bf9\u5b57\u7b26\u4e32\u505a\u52a0\u89e3\u5bc6\n\n```python\n# gcm\u6a21\u5f0f\u52a0\u5bc6\n\u276f py3 main.py aes -m gcm -a encrypt -i hello,world\n\n------ b8e914a4634acde7 begin@2024-04-04_15:36:39.558 ------\nplain size:11\nkey:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\niv:vvvvvvvvvvvv\ncipher size:16\ncipher:TajM7IwxIZIoqHkU87dY7w==\nauth_tag_size:16\nauth_tag:df8z3ccRyGOQTluw26dIlA==\n------ b8e914a4634acde7 took 14.280 milli-seconds to execute ------\n```\n\n#### \u5bf9 base64 \u7f16\u7801\u7684\u5b57\u8282\u6d41\u505a\u52a0\u89e3\u5bc6\n\n```python\n# \u52a0\u5bc6\n\u276f py3 main.py aes -m gcm -a encrypt -i 9H8InkmnUjgVHC8elQxThUSmzkO0tuGlP0Si4X1kmoK7azOIDoFnt8dXjeWNGb+dc7qiEBPi+jymax4i+24KBQ== -e\n\n------ 7781b5bffdcef12b begin@2024-04-04_15:37:05.562 ------\nplain size:64\nkey:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\niv:vvvvvvvvvvvv\ncipher size:80\ncipher:0bKoHqq6BMVP2DIPY74Ob2tGi69gVzHSZREJT3DAeCsVU52ykLcfKZIq/GD2PEkCwLLE8o37nvPK9t/pr4LStVy5unAN/EVllIvvopq2pis=\nauth_tag_size:16\nauth_tag:B1Jp0FuxyNXAOVAvj9S+Ow==\n------ 7781b5bffdcef12b took 13.915 milli-seconds to execute ------\n\n\n# \u89e3\u5bc6\n\u276f py3 main.py aes -m gcm -a decrypt -i 0bKoHqq6BMVP2DIPY74Ob2tGi69gVzHSZREJT3DAeCsVU52ykLcfKZIq/GD2PEkCwLLE8o37nvPK9t/pr4LStVy5unAN/EVllIvvopq2pis= -e -t B1Jp0FuxyNXAOVAvj9S+Ow==\n\n------ 5bcc82c4235dcde4 begin@2024-04-04_15:37:17.397 ------\ncipher size:80\nplain size:64\nb64 encoded plain:9H8InkmnUjgVHC8elQxThUSmzkO0tuGlP0Si4X1kmoK7azOIDoFnt8dXjeWNGb+dc7qiEBPi+jymax4i+24KBQ==\n------ 5bcc82c4235dcde4 took 13.844 milli-seconds to execute ------\n```\n\n#### \u5bf9\u6587\u4ef6\u505a\u52a0\u89e3\u5bc6\n\n```python\n# \u52a0\u5bc6\n\u276f py3 main.py aes -m gcm -a encrypt -i ./test_data/test_plain.txt -f -o ./tmp_gcm_cipher.bin\n\n------ 0c4605fe37eb7e4b begin@2024-04-04_15:37:45.621 ------\ninput file size:64\ncipher size:80\nkey:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\niv:vvvvvvvvvvvv\nauth_tag_size:16\nauth_tag:krJchuyaDRYHnu5tsy8UzA==\n------ 0c4605fe37eb7e4b took 14.347 milli-seconds to execute ------\n\n# \u89e3\u5bc6\n\u276f py3 main.py aes -m gcm -a decrypt -i ./tmp_gcm_cipher.bin -f -o tmp_gcm_plain.txt -t krJchuyaDRYHnu5tsy8UzA==\n\n------ d181cab086ebaeaa begin@2024-04-04_15:38:00.709 ------\ninput file size:80\ndecrypt ./tmp_gcm_cipher.bin success\nwrite to tmp_gcm_plain.txt\nplain size:64\n------ d181cab086ebaeaa took 14.397 milli-seconds to execute ------\n```\n\n#### tag\u503c\u5bf9\u89e3\u5bc6\u5f88\u91cd\u8981\n\n```python\n# gcm\u6a21\u5f0f\u6b63\u5e38\u89e3\u5bc6\n\u276f py3 main.py aes -m gcm -a decrypt -i TajM7IwxIZIoqHkU87dY7w== -e -t df8z3ccRyGOQTluw26dIlA==\n\n------ 86699527d1227e39 begin@2024-04-04_15:38:22.322 ------\ncipher size:16\nplain size:11\nstr plain:hello,world\n------ 86699527d1227e39 took 13.987 milli-seconds to execute ------\n\n# \u4e0d\u4f20 gcm tag \u4f1a\u62a5\u9519\n\u276f py3 main.py aes -m gcm -a decrypt -i TajM7IwxIZIoqHkU87dY7w== -e\n\n------ 11c1531f0fd5b7a8 begin@2024-04-04_15:38:32.957 ------\nexpected a gcm tag(16 Bytes)\n------ 11c1531f0fd5b7a8 took 0.030 milli-seconds to execute ------\n\n# \u4f20\u9519\u8bef\u7684 tag \u4f1a\u89e3\u5bc6\u5931\u8d25\n\u276f py3 main.py aes -m gcm -a decrypt -i TajM7IwxIZIoqHkU87dY7w== -e -t H7n7OzKgQyHL86zbnQ0r+g==\n\n------ 90580b5c3649a1ba begin@2024-04-04_15:38:46.823 ------\ndecrypt TajM7IwxIZIoqHkU87dY7w== failed:\n------ 90580b5c3649a1ba took 14.030 milli-seconds to execute ------\n\n```\n\n### \u5e38\u7528\u7684\u53c2\u6570\u5408\u6cd5\u6027\u68c0\u67e5\n\n#### -m \u6a21\u5f0f\u53c2\u6570\n\n```python\npy3 main.py aes -m abc -a encrypt -i 1234\nUsage: main.py aes [OPTIONS]\nTry 'main.py aes --help' for help.\n\nError: Invalid value for '-m' / '--mode': 'abc' is not one of 'cbc', 'gcm'.\n```\n\n#### -a \u52a8\u4f5c\u53c2\u6570\n\n```python\npy3 main.py aes -m cbc -a abc -i 1234\nUsage: main.py aes [OPTIONS]\nTry 'main.py aes --help' for help.\n\nError: Invalid value for '-a' / '--action': 'abc' is not one of 'encrypt', 'decrypt'.\n```\n\n#### -i \u8f93\u5165\u53c2\u6570\n\n##### \u5b57\u7b26\u4e32\u8d85\u9650\n\n```python\n# \u8fd9\u91cc\u8bbe\u7f6e\u6700\u5927\u9650\u5236\u4e3a0MBytes\uff0c\u4e5f\u5c31\u662f\u4e0d\u5141\u8bb8\u52a0\u5bc6\uff0c\u8fd9\u91cc\u662f\u6545\u610f\u9884\u7559\u7684\n\u276f py3 main.py aes -m cbc -a encrypt -i 1234 -l 0\n\n------ 5ce766f36cc28968 begin@2024-04-04_15:39:42.675 ------\nthe data exceeds the maximum bytes limit, limited to:0Bytes, now:4Bytes\n------ 5ce766f36cc28968 took 0.023 milli-seconds to execute ------\n```\n\n##### \u975e\u6cd5\u7684base64\u7f16\u7801\u6570\u636e\n\n```python\n# \u4efb\u610f\u6784\u9020\u7684\u5b57\u7b26\u4e32\n\u276f py3 main.py aes -m cbc -a encrypt -i qwert -e\n\n------ 4844fa0e0939482d begin@2024-04-04_15:39:53.597 ------\ninvalid b64 encoded data:qwert\n------ 4844fa0e0939482d took 0.044 milli-seconds to execute ------\n\n# base64\u6570\u636e\u7f3a\u5c11\u5b57\u7b26\uff08\u6b63\u786e\u7684\u662f\uff1aZUD3MJT3ohiimrryNW7jBw==\uff09\n\u276f py3 main.py aes -m cbc -a encrypt -i ZUD3MJT3ohiimrryNW7jBw -e\n\n------ 22301b388db43f9d begin@2024-04-04_15:40:05.092 ------\ninvalid b64 encoded data:ZUD3MJT3ohiimrryNW7jBw\n------ 22301b388db43f9d took 0.036 milli-seconds to execute ------\n```\n\n##### \u6587\u4ef6\u4e0d\u53ef\u8bfb\n\n```python\n# \u521b\u5efa\u6587\u4ef6\u5e76\u8bbe\u7f6e\u4e3a\u53ea\u53efroot\u8bfb\nsudo touch test_plain\nsudo chmod 400 test_plain\n# \u67e5\u770b\u6587\u4ef6\nll test_plain\n-r--------  1 root  staff  0 Apr  3 11:29 test_plain\n\n# \u4f7f\u7528\u5176\u4ed6\u7528\u6237\u8fd0\u884c\u547d\u4ee4\u8bbf\u95ee\npy3 main.py aes -m cbc -a encrypt -i test_plain -f\ntest_plain may not exist or may be unreadable\n------ aes_command took 0.076 milli-seconds to execute ------\n```\n\n##### \u6587\u4ef6\u4e0d\u53ef\u5199\n\n```python\n# \u6587\u4ef6\u5199\u6743\u9650\u68c0\u67e5\u5931\u8d25\npy3 main.py aes -m cbc -a encrypt -i  tmp_gcm_plain.txt -f -o test_plain\n\ntmp_gcm_plain.txt opened in mode rb success\ntest_plain may not exist or may not writable\ntmp_gcm_plain.txt closed success\n------ aes_command took 0.126 milli-seconds to execute ------\n```\n\n##### -e \u4e0e -f \u53c2\u6570\u4e92\u65a5\n\n```python\n\u276f py3 main.py aes -m cbc -a encrypt -i test_plain -f -e\n\n------ 75998f7a4a1364f6 begin@2024-04-04_15:40:30.038 ------\nthe input data cannot be used as both a file and base64 encoded data\n------ 75998f7a4a1364f6 took 0.026 milli-seconds to execute ------\n```\n\n##### \u5bf9\u6587\u4ef6\u52a0\u5bc6\u6216\u89e3\u5bc6\u65f6\uff0c\u5fc5\u987b\u6307\u5b9a\u8f93\u51fa\u7684\u6587\u4ef6\u540d\n\n```python\n# \u52a0\u5bc6\u4e0d\u6307\u5b9a\u8f93\u51fa\u6587\u4ef6\n\u276f py3 main.py aes -m gcm -a encrypt -i ./test_data/test_plain.txt -f\n\n------ 3564874090cf12d5 begin@2024-04-04_15:40:55.522 ------\nneed a output file specified and writable\n------ 3564874090cf12d5 took 0.074 milli-seconds to execute ------\n\n# \u89e3\u5bc6\u4e0d\u6307\u5b9a\u8f93\u51fa\u6587\u4ef6\n\u276f py3 main.py aes -m gcm -a decrypt -i ./test_data/test_plain.txt -f -t df8z3ccRyGOQTluw26dIlA==\n\n------ c3dee26a5649a077 begin@2024-04-04_15:41:07.541 ------\nneed a output file specified and writable\n------ c3dee26a5649a077 took 0.084 milli-seconds to execute ------\n```\n\n\n\n## HMAC\u9a8c\u8bc1\u7801\n\n### \u652f\u6301\u7684\u547d\u4ee4\u53c2\u6570\n\n```python\n\u276f py3 main.py hmac --help\nUsage: main.py hmac [OPTIONS]\n\nOptions:\n  -i, --input-data TEXT           \u8f93\u5165\u6570\u636e\uff0c\u5141\u8bb8\u8f93\u5165\uff1a\u5b57\u7b26\u4e32\u3001 base64 \u7f16\u7801\u6570\u636e\u3001\u6587\u4ef6\u8def\u5f84  [required]\n  -e, --is-base64-encoded         \u5982\u679c -i/--input-data \u7684\u503c\u88ab base64 \u7f16\u7801\u8fc7\uff0c\u5219\u9700\u8981\u5e26\u4e0a -e\n                                  \u53c2\u6570\uff0c-e \u4e0e -f \u4e92\u65a5  [default: False]\n  -f, --is-a-file                 \u5982\u679c -i/--input-data \u7684\u503c\u662f\u4e00\u4e2a\u6587\u4ef6\uff0c\u5219\u9700\u8981\u5e26\u4e0a -f\n                                  \u53c2\u6570\u8868\u793a\u5f53\u524d\u9700\u8981\u88ab\u5904\u7406\u7684\u662f\u4e00\u4e2a\u6587\u4ef6\uff0c-e \u4e0e -f \u4e92\u65a5\n  -h, --hash-alg [sha224|sha256|sha384|sha512|sha3_224|sha3_256|sha3_384|sha3_512]\n                                  \u54c8\u5e0c\u7b97\u6cd5  [default: sha256]\n  -k, --key TEXT                  key \u9ed8\u8ba4\u503c\u4e3a 32 \u5b57\u8282\uff0c\u5373 256 \u4f4d\uff0c\u53ea\u5141\u8bb8\u8f93\u5165\u53ef\u89c1\u5b57\u7b26  [default:\n                                  kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk]\n  -r, --random-key                \u662f\u5426\u81ea\u52a8\u751f\u6210\u968f\u673a\u7684\u5bc6\u94a5\uff0c\u5982\u679c\u81ea\u52a8\u751f\u6210\u968f\u673a\u5bc6\u94a5\u5219\u9ed8\u8ba4 32 \u5b57\u8282\u957f\u5ea6\n  --help                          Show this message and exit.\n```\n\n### \u5173\u4e8e\u8f93\u5165\u6570\u636e\u548c\u5bc6\u94a5\u7684\u9884\u8bbe\n\n-   \u8f93\u5165\u6570\u636e\u652f\u6301\u4e09\u79cd\u65b9\u5f0f\uff1a\u5b57\u7b26\u4e32\u660e\u6587\u3001base64 \u7f16\u7801\u7684\u5b57\u8282\u6d41\u3001\u6587\u4ef6\n-   \u5bc6\u94a5\u9ed8\u8ba4 32 \u5b57\u8282\uff0c\u652f\u6301\u751f\u6210\u968f\u673a\u5bc6\u94a5\uff08\u957f\u5ea6\u5f3a\u5236\u4e3a 32 \u5b57\u8282\uff09\n\n### \u6307\u5b9a\u5bc6\u94a5\n\n#### \u4f7f\u7528\u9ed8\u8ba4\u5bc6\u94a5\n\n```python\n\u276f py3 main.py hmac -i hello,world\n\n------ 1daa56484b0a4733 begin@2024-04-04_15:41:52.566 ------\ndata size:11Bytes\nkey:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nhmac:dcd5f3d53661434856c4fb1f76072a22c5fb2526bfd8713aa5041cc43aab7675\n------ 1daa56484b0a4733 took 0.029 milli-seconds to execute ------\n```\n\n#### \u81ea\u5df1\u6307\u5b9a\u5bc6\u94a5\n\n```python\n\u276f py3 main.py hmac -i hello,world -k 1234\n\n------ 990d2a043f6fb90a begin@2024-04-04_15:42:03.420 ------\ndata size:11Bytes\nkey:1234\nhmac:96dd6f73018a6d1911d77a906bc41a6aaae760331eb367ca7134a6b85dbbfdcb\n------ 990d2a043f6fb90a took 0.025 milli-seconds to execute ------\n```\n\n#### \u751f\u6210\u968f\u673a\u5bc6\u94a5\n\n```python\n\u276f py3 main.py hmac -i hello,world -r\n\n------ 8acd4791042aae7c begin@2024-04-04_15:42:14.518 ------\ndata size:11Bytes\nkey:6+98I^y4IsiGGj0p!(1^O+iuoH%CO!s5\nhmac:f8f9931c074fd30c9fe60c31beb87600bfd3b51960e91f34d765d339aa9981f8\n------ 8acd4791042aae7c took 0.057 milli-seconds to execute ------\n```\n\n### \u6307\u5b9a\u8f93\u5165\n\n#### \u8f93\u5165\u5b57\u7b26\u4e32\n\n```python\n\u276f py3 main.py hmac -i hello,world\n\n------ 7ad6f172e3498e2a begin@2024-04-04_15:42:33.801 ------\ndata size:11Bytes\nkey:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nhmac:dcd5f3d53661434856c4fb1f76072a22c5fb2526bfd8713aa5041cc43aab7675\n------ 7ad6f172e3498e2a took 0.028 milli-seconds to execute ------\n```\n\n#### \u8f93\u5165 base64 \u7f16\u7801\u7684\u5b57\u8282\u6d41\n\n```python\n\u276f py3 main.py hmac -i krJchuyaDRYHnu5tsy8UzA== -e\n\n------ 7f8694414df48f4e begin@2024-04-04_15:42:46.859 ------\ndata size:16Bytes\nkey:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nhmac:276e565d1e8a65b38463e124c45c60b00e01a8a623995aae360d1035e0d58923\n------ 7f8694414df48f4e took 0.035 milli-seconds to execute ------\n```\n\n#### \u8f93\u5165\u6587\u4ef6\n\n```python\n\u276f py3 main.py hmac -i ./test_data/test_plain.txt -f\n\n------ d9f4d5072cc8d6ee begin@2024-04-04_15:42:57.326 ------\nfile size:64Bytes\nkey:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nhmac:5b0ea206c45019e090246cea031ca3a267bab15d39bd53491272473aef75d8b0\n------ d9f4d5072cc8d6ee took 0.102 milli-seconds to execute ------\n\n```\n\n### \u6307\u5b9a\u54c8\u5e0c\u7b97\u6cd5\n\n```python\n# \u652f\u6301\u7684 hash \u5217\u8868\uff1a\n# [sha224 | sha256 | sha384 | sha512 | sha3_224 | sha3_256 | sha3_384 | sha3_512]\n\n# \u4f7f\u7528 sha512\n\u276f py3 main.py hmac -i ./test_data/test_plain.txt -f -h sha512\n\n------ 440b99b2f7479972 begin@2024-04-04_15:43:10.055 ------\nfile size:64Bytes\nkey:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nhmac:3c41a94f15c6517e5774d0878268e33c12d9170136c8d9c972f9294324aca61ee2bc4e0f1c7b4a59525ba40f3ccf7b94ebb1de74881ae85023a187e8c1626e1b\n------ 440b99b2f7479972 took 0.107 milli-seconds to execute ------\n\n# \u4f7f\u7528sha3_256\n\u276f py3 main.py hmac -i ./test_data/test_plain.txt -f -h sha3_256\n\n------ c48755f9b49e99b3 begin@2024-04-04_15:43:23.256 ------\nfile size:64Bytes\nkey:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nhmac:25494b6effa8df3ad1bff777892e08ceccf3fbaa181608d006400b8da3fef853\n------ c48755f9b49e99b3 took 0.087 milli-seconds to execute ------\n```\n\n## RSA\u975e\u5bf9\u79f0\u5bc6\u94a5\n\n### \u652f\u6301\u7684\u547d\u4ee4\n\n```python\n\u276f py3 main.py rsa --help\nUsage: main.py rsa [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --help  Show this message and exit.\n\nCommands:\n  decrypt\n  encrypt\n  generate\n  sign\n  verify\n```\n\n### \u751f\u6210\u5bc6\u94a5\u5bf9\n\n#### \u652f\u6301\u7684\u53c2\u6570\n\n```python\n\u276f py3 main.py rsa generate --help\nUsage: main.py rsa generate [OPTIONS]\n\nOptions:\n  -s, --size [2048|3072|4096]  \u5bc6\u94a5\u4f4d\u6570  [default: 2048]\n  -e, --encoding [pem|der]     \u5bc6\u94a5\u683c\u5f0f  [default: pem]\n  -f, --file-name TEXT         \u8f93\u51fa\u5bc6\u94a5\u5bf9\u7684\u6587\u4ef6\u540d\u524d\u7f00\uff0c\u6700\u7ec8\u5199\u5165\u6570\u636e\u65f6\u4f1a\u521b\u5efa\u6587\u4ef6\u5e76\u52a0\u4e0a\u6587\u4ef6\u540d\u540e\u7f00  [default:\n                               demo; required]\n  -p, --password TEXT          \u79c1\u94a5\u5bc6\u7801\uff0c\u4f7f\u7528\u79c1\u94a5\u65f6\u9700\u8981\u8f93\u5165\u6b63\u786e\u7684\u5bc6\u7801\n  -r, --random-password        \u662f\u5426\u751f\u6210\u79c1\u94a5\u7684\u968f\u673a\u5bc6\u7801\uff0c\u5982\u679c\u5e26\u4e0a -r \u6807\u8bc6\uff0c\u5219\u968f\u673a\u751f\u621032\u5b57\u8282\u7684\u5bc6\u7801\n  --help                       Show this message and exit.\n```\n\n#### \u9ed8\u8ba4\u751f\u6210\n\n```\u00a0python\n# \u5bc6\u94a5\u957f\u5ea62048\u4f4d\uff0c\u79c1\u94a5\u4e0d\u5e26\u5bc6\u7801\n\u276f py3 main.py rsa generate -f test\n\n------ 6b89fd023be2d70e begin@2024-04-04_15:48:44.313 ------\ngenerate test_rsa_public.pem/test_rsa_private.pem success\n------ 6b89fd023be2d70e took 134.487 milli-seconds to execute ------\n```\n\n#### \u6307\u5b9a\u957f\u5ea6\u4e14\u6307\u5b9a\u5bc6\u7801\n\n```python\n# pem\u683c\u5f0f\u5bc6\u94a5\uff0c\u79c1\u94a5\u4e0d\u5e26\u5bc6\u7801\n\u276f py3 main.py rsa generate -f test_no_pwd_pem -s 4096 -e pem\n\n------ 7d68ecefd4536a1c begin@2024-04-04_15:50:00.393 ------\ngenerate test_no_pwd_pem_rsa_public.pem/test_no_pwd_pem_rsa_private.pem success\n------ 7d68ecefd4536a1c took 560.056 milli-seconds to execute ------\n\n# pem\u683c\u5f0f\u5bc6\u94a5\uff0c\u79c1\u94a5\u5e26\u5bc6\u7801\n\u276f py3 main.py rsa generate -f test_pwd_pem -s 4096 -e pem -p 1234567890\n\n------ f036eed08d4188e6 begin@2024-04-04_15:51:20.417 ------\nprivate key password:1234567890\ngenerate test_pwd_pem_rsa_public.pem/test_pwd_pem_rsa_private_cipher.pem success\n------ f036eed08d4188e6 took 341.474 milli-seconds to execute ------\n\n# der\u683c\u5f0f\u5bc6\u94a5\uff0c\u79c1\u94a5\u4e0d\u5e26\u5bc6\u7801\n\u276f py3 main.py rsa generate -f test_no_pwd_der -s 4096 -e der\n\n------ e152e62cc8ff4080 begin@2024-04-04_15:51:53.004 ------\ngenerate test_no_pwd_der_rsa_public.der/test_no_pwd_der_rsa_private.der success\n------ e152e62cc8ff4080 took 620.032 milli-seconds to execute ------\n\n# der\u683c\u5f0f\u5bc6\u94a5\uff0c\u79c1\u94a5\u5e26\u5bc6\u7801\n\u276f py3 main.py rsa generate -f test_pwd_der -s 4096 -e der -p 1234567890\n\n------ 9b08b9054b7642cd begin@2024-04-04_15:52:04.209 ------\nprivate key password:1234567890\ngenerate test_pwd_der_rsa_public.der/test_pwd_der_rsa_private_cipher.der success\n------ 9b08b9054b7642cd took 1108.390 milli-seconds to execute ------\n\n```\n\n#### \u6307\u5b9a\u957f\u5ea6\u4e14\u968f\u673a\u751f\u6210\u5bc6\u7801\n\n```python\n\u276f py3 main.py rsa generate -f test -s 4096 -r\n\n------ e3eba04fda53c701 begin@2024-04-04_15:53:14.570 ------\nprivate key password:4)H(iipM9=qnUV!!16LZ3)n&YGQE@v04\ngenerate test_rsa_public.pem/test_rsa_private_cipher.pem success\n------ e3eba04fda53c701 took 300.131 milli-seconds to execute ------\n```\n\n#### \n\n### \u52a0\u5bc6\u4e0e\u89e3\u5bc6\n\n#### \u652f\u6301\u7684\u53c2\u6570\n\n```python\n# \u52a0\u5bc6\n\u276f py3 main.py rsa encrypt --help\nUsage: main.py rsa encrypt [OPTIONS]\n\nOptions:\n  -f, --public-key TEXT           \u516c\u94a5\u6587\u4ef6\u8def\u5f84  [required]\n  -i, --input-data TEXT           \u8f93\u5165\u6570\u636e\uff0c\u53ef\u4ee5\u76f4\u63a5\u4e3a\u5b57\u7b26\u4e32\uff0c\u4e5f\u53ef\u4ee5\u4e3a\n                                  base64\u7f16\u7801\u7684\u6570\u636e\uff0cbase64\u7f16\u7801\u7684\u6570\u636e\u9700\u8981\u5e26\u4e0a\u6807\u8bc6 -c  [required]\n  -e, --encoding [pem|der]        \u5bc6\u94a5\u683c\u5f0f  [default: pem]\n  -c, --b64-encoded               \u8f93\u5165\u6570\u636e\u662f\u5426\u88ab base64 \u7f16\u7801\u8fc7\n  -l, --input-limit INTEGER       \u8f93\u5165\u5185\u5bb9\u6700\u5927\u957f\u5ea6\uff0c\u5355\u4f4d\u4e3a MB\uff0c\u9ed8\u8ba4\u4e3a 1MB\uff0c\u975e\u5bf9\u79f0\u4e0d\u9002\u5408\u76f4\u63a5\u52a0\u5bc6\u8fc7\u957f\u7684\u6570\u636e\n                                  [default: 1]\n  -m, --mode [oaep|pkcs1v15]      \u52a0\u5bc6\u65f6\u7684\u586b\u5145\u6a21\u5f0f  [default: oaep; required]\n  -h, --hash-mode [sha256|sha384|sha512]\n                                  \u6b64\u53c2\u6570\u4ec5\u5728-m\u4e3a oaep \u65f6\u751f\u6548  [default: sha256]\n  --help                          Show this message and exit.\n\n # \u89e3\u5bc6\n \u276f py3 main.py rsa decrypt --help\nUsage: main.py rsa decrypt [OPTIONS]\n\nOptions:\n  -f, --private-key TEXT          \u79c1\u94a5\u6587\u4ef6\u8def\u5f84  [required]\n  -i, --input-data TEXT           \u8f93\u5165\u7684\u5bc6\u6587\u6570\u636e\uff0c \u5fc5\u987b\u4e3abase64\u7f16\u7801\u7684\u6570\u636e  [required]\n  -e, --encoding [pem|der]        \u5bc6\u94a5\u683c\u5f0f  [default: pem]\n  -m, --mode [oaep|pkcs1v15]      \u52a0\u5bc6\u65f6\u7684\u586b\u5145\u6a21\u5f0f  [default: oaep; required]\n  -h, --hash-mode [sha256|sha384|sha512]\n                                  \u6b64\u53c2\u6570\u4ec5\u5728-m\u4e3a oaep \u65f6\u751f\u6548  [default: sha256]\n  -p, --password TEXT             \u79c1\u94a5\u5bc6\u7801\uff0c\u4f7f\u7528\u79c1\u94a5\u65f6\u9700\u8981\u8f93\u5165\u6b63\u786e\u7684\u5bc6\u7801\n  --help                          Show this message and exit.\n\n```\n\n#### \u4f7f\u7528 PEM \u5bc6\u94a5\u5bf9\u52a0\u89e3\u5bc6\n\n##### \u79c1\u94a5\u4e0d\u9700\u8981\u5bc6\u7801\n\n```python\n# \u52a0\u5bc6\n\u276f py3 main.py rsa encrypt -e pem -f ./test_data/test_no_pwd_pem_public.pem -i hello,world\n\n------ 18869a5ba5f11a4f begin@2024-04-04_15:55:10.501 ------\npub key size:4096\npadding mode:oaep-sha256\ncipher:pQlqgAyKEdrjcdRPe90uWHIJv781VD1X0+wrVyzmf6GE1hMdEwcukflGsgkysN3jbR2btNAEfYwxmvk+b1Om/AUdtGrZNAMuCygY3Y2U6ikVRcOCdd0ZCz3Gp7NTEblifVxMR/UsK2VQ+/4Tysmslv2QFOV7Mz+uE6j/o+hTBYhR42r+tkKsAEQGB8LLfo5GC+Wjk5mU1Yt3d8bz3/55S7Wv3DhAlrD9AuiEhqv4E8JL0MgSIN26rzHnOOlkP5vRlH5lLITzier7W9inoQxpYpKdk3xa7gsRXKXVBNcaNdCn9AH/SkrfEe+bHpZcAWG7It2OyTlaAzSwmia+wYx3CgyVtzMHNU9jQrz8xnMcP1ZntxVNvoVnhn9li0H8XTCAy3p+YfYGybEqiSNeFL7cEsONO8x8y0bkqNQE9KFTba0yZNsME1JfJmQVG9IrLaIn1RAsGmPeVYCuHmwcZQCxFUc14von867Z4HewLNqnN5EzalTnVzIY4whZcwMnmp53tZKeNhh0QemuoEqWmkf4cwJHGR/KZJKi+dhB5vo0+LffXf4LzsJRAwbE9ylwEPEsjFx1BYw7jbVIb7hgZ0AZB0J2OMdov25xMWk2nYBmR6L/QFBCtw/J8t7198ZuHmHI247gl8zJ3tFEAPFw1eFOQOkIAKnSDVfnPBlTZQ8smtM=\n------ 18869a5ba5f11a4f took 15.731 milli-seconds to execute ------\n\n# \u89e3\u5bc6\n\u276f py3 main.py 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=\n\n------ 197c89cd0b631ce0 begin@2024-04-04_15:55:40.536 ------\nprivate key password:\nkey size:4096\npadding mode:oaep-sha256\norigin plain:hello,world\n------ 197c89cd0b631ce0 took 338.602 milli-seconds to execute ------\n```\n\n##### \u79c1\u94a5\u9700\u8981\u5bc6\u7801\n\n```python\n# \u52a0\u5bc6\n\u276f py3 main.py rsa encrypt -e pem -f ./test_data/test_pwd_pem_public.pem -i hello,world\n\n------ e1cde686b573fb50 begin@2024-04-04_15:56:04.554 ------\npub key size:4096\npadding mode:oaep-sha256\ncipher:pF06oJgMvzJ8WUphoYqaccLhClQjeSiSQXbQpORXtzkAFKeSqAQwGCKLQlDeJft6bc4wxUe1hS5IM/21hOpx1HZKZyXurfeqHkOXx4ekiakqS+8MgW6x4vozQfTKUZHoDStA8chwibtWlDCAGESYj1drr1UA8cNc5I+ij+hM3voFA3zh8o6JaKLKmxvNedRk5ugJQE6lL3RHMAya5oQS5AYQTtfuLQl52G0loQIPoWWB8KgZD6iZ///I2MI8B4kEHS1O2eg897DNyHGRdf8nRjTJdecWFR7wXY0VQeV8lR2BEsPb7L15qg4lZvonpew9qII6gW5J39yLK73vbAAkpdAmpOGxvOVtztE0Tn4UFkIkOZDkH8nlj1JwhCJ5K9R+TwlkoUinFMasOUZFEvNHzbha69mVErxBQHwv6N6P4kTLOBFVDrqF1Y00ZAQ0ZjIr/s7OdJAyoHlzZkroSfkbvV2eOho3nJD8aoIYdfa1kwttJ7p027VSVMflO1jULRZ0EkT2ncgzOMjqm4fB8Se42/QGjGtKYKOOPp4uBbFuxi8ra4LWY0l0h+FYJ6wXeIcODMLuxHWK4drfJrj5IpaTYNuysmeDEDfMQZQV1WYmyfFsJtIqXFiKrQatgFtGsfYXPCNBTrXa4HVW/Ohm7vE1PKGh+e2K7VpSZ6F4nW+YmQc=\n------ e1cde686b573fb50 took 15.492 milli-seconds to execute ------\n\n# \u89e3\u5bc6 -p \u6307\u5b9a\u5bc6\u7801\n\u276f py3 main.py 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\n\n------ cb0ebbe7b572b665 begin@2024-04-04_15:56:25.496 ------\nprivate key password:1234567890\nkey size:4096\npadding mode:oaep-sha256\norigin plain:hello,world\n------ cb0ebbe7b572b665 took 338.788 milli-seconds to execute ------\n```\n\n#### \u4f7f\u7528 DER \u5bc6\u94a5\u5bf9\u52a0\u89e3\u5bc6\n\n##### \u79c1\u94a5\u4e0d\u9700\u8981\u5bc6\u7801\n\n```python\n# \u52a0\u5bc6\n\u276f py3 main.py rsa encrypt -e der -f ./test_data/test_no_pwd_der_public.der -i hello,world\n\n------ 10e4568e22050ecc begin@2024-04-04_15:56:47.705 ------\npub key size:4096\npadding mode:oaep-sha256\ncipher:V0g9TwUetAKZOl6xwe9SL7ra1P3K2JGwTZ2NMKdZiP4zNaPxxjPPv8Me3g9qMWLNBcfU6dd+7Ia7xGb0c5Ou1/uf7D3xSoV6hU0PV/0i8feJYATgkWFO1NOt1TpIHlcYHtA9NdHEaNXR9qbY8pHyAokVRf83hyQIZMTPgpGo2GH0lJkFAOjxWOiGyPKF7GgdHjz+8rfu4R9VBUg0Wy0O1zyvTKA+b4iE6MS4zJBbzPe0H43w9OLp+TQFykrhLWXsFX+AEhdhxa7N0ebaorlQNtPnY8KuXFx0cqIzWigBcfWNTYgcjbFGLm+mo0Btin0UqDFhbC8EwdpVGnVr6ZBLCvEmyqDAuJN5UCEBQ7Jrakgot/qZ4QHPL5HdU+tNXb8KULH75fyu0A11zzHjpw2E2KRKmg1Fg9aExaim4r15T2VU1eYjZKaPV/YiYMPlqZM9udUQFTmrLRIhCUUp+fc+MJu3zR6chz6d0eSx/RdV8ik8ilKILZl7dAfRS3hC5QG0pPh54Z+MqgAZbHfTxCbjnxqoPJzMOcC+JOPEpjC2PhS6MYE70+Ub8RS1cGZmZ2z32UnanqfT9kLbR626CWUzPzZWsnMheoX5bAABDfp7AkC9BXv+ca3REAyvR8HchVkVMiIRC4dTlY4p4+uFVtOnkhUG5mzSOVGebAWOJ+ftTFY=\n------ 10e4568e22050ecc took 14.792 milli-seconds to execute ------\n\n\n# \u89e3\u5bc6\n\u276f py3 main.py 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=\n\n------ ff1efcc52f4fc05e begin@2024-04-04_15:57:10.634 ------\nprivate key password:\nkey size:4096\npadding mode:oaep-sha256\norigin plain:hello,world\n------ ff1efcc52f4fc05e took 348.368 milli-seconds to execute ------\n```\n\n##### \u79c1\u94a5\u9700\u8981\u5bc6\u7801\n\n```python\n# \u52a0\u5bc6\n\u276f py3 main.py rsa encrypt -e der -f ./test_data/test_pwd_der_public.der -i hello,world\n\n------ d59dc4bec2be5592 begin@2024-04-04_15:57:28.114 ------\npub key size:4096\npadding mode:oaep-sha256\ncipher:XNNpZfpu7ZjnI1HnH/KN9BdO+/rxrtt0K4z/KRQjsAZEYZV4uMtT0o45ZHrDfr6mHNrrIlTRrt6wghIeQUojEo0uQA7auwhqJXXl3ghwTqGhKH4Lkf6q+d0X/Pn1MgRoNb3dIvWsZcpTlnqmffphOe2DzWP4By9a3yZe9rb8S/ddml7/+4BIXVqxwWcAMsAg3lpLnNHBQ853XYeDZXxKjvx4J8f2RUbp7c/xsH6eUjxZfDehcoZL7te6OrY2N342UzYKBqTQV4zbqVTm0c6V1Q7XkjFK3esgcxicitIP2UsdQjpQf9xMtOTQzErdSQk/Pd6tLxLNyKQcxDaqXR9TXA84koIfGETx434im+zhOgsUuSwS6zBARI3AlpQi14LVAbr3/6ABIEJG5QvVVVG32aVzOMrPtViRqZzcDgkyIsBOXLAQv7c5UkP+nePtnjs31IXmcO87p5zW6rweW/6Y5z1emI6RIHgLjqGKFKkaWXua0N+ZqHTEuqks2y27mFFT/g2DJN3zp5corIcjgSEqyuQbQg/hFaurrqzu+djQ1Pevjzy8rUOM7k97UYUHwjv0ITeIB/m2Rknbwsu3WH3jW6TV8Ta+Bw05ZKYT6hoFPttfno+iDVRmzRlY2QuBxHzEALtdsANzxKnpUr/vr5mEmU8Wmi87QSjp1ULMJ5lTU64=\n------ d59dc4bec2be5592 took 14.696 milli-seconds to execute ------\n\n# \u89e3\u5bc6 -p \u6307\u5b9a\u5bc6\u7801\n\u276f py3 main.py 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\n\n------ 806b307f230908a4 begin@2024-04-04_15:57:47.873 ------\nprivate key password:1234567890\nkey size:4096\npadding mode:oaep-sha256\norigin plain:hello,world\n------ 806b307f230908a4 took 343.988 milli-seconds to execute ------\n```\n\n#### \u5bf9\u660e\u6587\u4e3a base64 \u7f16\u7801\u7684\u5b57\u8282\u6d41\u505a\u52a0\u89e3\u5bc6\n\n```python\n# \u52a0\u5bc6\n\u276f py3 main.py rsa encrypt -e pem -f ./test_data/test_pwd_pem_public.pem -i krJchuyaDRYHnu5tsy8UzA== -c\n\n------ 29fa5af7e9f84f15 begin@2024-04-04_15:58:07.029 ------\npub key size:4096\npadding mode:oaep-sha256\ncipher:QiztiJ21bVsNf4DyPhzDAR/E24Xqe94P398JLDakFl3LDhOA3I/XHY3v3R0GBNRrrMPtUorGHxCVmJNqc06kLCtQ4ljd015rYFRgbAtNLsaNgjsdv1Q7kHQSVa7L1BHdhNDK47svEWMQTS4jKLiKVYbCnz4ARYqe3n+vf5UtVDlrpmMNjowbdfnhnEFibCICBwnGUpssFs9X546/BzCTlqgEGdy1SpFhfX2LaqXkTQwsd3YxU9ynHZ7oVe78z/xJlEDQbPGJSfGbUtoCgQAn975hzCceC+CeDK9E7N8vu6HTv9K3vMNRHTOweRWuGxJKKjzVLSXRcDjkXynJPPe6yuyJdFnsoSHWuOsyqPrjJJC+2RvrkW24RlIEMnVEqLReD8/OnZEEw4CZF9xqplS7yRN/khaYM4MxD9qcxAIYgpg2wq6QngtabU+nGtQSfjKIkXlXnbvqMcLI1pS0TtG5vUeNSzc3Ll8g9CxvMrA/T/vUjz9d60fsGpHbjZezpsQdI8Us60BMxUWgFZ6x/ME5HkMmtXYfvi0/aNKWXymgHtVxqeM9hJaQ6MX1zNZRPe4MMHu3xJgATAbVc7GldgV+d2gZm2cLzZaTTB4ARcAARSKPgbskmIQ2buNRs2/ogjvtG72jilOCmSPKZom0VPHkrLzL4csxgxSd2M5N4cu6+Po=\n------ 29fa5af7e9f84f15 took 15.584 milli-seconds to execute ------\n\n# \u89e3\u5bc6 -p \u6307\u5b9a\u5bc6\u7801\n\u276f py3 main.py 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\n\n------ d1f6350d34acf14e begin@2024-04-04_15:58:25.431 ------\nprivate key password:1234567890\nkey size:4096\npadding mode:oaep-sha256\nb64 encoded plain:krJchuyaDRYHnu5tsy8UzA==\n------ d1f6350d34acf14e took 344.681 milli-seconds to execute ------\n```\n\n#### \u52a0\u5bc6\u6a21\u5f0f\u8bbe\u7f6e\n\n##### OAEP\u6a21\u5f0f\n\n```python\n# \u52a0\u5bc6\n\u276f py3 main.py rsa encrypt -e pem -f ./test_data/test_no_pwd_pem_public.pem -i hello,world -m oaep\n\n------ 5d4c86b12cac7641 begin@2024-04-04_15:58:41.153 ------\npub key size:4096\npadding mode:oaep-sha256\ncipher: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=\n------ 5d4c86b12cac7641 took 14.201 milli-seconds to execute ------\n\n# \u89e3\u5bc6\n\u276f py3 main.py 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=\n\n------ 9f151c4c9f56af86 begin@2024-04-04_15:59:05.700 ------\nprivate key password:\nkey size:4096\npadding mode:oaep-sha256\norigin plain:hello,world\n------ 9f151c4c9f56af86 took 346.121 milli-seconds to execute ------\n```\n\n##### PKCS1v15 \u6a21\u5f0f\n\n```python\n# \u52a0\u5bc6\n\u276f py3 main.py rsa encrypt -e pem -f ./test_data/test_no_pwd_pem_public.pem -i hello,world -m pkcs1v15\n\n------ 875086be5059242c begin@2024-04-04_15:59:19.282 ------\npub key size:4096\npadding mode:pkcs1v15\ncipher:i1hVnoQsWAQK4sftuvg08Fq1dzm3o5BRNb78K6gBGVwsu1a/gSFGwIqSOa22ONlZ0cnPu7v/mZAVOi8/tXa1++JrmpnyoZTQ3vATkXK8WG6Q6Dw/dLKUFvsRv04hxMI2ttSMNqFsiRRnCy1qx2m4PFPPuZFniuT4i9hutGn4br+d5e1DtyLxsSmefKk4BJn0Rzgzv3ImeBmT0znTJ5VN2SI/WRHlvc6KmtnQ1xD2/2kkMycPzLguL+XXc+ie/sNg3Y0CelQcXOxonAnkQcXKpzQL7+pONVDHIJvRRXjv0nUWhTay+KWPApfB+BZ0MkI03oW0divZXohI5pWa7n4Gvw1qN+Kvt3BAmBK64LvlKFzZF553re5fMKodhrK/yhIsCtWYjsrgEz+5UAmavwH6dgTrIpssfSQDaUlWwVQRG/pG+jbxkKZ1Y7SX1SAznS4Jb3xKFeWN7ulPLJIe3Zro4VxihW0KgChDFrnVtpZLuXq98mVR+v/L2HaCzNRCY39soYZZywt3IhP2ZDVoCGpVQWQ8y69pbCKfCfiOheRf1j7VYtIOATT2kNGJrVnBwZvXBfQ2Mp3y9UPIud+WAkS2s6bha1QBF/YX72xtZoiICLZZmrmXN3DdGWy1y8SM3mI75s2GsqjF6JeN2iNoLtDy2tpREH78MujjnSjMSCP78wY=\n------ 875086be5059242c took 14.024 milli-seconds to execute ------\n\n# \u89e3\u5bc6\n\u276f py3 main.py 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=\n\n------ d5096f43a1dd5d65 begin@2024-04-04_15:59:37.216 ------\nprivate key password:\nkey size:4096\npadding mode:pkcs1v15\norigin plain:hello,world\n------ d5096f43a1dd5d65 took 348.221 milli-seconds to execute ------\n```\n\n\n\n### \u7b7e\u540d\u4e0e\u9a8c\u7b7e\n\n#### \u652f\u6301\u7684\u53c2\u6570\n\n```python\n# \u7b7e\u540d\n\u276f py3 main.py rsa sign --help\nUsage: main.py rsa sign [OPTIONS]\n\nOptions:\n  -f, --private-key TEXT          \u79c1\u94a5\u6587\u4ef6\u8def\u5f84  [required]\n  -e, --encoding [pem|der]        \u5bc6\u94a5\u683c\u5f0f  [default: pem]\n  -m, --mode [pss|pkcs1v15]       \u7b7e\u540d\u65f6\u7684\u586b\u5145\u6a21\u5f0f  [default: pss; required]\n  -h, --hash-mode [sha256|sha384|sha512]\n                                  \u7b7e\u540d\u65f6\u7684\u54c8\u5e0c\u7b97\u6cd5  [default: sha256]\n  -p, --password TEXT             \u79c1\u94a5\u5bc6\u7801\uff0c\u4f7f\u7528\u79c1\u94a5\u65f6\u9700\u8981\u8f93\u5165\u6b63\u786e\u7684\u5bc6\u7801\n  -i, --input-data TEXT           \u9700\u8981\u88ab\u7b7e\u540d\u7684\u6570\u636e  [required]\n  -c, --b64-encoded               \u8f93\u5165\u6570\u636e\u662f\u5426\u88ab base64 \u7f16\u7801\u8fc7\n  --help                          Show this message and exit.\n\n# \u9a8c\u7b7e\n\u276f py3 main.py rsa verify --help\nUsage: main.py rsa verify [OPTIONS]\n\nOptions:\n  -f, --public-key TEXT           \u516c\u94a5\u6587\u4ef6\u8def\u5f84  [required]\n  -e, --encoding [pem|der]        \u5bc6\u94a5\u683c\u5f0f  [default: pem]\n  -m, --mode [pss|pkcs1v15]       \u7b7e\u540d\u65f6\u7684\u586b\u5145\u6a21\u5f0f  [default: pss; required]\n  -h, --hash-mode [sha256|sha384|sha512]\n                                  \u7b7e\u540d\u65f6\u7684\u54c8\u5e0c\u7b97\u6cd5  [default: sha256]\n  -i, --input-data TEXT           \u9700\u8981\u88ab\u7b7e\u540d\u7684\u6570\u636e  [required]\n  -c, --b64-encoded               \u8f93\u5165\u6570\u636e\u662f\u5426\u88ab base64 \u7f16\u7801\u8fc7\n  -s, --signature TEXT            base64 \u7f16\u7801\u8fc7\u7684\u7b7e\u540d\u503c\n  --help                          Show this message and exit.\n```\n\n#### PSS\u6a21\u5f0f\n\n```python\n# \u7b7e\u540d -p \u6307\u5b9a\u5bc6\u7801\n\u276f py3 main.py rsa sign -e der -f ./test_data/test_pwd_der_private_cipher.der -m pss -i hello,world -p 1234567890\n\n------ 9238d47e0e2636f1 begin@2024-04-04_16:01:35.674 ------\nkey size:4096\nsignature:74bd0807319b4b7c58dc40eaf58efee853eb5d506079ebe8aa3e76350d42ea88c4560c4e732911cca4cd101da6b5b712fae4005bd207d88fcc87761c5c0942f932b9f5773814b91c68c91b23fd623681a069fd29d86c1c89b080b35cf1f45024bf92fdfade2b9536603f5ae40ee0d1350eae686ba1b02954efd8f2b43226228247ce8d5d9c1bbebb97aa77eb52c5a62fbf8bd46e531abf3683487ce5f18cb48f2f175398861f579ea3f38281fc74c7d26942a890fbf3f7c089c553fb632058e7d553c9fc3f4126433cd126067df935008227eaa96b4b7fcb01621d1d553d58070b656aaf2e6d28eb062e5643c639261d908bfd57542ed06e18bfd1419f300582d571c8f461422f684ffd9a68584fd164667f94e9775024cfe635a207297c8a3f1e078652c45c92c7d5ac2a10b6541b2aaaa30e926496caae06effe280bc275ea6b34cf83f3f2ce141acfbce1e03d11071cd9e177be28855fe108ef25ae0ba42db67e9992e3fa0072f92dd8843c666707685f49a10fba0f5719b752025893b272f8171951e007f1527b0320c62e1e9d6814e8de43084e51f917d52047a856576e6cc608576f4d99f4a8e9b237be7c576cf30cb8f97b69e85be2a6e5911f1105555778d122351691d434d40e3742278c54e71c8eac4bbb59918e3ffd3c162d25f0d1dff36e17c3ced4af449f5d06195f9a3328f1c24bd7b52aa49d8727e1894ad2\n----------------\nbase64 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=\nmode:pss-sha256\n------ 9238d47e0e2636f1 took 348.185 milli-seconds to execute ------\n\n# \u9a8c\u7b7e\n\u276f py3 main.py 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\n\n------ 8e8b995bbc527e67 begin@2024-04-04_16:02:01.136 ------\nverify success\nkey size:4096\nmode:pss-sha256\n------ 8e8b995bbc527e67 took 14.193 milli-seconds to execute ------\n```\n\n#### PKCS1v15\u6a21\u5f0f\n\n```python\n# \u7b7e\u540d -p \u6307\u5b9a\u5bc6\u7801\n\u276f py3 main.py rsa sign -e pem -f ./test_data/test_pwd_pem_private_cipher.pem -i hello,world -p 1234567890\n\n------ c12c59d278e72bb6 begin@2024-04-04_16:02:15.070 ------\nkey size:4096\nsignature:8590c16fd7349f7da4b845ab56c0fd786cd0f5bd4c60b8508d571f9c1da8a6f647c6b283a593ce3a8d77bf052f8eef2752058cb653faf434b7e04e4b49248d2d55815616c0e9e4e4196186bc749831616ab66a815f82bc6414d9469790aabb987cdf76b2594e586c65512042aa70f04c6c5ddf9d2038cd01971d36829e3342710e3221eb83f0299baa876df8fa43f76b6bad7ec0a28e30d77f5bdbae132f880ee2234bd5de82ae1e7c00fcb20d04f5c65e5d79a9b64f3776868139581b1ba3cf8167ca2e893330b4a49f2a5c0cd9bd5f331d270dbd3aacc6fba492ab7cce3fe78ec2f7b82d339b9ab90b89bbed8fe5f123f26709a4777dee8df500bf6d4d7178c25889c90b4d0826a47a85556958041aeb5e3609abe315d286d2804eacda85af2bbdfab943206150bd651fd0cb5106ff9b03636dcd2b5ab4d2186fe48241802ad0c8a4313d8bc29ff5c36fa0cffad5e566f3b47b3564b2739685e5ca881c3729fc300911f62b95c36eced3ebb6260997ba16b614599d809df71010a94ada31fa1db0342b632826b57599a8227ce18a44565de61e23e96b5d413702648173ada70f7c3d46599357edb4b2926f5824eef4a5960eae06c236c7cf1a8890ff67365b1aaf778423b99e641ffd56553d8196b4ed40b11ae6e804f8623fc9e3842f248394b61d1886c550d5e20c4e9d3c8b071da6f55569740f3b633cfd99167442a9f5\n----------------\nbase64 encoded:hZDBb9c0n32kuEWrVsD9eGzQ9b1MYLhQjVcfnB2opvZHxrKDpZPOOo13vwUvju8nUgWMtlP69DS34E5LSSSNLVWBVhbA6eTkGWGGvHSYMWFqtmqBX4K8ZBTZRpeQqruYfN92sllOWGxlUSBCqnDwTGxd350gOM0Blx02gp4zQnEOMiHrg/Apm6qHbfj6Q/dra61+wKKOMNd/W9uuEy+IDuIjS9Xegq4efAD8sg0E9cZeXXmptk83doaBOVgbG6PPgWfKLokzMLSknypcDNm9XzMdJw29OqzG+6SSq3zOP+eOwve4LTObmrkLibvtj+XxI/JnCaR3fe6N9QC/bU1xeMJYickLTQgmpHqFVWlYBBrrXjYJq+MV0obSgE6s2oWvK736uUMgYVC9ZR/Qy1EG/5sDY23NK1q00hhv5IJBgCrQyKQxPYvCn/XDb6DP+tXlZvO0ezVksnOWheXKiBw3KfwwCRH2K5XDbs7T67YmCZe6FrYUWZ2AnfcQEKlK2jH6HbA0K2MoJrV1magifOGKRFZd5h4j6WtdQTcCZIFzracPfD1GWZNX7bSykm9YJO70pZYOrgbCNsfPGoiQ/2c2Wxqvd4QjuZ5kH/1WVT2BlrTtQLEa5ugE+GI/yeOELySDlLYdGIbFUNXiDE6dPIsHHab1VWl0DztjPP2ZFnRCqfU=\nmode:pss-sha256\n------ c12c59d278e72bb6 took 343.034 milli-seconds to execute ------\n\n# \u9a8c\u7b7e\n\u276f py3 main.py 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=\n\n------ 8151e7568131a1c6 begin@2024-04-04_16:02:36.431 ------\nverify success\nkey size:4096\nmode:pss-sha256\n------ 8151e7568131a1c6 took 13.708 milli-seconds to execute ------\n```\n\n## ECC\u692d\u5706\u66f2\u7ebf\n\n### \u652f\u6301\u7684\u547d\u4ee4\n\n```\n\u276f py3 main.py ecc --help\nUsage: main.py ecc [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --help  Show this message and exit.\n\nCommands:\n  ecdh\n  generate\n  sign\n  verify\n```\n\n### \u751f\u6210\u5bc6\u94a5\u5bf9\n\n```python\n\u276f py3 main.py ecc generate --help\nUsage: main.py ecc generate [OPTIONS]\n\nOptions:\n  -c, --curve [secp256r1|secp384r1|secp521r1|secp256k1]\n                                  ecc \u692d\u5706\u66f2\u7ebf\u7c7b\u578b  [default: secp256k1]\n  -e, --encoding [pem|der]        \u5bc6\u94a5\u683c\u5f0f  [default: pem]\n  -f, --file-name TEXT            \u8f93\u51fa\u5bc6\u94a5\u5bf9\u7684\u6587\u4ef6\u540d\u524d\u7f00\uff0c\u6700\u7ec8\u5199\u5165\u6570\u636e\u65f6\u4f1a\u521b\u5efa\u6587\u4ef6\u5e76\u52a0\u4e0a\u6587\u4ef6\u540d\u540e\u7f00  [default:\n                                  demo; required]\n  -p, --password TEXT             \u79c1\u94a5\u5bc6\u7801\uff0c\u4f7f\u7528\u79c1\u94a5\u65f6\u9700\u8981\u8f93\u5165\u6b63\u786e\u7684\u5bc6\u7801\n  -r, --random-password           \u662f\u5426\u751f\u6210\u79c1\u94a5\u7684\u968f\u673a\u5bc6\u7801\uff0c\u5982\u679c\u5e26\u4e0a -r \u6807\u8bc6\uff0c\u5219\u968f\u673a\u751f\u621032\u5b57\u8282\u7684\u5bc6\u7801\n  --help                          Show this message and exit.\n```\n\n#### \u9ed8\u8ba4\u751f\u6210\n\n```python\n\u276f py3 main.py ecc generate\n\n------ d6b0cebd74d64b57 begin@2024-04-04_16:07:59.720 ------\ngenerate demo_ecc_public.pem/demo_ecc_private.pem success\n------ d6b0cebd74d64b57 took 17.039 milli-seconds to execute ------\n```\n\n#### \u6307\u5b9a\u692d\u5706\u66f2\u7ebf\u4e14\u6307\u5b9a\u5bc6\u7801\n\n```python\n\u276f py3 main.py ecc generate -c secp384r1 -p 1234567890\n\n------ e852fd0a2d84d39f begin@2024-04-04_16:08:46.706 ------\nprivate key password:1234567890\ngenerate demo_ecc_public.pem/demo_ecc_private_cipher.pem success\n------ e852fd0a2d84d39f took 16.710 milli-seconds to execute ------\n```\n\n#### \u6307\u5b9a\u692d\u5706\u66f2\u7ebf\u4e14\u968f\u673a\u751f\u6210\u5bc6\u7801\n\n```python\n\u276f py3 main.py ecc generate -c secp384r1 -r\n\n------ 073bd5585937e6fd begin@2024-04-04_16:09:28.102 ------\nprivate key password:)N)y&4dq=ODg`339uE`7*@A9Gl0eVs3Z\ngenerate demo_ecc_public.pem/demo_ecc_private_cipher.pem success\n------ 073bd5585937e6fd took 16.721 milli-seconds to execute ------\n```\n\n### ECDH\u5bc6\u94a5\u4ea4\u6362\n\n#### \u652f\u6301\u7684\u53c2\u6570\n\n```python\n\u276f py3 main.py ecc ecdh --help\nUsage: main.py ecc ecdh [OPTIONS]\n\nOptions:\n  -a, --alice-pub-key TEXT    \u4f60\u81ea\u5df1\u7684\u516c\u94a5\u6587\u4ef6\u7684\u8def\u5f84\u5982: ./alice_public.pem  [required]\n  -k, --alice-pri-key TEXT    \u4f60\u81ea\u5df1\u7684\u79c1\u94a5\u6587\u4ef6\u7684\u8def\u5f84\u5982: ./alice_private.pem  [required]\n  -p, --password TEXT         \u4f60\u81ea\u5df1\u7684\u79c1\u94a5\u7684\u5bc6\u7801\uff0c\u5982\u679c\u521b\u5efa\u65f6\u8bbe\u7f6e\u4e86\u5bc6\u7801\uff0c\u90a3\u4e48\u5728\u4f7f\u7528\u79c1\u94a5\u65f6\u9700\u8981\u8f93\u5165\u6b63\u786e\u7684\u5bc6\u7801\n  -b, --bob-pub-key TEXT      \u5bf9\u65b9\u7684\u516c\u94a5\u6587\u4ef6\u7684\u8def\u5f84\u5982: ./bob_public.pem  [required]\n  -e, --encoding [pem|der]    \u5bc6\u94a5\u683c\u5f0f  [default: pem]\n  -l, --length INTEGER RANGE  \u6d3e\u751f\u5bc6\u94a5\u7684\u957f\u5ea6\uff0c\u9ed8\u8ba4 32 \u5b57\u8282\uff0c\u957f\u5ea6\u8303\u56f4[16 -- 64]  [default: 32;\n                              16<=x<=64]\n  -s, --salt TEXT             \u7528\u4e8e\u589e\u52a0\u6d3e\u751f\u5bc6\u94a5\u5b89\u5168\u6027\u7684\u76d0\u503c\uff0c\u4e24\u8fb9\u5fc5\u987b\u63d0\u4f9b\u4e00\u6837\u7684\u76d0\u503c  [default:\n                              hello,world1234567890!@#$%^&*()_+{}:\";<>?/;\n                              required]\n  -c, --context TEXT          \u7528\u4e8e\u589e\u52a0\u6d3e\u751f\u5bc6\u94a5\u5b89\u5168\u6027\u7684\u4e0a\u4e0b\u6587\u4fe1\u606f\uff0c\u4e24\u8fb9\u5fc5\u987b\u63d0\u4f9b\u4e00\u6837\u7684\u4e0a\u4e0b\u6587\u6570\u636e  [default: ecc\n                              handshake context data; required]\n  --help                      Show this message and exit.\n\n```\n\n#### \u751f\u6210 alice \u4e0e bob \u7684\u5bc6\u94a5\u5bf9\n\n```python\n\u276f py3 main.py ecc generate -f alice -p 1234567890\n\n------ f4815ee66aa727b2 begin@2024-04-04_16:11:03.966 ------\nprivate key password:1234567890\ngenerate alice_ecc_public.pem/alice_ecc_private_cipher.pem success\n------ f4815ee66aa727b2 took 17.763 milli-seconds to execute ------\n\n\u276f py3 main.py ecc generate -f bob -p 1234567890\n\n------ 76e72cdd07cb5c32 begin@2024-04-04_16:11:26.201 ------\nprivate key password:1234567890\ngenerate bob_ecc_public.pem/bob_ecc_private_cipher.pem success\n------ 76e72cdd07cb5c32 took 16.373 milli-seconds to execute ------\n```\n\n#### alice\u6d3e\u751f\u548c bob \u5171\u4eab\u7684\u5bf9\u79f0\u5bc6\u94a5\n\n```python\n\u276f py3 main.py 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\n\n------ 8235537a02e647d4 begin@2024-04-04_16:14:48.686 ------\ncurve name:secp256k1\nderived key:u+UNGIzrPbLRVlTSixl8fgd3SgLuGeQrwSI4Irs1tpSVivmTxYLTOUm/o1pvqPLuOGVA8D3iLdUGLEE72Wo1QQ==\nlength:64\n------ 8235537a02e647d4 took 18.166 milli-seconds to execute ------\n```\n\n#### bob\u6d3e\u751f\u548calice\u5171\u4eab\u7684\u5bf9\u79f0\u5bc6\u94a5\n\n```python\n\u276f py3 main.py 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\n\n------ d50d7d254d02104c begin@2024-04-04_16:15:39.570 ------\ncurve name:secp256k1\nderived key:u+UNGIzrPbLRVlTSixl8fgd3SgLuGeQrwSI4Irs1tpSVivmTxYLTOUm/o1pvqPLuOGVA8D3iLdUGLEE72Wo1QQ==\nlength:64\n------ d50d7d254d02104c took 16.998 milli-seconds to execute ------\n```\n\n### \u7b7e\u540d\u4e0e\u9a8c\u7b7e\n\n#### \u652f\u6301\u7684\u53c2\u6570\n\n```python\n# \u7b7e\u540d\n\u276f py3 main.py ecc sign --help\nUsage: main.py ecc sign [OPTIONS]\n\nOptions:\n  -f, --private-key TEXT          \u79c1\u94a5\u6587\u4ef6\u8def\u5f84  [required]\n  -e, --encoding [pem|der]        \u5bc6\u94a5\u683c\u5f0f  [default: pem]\n  -h, --hash-mode [sha256|sha384|sha512|sha3-224|sha3-256|sha3-384|sha3-512]\n                                  \u7b7e\u540d\u65f6\u7684\u54c8\u5e0c\u7b97\u6cd5  [default: sha256]\n  -p, --password TEXT             \u79c1\u94a5\u5bc6\u7801\uff0c\u5982\u679c\u751f\u6210\u65f6\u8bbe\u7f6e\u4e86\u5bc6\u7801\u90a3\u4e48\u5728\u4f7f\u7528\u79c1\u94a5\u65f6\u9700\u8981\u8f93\u5165\u6b63\u786e\u7684\u5bc6\u7801\n  -i, --input-data TEXT           \u9700\u8981\u88ab\u7b7e\u540d\u7684\u6570\u636e  [required]\n  -c, --b64-encoded               \u8f93\u5165\u6570\u636e\u662f\u5426\u88ab base64 \u7f16\u7801\u8fc7\n  --help                          Show this message and exit.\n\n# \u9a8c\u7b7e\n\u276f py3 main.py ecc verify --help\nUsage: main.py ecc verify [OPTIONS]\n\nOptions:\n  -f, --public-key TEXT           \u516c\u94a5\u6587\u4ef6\u8def\u5f84  [required]\n  -e, --encoding [pem|der]        \u5bc6\u94a5\u683c\u5f0f  [default: pem]\n  -h, --hash-mode [sha256|sha384|sha512|sha3-224|sha3-256|sha3-384|sha3-512]\n                                  \u7b7e\u540d\u65f6\u7684\u54c8\u5e0c\u7b97\u6cd5  [default: sha256]\n  -i, --input-data TEXT           \u9700\u8981\u88ab\u7b7e\u540d\u7684\u6570\u636e  [required]\n  -c, --b64-encoded               \u8f93\u5165\u6570\u636e\u662f\u5426\u88ab base64 \u7f16\u7801\u8fc7\n  -s, --signature TEXT            base64 \u7f16\u7801\u8fc7\u7684\u7b7e\u540d\u503c\n  --help                          Show this message and exit.\n```\n\n#### \u751f\u6210\u5bc6\u94a5\u5bf9\n\n```python\n\u276f py3 main.py ecc generate -c secp384r1 -p 1234567890 -e der\n\n------ 3a40beeed28cffa4 begin@2024-04-04_16:17:49.172 ------\nprivate key password:1234567890\ngenerate demo_ecc_public.der/demo_ecc_private_cipher.der success\n------ 3a40beeed28cffa4 took 16.821 milli-seconds to execute ------\n```\n\n#### \u7b7e\u540d\n\n```python\n\u276f py3 main.py ecc sign -f ./demo_ecc_private_cipher.der -e der -h sha3-512 -p 1234567890 -i aGVsbG8sd29ybGQK -c\n\n------ dbc12fab8422ba0f begin@2024-04-04_16:18:57.578 ------\ncurve name:secp384r1\nkey size:384\nsignature:30640230243bba7ec0a95f7aef4868673282b70217285a667ae52ce5e43c6af5b33e8adbda86bbe2a7d9f995b934d038eae5624c02306c47daed069e51bb12c274c13219c173ed4b59c6f76caab04f50b4359f3f25c0fa4dab4c17cb88888767f37e4c8cf993\nbase64 encoded:MGQCMCQ7un7AqV9670hoZzKCtwIXKFpmeuUs5eQ8avWzPorb2oa74qfZ+ZW5NNA46uViTAIwbEfa7QaeUbsSwnTBMhnBc+1LWcb3bKqwT1C0NZ8/JcD6TatMF8uIiIdn835MjPmT\nmode:ECDSA\n------ dbc12fab8422ba0f took 17.265 milli-seconds to execute ------\n```\n\n#### \u9a8c\u7b7e\n\n```python\n\u276f py3 main.py ecc verify -f ./demo_ecc_public.der -e der -h sha3-512 -i aGVsbG8sd29ybGQK -c -s MGQCMCQ7un7AqV9670hoZzKCtwIXKFpmeuUs5eQ8avWzPorb2oa74qfZ+ZW5NNA46uViTAIwbEfa7QaeUbsSwnTBMhnBc+1LWcb3bKqwT1C0NZ8/JcD6TatMF8uIiIdn835MjPmT\n\n------ d1c74d3acc46413b begin@2024-04-04_16:20:09.177 ------\ncurve name:secp384r1\nverify success\nkey size:384\nmode:ECDSA\n------ d1c74d3acc46413b took 15.220 milli-seconds to execute ------\n```\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": null,
    "version": "1.0.1",
    "project_urls": {
        "Homepage": "https://cloud.tencent.com/developer/article/2155922"
    },
    "split_keywords": [
        "encryption",
        "cli",
        "tool",
        "security",
        "aes",
        "hmac",
        "ecc",
        "rsa"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "aa3ee99910c59507ee7dc19c420ffc48978b8d7f8fa92bbabc7ef4d8be625807",
                "md5": "71cfe0343328bd44813bb995691e693c",
                "sha256": "92c6062e0be8a6ea145aee2e3e16fe1237a597310ede3b4e9edd3a23e85744e1"
            },
            "downloads": -1,
            "filename": "encryption_tool-1.0.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "71cfe0343328bd44813bb995691e693c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 19128,
            "upload_time": "2024-04-04T09:03:40",
            "upload_time_iso_8601": "2024-04-04T09:03:40.742631Z",
            "url": "https://files.pythonhosted.org/packages/aa/3e/e99910c59507ee7dc19c420ffc48978b8d7f8fa92bbabc7ef4d8be625807/encryption_tool-1.0.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-04-04 09:03:40",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "encryption-tool"
}
        
Elapsed time: 0.20910s