# sample_crypto 使用说明

## 功能概述

sample_crypto 通过多个操作示例演示常用安全操作接口的使用方法，以下是各个示例功能说明
- sample_cipher: 实现对称加解密操作
  - 支持配置加密算法，包括 AES / DES / SM4
  - 支持配置密钥长度，64 / 128 / 192 / 256 bit

- sample_digest: 实现哈希摘要计算
  - 支持配置哈希算法，包括 MD5 / SHA1 / SHA2 / SHA3

- sample_hmac: 实现消息认证码计算
  - 支持配置哈希算法，包括 MD5 / SHA1 / SHA2 / SHA3
  - 支持配置任意密钥长度

- sample_rsa: 实现非对称加解密操作
  - 支持生成 RSA 密钥对
  - 支持配置 RSA 密钥长度，1024 / 2048 / 3072 / 4096 / 8192 bit
  - 使用公钥加密，私钥解密


### 软件架构说明

![sample_crypto_software_arch.png](./_static/_images/sample_crypto/sample_crypto_software_arch.png)

### 代码位置及目录结构

- 代码位置 `app/samples/platform_samples/sample_crypto`
- 目录结构

```bash
sample_crypto
├── sample_cipher
│   ├── Makefile
│   └── sample_cipher.c
├── sample_digest
│   ├── Makefile
│   └── sample_digest.c
├── sample_hmac
│   ├── Makefile
│   └── sample_hmac.c
└── sample_rsa
    ├── Makefile
    └── sample_rsa.c
```

### API 流程说明

![sample_crypto_api_process.png](./_static/_images/sample_crypto/sample_crypto_api_process.png)

## 编译 & 部署


### 编译

在 sample_crypto 各个子目录下执行 `make` 命令即可完成编译，以 sample_cipher 为例

```Shell
cd app/samples/platform_samples/sample_cryto/sample_cipher
make
```

详细的程序编译方式请查阅 [ 编译方法 ](overview.html#span-id-sample-build) 章节。


### 部署

刷写系统软件镜像后 , sample_crypto 的所有示例程序位于板端 `/app/platform_samples/sample_crypto`目录


## 运行

### sample_cipher 运行

#### sample_cipher 运行方法

- 直接执行程序 `./sample_cipher -h` 可以获得帮助信息

#### sample_cipher 参数选项说明

```
Usage: sample_cipher [Options] [value]
Options:
  -s <cipher name>      Select Cipher Name
  -k <key size>         Key Size [64/128/192/256]
  -h                    Show this help message
Available Cipher:
        Cipher Name     Recommend Key Size
         1. aes_ecb     128/192/256-bit
         2. aes_cbc     128/192/256-bit
         3. aes_cfb     128/192/256-bit
         4. aes_ofb     128/192/256-bit
         5. aes_ctr     128/192/256-bit
         6. sm4_ecb     128/-bit
         7. sm4_cbc     128/-bit
         8. sm4_cfb     128/-bit
         9. sm4_ofb     128/-bit
         10. sm4_ctr    128/-bit
         11. des_ecb    64/-bit
         12. des_cbc    64/-bit
         13. des_ofb    64/-bit
```

**选项：**

- `-s <cipher name>`: 选择加密算法。
- `-k <key size>`: 设置密钥长度。
- `-h`: 显示帮助信息。

各个加密算法支持密钥长度如下

| **加密算法**                       | **64bit** | **128bit** | **192bit** | **256bit** |
|:---------------------------------:|:------:|:------:|:------:|:------:|
| aes_ecb                                | ×      | ✔      | ✔      | ✔      |
| aes_cbc                                | ×      | ✔      | ✔      | ✔      |
| aes_cfb                                | ×      | ✔      | ✔      | ✔      |
| aes_ofb                                | ×      | ✔      | ✔      | ✔      |
| aes_ctr                                | ×      | ✔      | ✔      | ✔      |
| sm4_ecb                                | ×      | ✔      | ×      | ×      |
| sm4_cbc                                | ×      | ✔      | ×      | ×      |
| sm4_cfb                                | ×      | ✔      | ×      | ×      |
| sm4_ofb                                | ×      | ✔      | ×      | ×      |
| sm4_ctr                                | ×      | ✔      | ×      | ×      |
| des_ecb                                | ✔      | ×      | ×      | ×      |
| des_cbc                                | ✔      | ×      | ×      | ×      |
| des_ofb                                | ✔      | ×      | ×      | ×      |

#### sample_cipher 运行效果

以 AES 算法为例，使用 ECB 模式，密钥长度256位。对文本字符串 `Test message for encryption, Cipher[aes_ecb], KeySize[256]` 进行加解密操作。
执行命令如下:

```shell
./sample_cipher -s aes_ecb -k 256
```

打印信息如下

```
Encrypted text (hex): ffbc5dcf79a3e0bf45fb3f974983c3258f800e9eb65f78749710d35d9494dabc083f1481350d73fce81f5d513bb5e7da00c12f646cc2c3ae1a9604915ddad2ae
Decrypted text: Test message for encryption, Cipher[aes_ecb], KeySize[256]
```

可以得知解密后字符串与原文一致。


### sample_digest 运行

#### sample_digest 运行方法

- 直接执行程序 `./sample_digest -h` 可以获得帮助信息

#### sample_digest 参数选项说明

```
Usage: sample_digest [Options] [value]
Options:
  -s <hash name>      Select Hash Name
  -h                  Show this help message
Available Hash:
         1. md5
         2. sha1
         3. sha224
         4. sha256
         5. sha384
         6. sha512
         7. sha3-224
         8. sha3-256
         9. sha3-384
         10. sha3-512
```

**选项：**

- `-s <hash name>`: 选择哈希算法。
- `-h`: 显示帮助信息。

sample_digest 支持配置的哈希算法如下
- MD5
- SHA1
- SHA-2: SHA-224 /256 / 384 / 512
- SHA-3: SHA3-224 /256 / 384 / 512


#### sample_digest 运行效果

以 SHA256 算法为例，对文本字符串 `Test message for digest [sha256]` 进行哈希计算。
执行命令如下:

```shell
./sample_digest -s sha256
```

打印信息如下

```
plain_text:
Test message for digest [sha256]
[sha256] hash is:
ded9cd0a4ac6e11c38ab3ceb3cff7cff5d18a3bbc37b9fc578f96b3ee63df4b4
```

可以得知 sample_digest 计算得到的哈希值为 `ded9cd0a4ac6e11c38ab3ceb3cff7cff5d18a3bbc37b9fc578f96b3ee63df4b4`

与系统命令 sha256sum 进行比较

```
echo -n "Test message for digest [sha256]" | sha256sum
ded9cd0a4ac6e11c38ab3ceb3cff7cff5d18a3bbc37b9fc578f96b3ee63df4b4
```

可以得知 sample_digest 计算哈希值与系统命令一致。


### sample_hmac 运行

#### sample_hmac 运行方法

- 直接执行程序 `./sample_hmac -h` 可以获得帮助信息

#### sample_hmac 参数选项说明

```
Usage: sample_hmac [Options] [value]
Options:
  -s <hash name>  Select hash Name
  -k <key size>   Key Size
  -h              Show this help message
```
**选项：**

- `-s <hash name>`: 选择哈希算法。
- `-k <key size>`: 配置密钥长度。
- `-h`: 显示帮助信息。

**注意: HMAC 的密钥可以是任意长度，但推荐密钥长度与所选择的哈希算法一致**

sample_hmac 支持哈希算法以及各个哈希算法推荐的密钥长度如下
```
Available Hash:
        Hash Name        Recommend Key Size
         1. md5          128-bits
         2. sha1         160-bits
         3. sha224       224-bits
         4. sha256       256-bits
         5. sha384       384-bits
         6. sha512       512-bits
         7. sha3-224     224-bits
         8. sha3-256     256-bits
         9. sha3-384     384-bits
         10. sha3-512    512-bits
```

#### sample_hmac 运行效果

以使用 SHA256 算法，密钥长度256位为例，对文本字符串 `Test message for Hmac: Hash[sha256] Key[256]` 进行消息认证码计算。
```shell
./sample_hmac -s sha256 -k 256
```

打印信息如下
```
plain_text:
Test message for Hmac: Hash[sha256] Key[256]

Key is:
37099184641824357814880241575040

HMAC is:
8c5b046e961c4dfaea07c60293ebd36b9cea95cfba7e31c02c583a5cdb2303e2
```

可以得知 sample_hmac 计算得到的消息认证码为 `8c5b046e961c4dfaea07c60293ebd36b9cea95cfba7e31c02c583a5cdb2303e2`

使用 openssl 命令传入相同的 KEY 与 消息原文进行 HMAC 计算比较

**注意: sample_hmac 每次根据 key size 生成随机数作为密钥，需拷贝 key 字符串作为 openssl 命令参数**
```
echo -n "Test message for Hmac: Hash[sha256] Key[256]" \
| openssl dgst -sha256 -hmac "37099184641824357814880241575040"
```
输出 `8c5b046e961c4dfaea07c60293ebd36b9cea95cfba7e31c02c583a5cdb2303e2`

可以得知 sample_hmac 计算消息认证值与系统命令一致。

### sample_rsa 运行

#### sample_rsa 运行方法

- 直接执行程序 `./sample_cipher -h` 可以获得帮助信息

#### sample_rsa 参数选项说明

```
Usage: sample_rsa [Options] [value]
Options:
  -k <key size>     Key Size [1024/2048/3072/4096/8192]
  -h                Show this help message
```

**选项：**

- `-k <key size>`: : 设置密钥长度，支持 1024 / 2048 / 3072 / 4096 / 8192
- `-h`: 显示帮助信息。

#### sample_rsa 运行效果

以使用 RSA2048 算法为例，对文本字符串 `The test message for RSA-2048 encryption!` 进行私钥加密，使用公钥解密
```shell
./sample_rsa -k 2048
```

```
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA1iFUncTYJEnDxdpzcj+4ZYyj2jpu7GgE0/3Z9r91H2y54nju
GyyeLV1zAaekxpHcvbxkdqozb5sU8St2jAaj6M7413dEQstO+DNK1U4y7KTeC67g
eJ11Qmya0bpvKaWmrA8/9xi0TLJs/P0MzVMgHpZNSjn2EeKuMRT+operzJYfqvFe
VoX+9iZjzaiCSO1Ely4jP77nuMlGnrUUAfMT79WveEOO6IErxyvpic/RiBDnWmn6
IjWjFGxVsqMqDfWHKI4ceGPAESfXp6rNJ134WcJjZT6CW1cWT2UcmIHgFJTgGo+R
TggPM2yloancHxSiK1D8gcuugRspIchEKoUbrwIDAQABAoIBAQCaYKNRr4Yo+2mC
rpEG8Huv8up6viAUnpXEhMLtC3GUe120snzv6IYNrM7qhYPdiXG89SL1DpZQw10g
1rX8FBl+EiIDrb/v7AX+GXS9PkimpeJUR/sb2mGcxxIDXMciHoSAjeoO6qeqmATN
jF77dQ+2HaSRfCI1GNl/F2TRskmxD8RN6u/sX5MqvdLU5z7mV2Lzn2XsryrRyc5S
+6AfVy554IYdyOsW56uiTyXfhEDF/OFCiNIHR7nVDD4ziW71RjydEazosiFnwqWB
3igfsCll6hN5JY0ZorRxEDozB0UeP5GFfpAJ1UvnFPpunyxK8cEAk8K2y9v1TwJm
fAyMxcChAoGBAPsZ6CTvlOhKrMwRl/ZX4exS2CezDIEoNFoWYQ9MuXC5mYe3QHFJ
SL2ptv2WcMUEX7dlx278kCXQtRyqOMIqopRSxhTh62+i6PevxUokYu8hVYfeMbIq
PoSqNwmLJvs7jSxC6lwi2s+S4PU2tQyNgRnD86DMwrBXoUcs23XTyN9fAoGBANpO
xteskS4FJ82m00N3QS7S5ScuX2MbtxstmjFvPkbEkY40BabtspKtMd3Bzkfu95Ex
K8UuCPWtfM8RGPEitDWmRLjVaA3MpRuNykqProryFxpkgQvnWIYYV/R3MJPnZo2X
F/XSzj+6X9k1G58EMi+gV75V12LQL5i6d3dIHDWxAoGBAIlKw/QWDsvnsI0vfXAS
4xMsxMUID+k6i01KeS09XRM2V6yt1I1cbWpONiB3Nhdy6cbD3oRfkY0rjSssIzZ+
yz/f9jAKyojSgSCUOYHtXS60gih0o6VvlZlB3C/apqitCeZOfAd+gzcFbvyEOf+w
CwuEaVvdOQHkF+lrrF7DOkxvAoGBAMH23ltAO1ntQLlLMUgvTB4DSZEvdZcESAOA
2BB2K5oLCtyTQjZX2aLS+YxzpwlovFQnoSE3zsQiWdNM+KE/WWiVi1fCXQptuoEp
0QPAd6+Ce556j+H4skGqnXNa9zFil07UYXiLza73tDO0KQ93VfPU/kDh2lY0bSXA
/2ZfDplxAoGAYVURUd4GqYuGo1xJ4GQc5vNgM1BVMlGLtFIE0S7IcuqjDoQrNArz
giOZQm0IdFS6Na9HcZJuQE2TZEXrFgPbRP7k5Ewih2LrallTO2To+Tua4gGNmRvE
0EupPJH3VxTTKbP0Qha/Y9g9NFQk0FR0f6AWnzMGvgzYsfj88lXujes=
-----END RSA PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1iFUncTYJEnDxdpzcj+4
ZYyj2jpu7GgE0/3Z9r91H2y54njuGyyeLV1zAaekxpHcvbxkdqozb5sU8St2jAaj
6M7413dEQstO+DNK1U4y7KTeC67geJ11Qmya0bpvKaWmrA8/9xi0TLJs/P0MzVMg
HpZNSjn2EeKuMRT+operzJYfqvFeVoX+9iZjzaiCSO1Ely4jP77nuMlGnrUUAfMT
79WveEOO6IErxyvpic/RiBDnWmn6IjWjFGxVsqMqDfWHKI4ceGPAESfXp6rNJ134
WcJjZT6CW1cWT2UcmIHgFJTgGo+RTggPM2yloancHxSiK1D8gcuugRspIchEKoUb
rwIDAQAB
-----END PUBLIC KEY-----

Encrypted text:
0c2f5795bfab85e0cccc32f729ab6050a079212eb260b88257bbbaaf3528804f69e657d132380edcf4dc28ee683ba41013b6a0404afdba4268c3bf9784c27567cd2f03ac6f2f92ac7663680fc405cc4e60aacc35b9ec33ef02fa0d10a9b28c4b2214a78807a2f234fd764d153e82eddf42fea42799e6632f7cda8678f6e288c1e711b7d94ea092736d8fdfd2b8b771ad8f8a9567

Decrypted text: The test message for RSA-2048 encryption!
```

可以得知解密后字符串与原文一致。


## 常见问题

### HMAC 使用不同密钥长度有哪些差异
HMAC 的密钥长度可以灵活选择，当密钥长度与哈希函数分组长度不一致时，按照如下处理:

- ​密钥长度小于哈希函数分组长度：例如使用 SHA-256 和密钥长度512，则算法内部需要在密钥末尾填充零，使其达到分组长度。
- ​密钥长度大于哈希函数分组长度：例如使用 SHA-256 和密钥长度128，则算法内部需要对密钥进行哈希运算，将哈希结果作为实际使用的密钥。

一般情况下，出于安全性考虑，推荐的密钥长度为哈希函数的输出长度
