#### Version : v2.1.0
## 名詞定義
1. **Host** : 生產端
1. **Device** : 設備(例如 MS30N)
1. **hex string** : 0x11, 0x22, 0x33 會是 "112233" 用這樣表示
1. **DAC_package** : 包含 DAC、DAC 私鑰、DAC 公鑰、PAI 和 CD 的集合
- 此部份的處理可以找 Ken
1. **Static_key** : Host 和 Device 需要事先知道此金鑰,用於保護 First_half_key/Second_half_key 的傳送
- 使用 AES 256 ECB 的固定金鑰
- 這裡的範例使用 : 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x35, 0x36, 0x36, 0x37, 0x37, 0x38, 0x38, 0x39, 0x39, 0x30, 0x30, 0x39, 0x39, 0x38, 0x38, 0x37, 0x37, 0x36, 0x36, 0x35, 0x35, 0x34, 0x34
1. **First_half_key** : Host 端所產出來的 Comm_key 前半段 key
- 使用 AES 256 ECB
- 前半段的 key 大小 16 bytes (請隨機產生)
- 這裡的範例會使用 : 0x61, 0x61, 0x62, 0x62, 0x63, 0x63, 0x64, 0x64, 0x65, 0x65, 0x66, 0x66, 0x67, 0x67, 0x68, 0x68, 0x0a
1. **Second_half_key** : Host 端所產出來的 Comm_key 前半段 key
- 使用 AES 256 ECB
- 前半段的 key 大小 16 bytes (請隨機產生)
- 這裡的範例會使用 : 0x72, 0x72, 0x74, 0x74, 0x79, 0x79, 0x75, 0x75, 0x69, 0x69, 0x6f, 0x6f, 0x70, 0x70, 0x6c, 0x6c, 0x0a
1. **Comm_key** : $First_half_key + $Second_half_key
- 使用 AES 256 ECB
1. **Save_DAC_key** : 用於將從 Host 接收的 DAC 存儲到 Device 上的金鑰,用於對 DAC_package 進行加密後存檔
- 此金鑰需要妥善保存(底下建議方法)
- 使用分散存放
- 使用部份演算
- 使用 AES 256 CBC(key and iv)
## Linux command line tools
### AES ECB encryption
- echo -n "$(your text)" | openssl enc -e -aes-256-ecb -K $(key hex string) | base64 -w 0
```bash
# example
# data : "hello test"
# key (hex string) : "3131323233333434353536363737383839393030393938383737363635353434"
$ echo -n "hello test" | openssl enc -e -aes-256-ecb -K "3131323233333434353536363737383839393030393938383737363635353434" | base64 -w 0
# output
OxYybQGex3dzw3fG6dP3kg==
```
### AES ECB decryption
- echo "$(your encode base64 of decryptoing data)" | base64 -d | openssl enc -d -aes-256-ecb -K $(hex string key)
```bash
# example
# data : "OxYybQGex3dzw3fG6dP3kg=="
# key (hex string) : "3131323233333434353536363737383839393030393938383737363635353434"
$ echo "OxYybQGex3dzw3fG6dP3kg==" | base64 -d | openssl enc -d -aes-256-ecb -K "3131323233333434353536363737383839393030393938383737363635353434"
# output
hello test
```
## Host 和 Device 通訊方式
1. telnet
2. uart
3. tcp(telnet or tcp server client)
## 資料格式
- 使用 JSON
## 生產流程
### 1. 從WiSecKey取得DAC
```mermaid
sequenceDiagram
Host ->> DAC_server: 呼叫API(https://inesapi.certifyiddemo.com/v2/auth)請求本次交易token
DAC_server -->> Host: 回傳交易token
Host ->> DAC_server: 呼叫API(https://ines.certifyiddemo.com/admin/application)+交易token請求Access Keys
DAC_server -->> Host: 回傳Access Keys
Host ->> DAC_server: 呼叫API(https://inesapi.certifyid.com/v2/organizations/{organization_id}/certificates)+Access Keys + Device序號請求DAC\PAI封包
DAC_server -->> Host: 回傳以Device序號當作CN的加密DAC\PAI封包
Note left of Host: 解密DAC\PAI封包
Note right of Host: 製作成csv檔後,移交給生產程式
```
### 2. BL602燒入置換DAC韌體\MS30N燒入出廠韌體
### 3. 生產程式(Host)置換DAC
```mermaid
sequenceDiagram
Note left of Host: $Static_key(必須已存在)
Note right of Device: $Static_key(必須已存在)
Note left of Host: 將解密後的DAC\PAI封包拆解成 $DAC_package (註1)
Note left of Host: 產出 $First_half_key
Note left of Host: 使用 $Static_key 將 $First_half_key 進行加密<br> $Static_key($First_half_key)
Host->>Device: 傳送前半段金鑰 send $First_half_key (api:set_comm_key)
Note right of Device: 使用 $Static_key 解密取得 $First_half_key
Note right of Device: 產出 $Second_half_key
Note right of Device: 合併出 $Comm_key<br>$First_half_key + $Second_half_key
Note right of Device: 使用 $Static_key 將 $Second_half_key 進行加密<br> $Static_key($Second_half_key)
Device-->>Host: 回應加密後的 $Second_half_key
Note left of Host: 使用 $Static_key 解密並取得 $Second_half_key
Note over Host,Device: 合併出 $Comm_key<br>$First_half_key + $Second_half_key
Note left of Host: 使用 $Comm_key 對 $DAC_package 做加密(範例5)<br>$Comm_key($DAC_package)
Host->>Device: 傳送加密後的 $DAC_package (api:send_dac_package)
Note right of Device: 使用 $Comm_key 解密並取得 $DAC_package (範例6)
Note right of Device: 產生出 $Save_DAC_key
Note right of Device: 此步驟必定要執行<br>使用 $Save_DAC_key 對 $DAC_package 進行加密
Note right of Device: save $DAC_package
Device-->>Host: 回應成功
```
### 4. BL602燒入燒入出廠韌體
## DAC寫入位置
| | BL602 | MS30N |
| - | - | -|
| PAI\DAC | PSM(0x3C3000~3F6000) | /root/DAC.data|
---
---
# 註1 (將 DAC 相關資料拆解成 $DAC_package)
## 使用 WISeKey
## 自產 CD
- 因為還沒有取得認證所以需要自產
- 複製相關資料
1. 建立測試資料夾
1. 複製 connectedhomeip 提供的 CD pem and key
1. 複製 chip-cert (請自行編譯出來)
```bash
mkdir test
cp -a ~/linux_disk/amigo/open_source_project/connectedhomeip/credentials/test/certification-declaration/Chip-Test-CD-Signing-Key.pem ./
cp -a ~/linux_disk/amigo/open_source_project/connectedhomeip/credentials/test/certification-declaration/Chip-Test-CD-Signing-Cert.pem ./
cp -a ~/linux_disk/amigo/open_source_project/connectedhomeip/out/host/chip-cert ./
```
- setup 環境變數
1. 設定你需要的 VID 和 VID
1. 注意是 16 進制且不加 0x
```bash
export VID=FFF1
export PID=8189
```
- Generate CD
1. 目前,將使用 chip-cert 生成 CD。目前,管理員只驗證 VID 和 PID 是否與設備其他地方公開的數據匹配:基本信息叢集、DAC 和 DAC 原始位置(若有)。您可以將其他字段保持不變。
```bash
$ ./chip-cert gen-cd \
--key ./Chip-Test-CD-Signing-Key.pem \
--cert ./Chip-Test-CD-Signing-Cert.pem \
--out ./Chip-Test-CD-${VID}-${PID}.der \
--format-version "1" \
--vendor-id "${VID}" \
--product-id "${PID}" \
--device-type-id "0x1234" \
--certificate-id "ZIG20141ZB330001-24" \
--security-level "0" \
--security-info "0" \
--version-number "9876" \
--certification-type "0"
```
1. Verify the CD. Make sure it contains your VID/PID (in decimal format):
```bash
$ ./chip-cert print-cd ./Chip-Test-CD-${VID}-${PID}.der
# output
SignerKeyId value: hex:62FA823359ACFAA9963E1CFA140ADDF504F37160
0x01, tag[Anonymous]: 0x100, type: Structure (0x15), container:
0x04, tag[Context Specific]: 0x0, type: Unsigned Fixed Point (0x04), value: 1
0x08, tag[Context Specific]: 0x1, type: Unsigned Fixed Point (0x04), value: 65521 # VID 0xFFF1
0x0A, tag[Context Specific]: 0x2, type: Array (0x16), container:
0x0D, tag[Anonymous]: 0x100, type: Unsigned Fixed Point (0x04), value: 33161 # PID 0x8189
0x12, tag[Context Specific]: 0x3, type: Unsigned Fixed Point (0x04), value: 4660
0x15, tag[Context Specific]: 0x4, type: UTF-8 String (0x0c), length: 19, value: "ZIG20141ZB330001-24"
0x2B, tag[Context Specific]: 0x5, type: Unsigned Fixed Point (0x04), value: 0
0x2E, tag[Context Specific]: 0x6, type: Unsigned Fixed Point (0x04), value: 0
0x32, tag[Context Specific]: 0x7, type: Unsigned Fixed Point (0x04), value: 39030
0x35, tag[Context Specific]: 0x8, type: Unsigned Fixed Point (0x04), value: 0
```
1. 產出 encode base64
```bash
$ base64 -w 0 ./Chip-Test-CD-${VID}-${PID}.der
# output
MIHqBgkqhkiG9w0BBwKggdwwgdkCAQMxDTALBglghkgBZQMEAgEwRQYJKoZIhvcNAQcBoDgENhUkAAElAfH/NgIFiYEYJQM0EiwEE1pJRzIwMTQxWkIzMzAwMDEtMjQkBQAkBgAlB3aYJAgAGDF+MHwCAQOAFGL6gjNZrPqplj4c+hQK3fUE83FgMAsGCWCGSAFlAwQCATAKBggqhkjOPQQDAgRIMEYCIQDtIe2KMsYANYaUboMtzWEsY6NVFG0Z6xPWyXwp5gW3EwIhAI2NyBDByrxD2yH+KgTCjECe7cecm7cSt2OfVc4/FrWs
```
## 拆分檔案
1. 主要要使用 xxx_full.pem (04B0A0724FE75F1E_full.pem)
1. 將它拆分成四個檔案依序是, DAC private key, DAC, PAI ,PAA
1. 拆分檔案, 目前必要的是:
- dac_key.pem 裡面的 private key
- dac_key.pem 裡面的 publickey key
- pai.pem
- CD:
- 當送驗 CSA 會簽發一個含有 VID and PID 的憑證,必須寫進產品內
- 測試的時候需要自行產出並放入程式內編譯,請參閱 **"`自產 CD`"**
1. 測試必要檔案(正式站不需要)
- paa.pem:
- 當在配對的時候必須要此轉換成 .der 格式並放在 --paa-trust-store-path 能找的到的地方
```bash
# dac_key.pem
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEILzEK1Wjjw7jR776IxdvH+kYbRu+ciOaYQBfVn5ZqROUoAoGCCqGSM49
AwEHoUQDQgAEzamLc8JTlxapTjoRg850BbPF/kbcuEeYxKhizyRmZWzOPjSZMIPb
D0qu8lB6Rdlg6AChDfH7/vsm36aeQGmLdQ==
-----END EC PRIVATE KEY-----
# dac.pem
-----BEGIN CERTIFICATE-----
MIIB2DCCAX+gAwIBAgIIAwfs1pB1A2owCgYIKoZIzj0EAwIwQDEoMCYGA1UEAwwf
TWF0dGVyIFBBSSBmb3IgQ29udG9zbyAyMDIzMDExNDEUMBIGCisGAQQBgqJ8AgEM
BEZGRjEwIBcNMjMxMDExMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMEExEzARBgNV
BAMMCktlbk1ha2VJdDIxFDASBgorBgEEAYKifAIBDARGRkYxMRQwEgYKKwYBBAGC
onwCAgwEODE4OTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABM2pi3PCU5cWqU46
EYPOdAWzxf5G3LhHmMSoYs8kZmVszj40mTCD2w9KrvJQekXZYOgAoQ3x+/77Jt+m
nkBpi3WjYDBeMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAURm9SgJWr3HuN7zS7
h+VZJIj2KP8wHQYDVR0OBBYEFM9DuuJe+DIviufCVsM8fr2QilugMA4GA1UdDwEB
/wQEAwIHgDAKBggqhkjOPQQDAgNHADBEAiAHFX1U2+nnRwSjsJBG1f1VouxSzlNz
0n82WghUWpsYEwIgMbTSuRO7ArxdGLPppH6UQg/vpv1RPFxH5e+KIyBQ8Yo=
-----END CERTIFICATE-----
# pai.pem
-----BEGIN CERTIFICATE-----
MIIB7zCCAZWgAwIBAgIIDyDSajmKu8AwCgYIKoZIzj0EAwIwUTELMAkGA1UEBhMC
Q0gxEDAOBgNVBAoMB1dJU2VLZXkxMDAuBgNVBAMMJ1dJU2VLZXkgUm9vdCBDQSBm
b3IgTWF0dGVyIFBLSSAyMDIzMDExNDAgFw0yMzAxMTUwMzAxMjBaGA85OTk5MTIz
MTIzNTk1OVowQDEoMCYGA1UEAwwfTWF0dGVyIFBBSSBmb3IgQ29udG9zbyAyMDIz
MDExNDEUMBIGCisGAQQBgqJ8AgEMBEZGRjEwWTATBgcqhkjOPQIBBggqhkjOPQMB
BwNCAASW04hStn+JHWagKgie9fKo6Sp9r0bnHAXBQVxzTmFQLG+T6rFTTugf1zfV
ybAU8WF5ACno9gVPz+iPfZqUYhPgo2YwZDASBgNVHRMBAf8ECDAGAQH/AgEAMB8G
A1UdIwQYMBaAFKRdxF2nJYIxpngKmxG1pqQ6PwCYMB0GA1UdDgQWBBRGb1KAlavc
e43vNLuH5VkkiPYo/zAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwIDSAAwRQIh
AOm8awp7J3u70vc4jShCjbsIL/ySjGGgHVZXcA6ssnWzAiBUDvsVbaK3PZU9yFBJ
CjRHCvovL/oxUIr9lgJb2VzOmA==
-----END CERTIFICATE-----
# paa.pem
-----BEGIN CERTIFICATE-----
MIICADCCAaagAwIBAgIIT5Xdm374/9owCgYIKoZIzj0EAwIwUTELMAkGA1UEBhMC
Q0gxEDAOBgNVBAoMB1dJU2VLZXkxMDAuBgNVBAMMJ1dJU2VLZXkgUm9vdCBDQSBm
b3IgTWF0dGVyIFBLSSAyMDIzMDExNDAgFw0yMzAxMTUwMjU1NDlaGA85OTk5MTIz
MTIzNTk1OVowUTELMAkGA1UEBhMCQ0gxEDAOBgNVBAoMB1dJU2VLZXkxMDAuBgNV
BAMMJ1dJU2VLZXkgUm9vdCBDQSBmb3IgTWF0dGVyIFBLSSAyMDIzMDExNDBZMBMG
ByqGSM49AgEGCCqGSM49AwEHA0IABJ61RmP2dmdLPWiGS4YTa0JFRA1edqsfNV4K
xHM03quEPK6Pfa0uCvJb+HC/kIcZEDL76zrSjYL63puLKu1FHoqjZjBkMBIGA1Ud
EwEB/wQIMAYBAf8CAQEwHwYDVR0jBBgwFoAUpF3EXaclgjGmeAqbEbWmpDo/AJgw
HQYDVR0OBBYEFKRdxF2nJYIxpngKmxG1pqQ6PwCYMA4GA1UdDwEB/wQEAwIBBjAK
BggqhkjOPQQDAgNIADBFAiEA9jc0FmC4IXIdavi+67mHaBWSCqaXk0SpwYAZS4wH
sBkCIBxjEJ7fEmZt8USiGx2gABISyGU1GM6+GmugtW26xfLW
-----END CERTIFICATE-----
```
1. dac_key.pem 取得 dac private/public key 在個別轉換成 base64
- 看裡面的樣子
```bash
$ openssl ec -in dac_key.pem -noout -text
# output
read EC key
Private-Key: (256 bit)
priv:
bc:c4:2b:55:a3:8f:0e:e3:47:be:fa:23:17:6f:1f:
e9:18:6d:1b:be:72:23:9a:61:00:5f:56:7e:59:a9:
13:94
pub:
04:cd:a9:8b:73:c2:53:97:16:a9:4e:3a:11:83:ce:
74:05:b3:c5:fe:46:dc:b8:47:98:c4:a8:62:cf:24:
66:65:6c:ce:3e:34:99:30:83:db:0f:4a:ae:f2:50:
7a:45:d9:60:e8:00:a1:0d:f1:fb:fe:fb:26:df:a6:
9e:40:69:8b:75
ASN1 OID: prime256v1
NIST CURVE: P-256
private key (hexstring) : bcc42b55a38f0ee347befa23176f1fe9186d1bbe72239a61005f567e59a91394
public key (hexstring) : 04cda98b73c2539716a94e3a1183ce7405b3c5fe46dcb84798c4a862cf2466656cce3e34993083db0f4aaef2507a45d960e800a10df1fbfefb26dfa69e40698b75
```
- 取得 private base64
```bash
# private key encode base64
$ openssl ec -in dac_key.pem -noout -text > dac_key.txt
# 取得 private key 然後 encode base64
$ sed -n -e '/priv:/,/pub:/p' dac_key.txt | grep -v "priv:" | grep -v "pub:" | tr -d ' \n:' | sed 's/\(..\)/\1:/g; s/.$//' | xxd -r -p | base64 -w 0
# output
vMQrVaOPDuNHvvojF28f6RhtG75yI5phAF9WflmpE5Q=
```
- 取得 public base64
```bash
# public key encode base64
$ openssl ec -in dac_key.pem -noout -text > dac_key.txt
# 取得 public key 然後 encode base64
$ sed -n -e '/pub:/,/ASN1 :/p' dac_key.txt | grep -v "pub:" | grep -v "ASN1 " | tr -d ' \n:' | sed 's/\(..\)/\1:/g; s/.$//' | xxd -r -p | base64 -w 0
# output
BM2pi3PCU5cWqU46EYPOdAWzxf5G3LhHmMSoYs8kZmVszj40mTCD2w9KrvJQekXZYOgAoQ3x+/77Jt+mnkBpi3U=
```
- 驗證 (請和上面比對)
```bash
# private key
echo -e "vMQrVaOPDuNHvvojF28f6RhtG75yI5phAF9WflmpE5Q=" | base64 -d | xxd -p | tr -d '\n'
# output
bcc42b55a38f0ee347befa23176f1fe9186d1bbe72239a61005f567e59a91394
# public key
echo -e "BM2pi3PCU5cWqU46EYPOdAWzxf5G3LhHmMSoYs8kZmVszj40mTCD2w9KrvJQekXZYOgAoQ3x+/77Jt+mnkBpi3U=" | base64 -d | xxd -p | tr -d '\n'
# output
04cda98b73c2539716a94e3a1183ce7405b3c5fe46dcb84798c4a862cf2466656cce3e34993083db0f4aaef2507a45d960e800a10df1fbfefb26dfa69e40698b75
```
1. dac.pem to dac.der 在將其轉 enccode base64
```bash
$ openssl x509 -in ./dac.pem -outform DER | base64 -w 0
# output
MIIB2DCCAX+gAwIBAgIIAwfs1pB1A2owCgYIKoZIzj0EAwIwQDEoMCYGA1UEAwwfTWF0dGVyIFBBSSBmb3IgQ29udG9zbyAyMDIzMDExNDEUMBIGCisGAQQBgqJ8AgEMBEZGRjEwIBcNMjMxMDExMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMEExEzARBgNVBAMMCktlbk1ha2VJdDIxFDASBgorBgEEAYKifAIBDARGRkYxMRQwEgYKKwYBBAGConwCAgwEODE4OTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABM2pi3PCU5cWqU46EYPOdAWzxf5G3LhHmMSoYs8kZmVszj40mTCD2w9KrvJQekXZYOgAoQ3x+/77Jt+mnkBpi3WjYDBeMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAURm9SgJWr3HuN7zS7h+VZJIj2KP8wHQYDVR0OBBYEFM9DuuJe+DIviufCVsM8fr2QilugMA4GA1UdDwEB/wQEAwIHgDAKBggqhkjOPQQDAgNHADBEAiAHFX1U2+nnRwSjsJBG1f1VouxSzlNz0n82WghUWpsYEwIgMbTSuRO7ArxdGLPppH6UQg/vpv1RPFxH5e+KIyBQ8Yo=
```
1. pai.pem to pai.der 在將其轉 enccode base64
```bash
$ openssl x509 -in ./pai.pem -outform DER | base64 -w 0
MIIB7zCCAZWgAwIBAgIIDyDSajmKu8AwCgYIKoZIzj0EAwIwUTELMAkGA1UEBhMCQ0gxEDAOBgNVBAoMB1dJU2VLZXkxMDAuBgNVBAMMJ1dJU2VLZXkgUm9vdCBDQSBmb3IgTWF0dGVyIFBLSSAyMDIzMDExNDAgFw0yMzAxMTUwMzAxMjBaGA85OTk5MTIzMTIzNTk1OVowQDEoMCYGA1UEAwwfTWF0dGVyIFBBSSBmb3IgQ29udG9zbyAyMDIzMDExNDEUMBIGCisGAQQBgqJ8AgEMBEZGRjEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASW04hStn+JHWagKgie9fKo6Sp9r0bnHAXBQVxzTmFQLG+T6rFTTugf1zfVybAU8WF5ACno9gVPz+iPfZqUYhPgo2YwZDASBgNVHRMBAf8ECDAGAQH/AgEAMB8GA1UdIwQYMBaAFKRdxF2nJYIxpngKmxG1pqQ6PwCYMB0GA1UdDgQWBBRGb1KAlavce43vNLuH5VkkiPYo/zAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwIDSAAwRQIhAOm8awp7J3u70vc4jShCjbsIL/ySjGGgHVZXcA6ssnWzAiBUDvsVbaK3PZU9yFBJCjRHCvovL/oxUIr9lgJb2VzOmA==
```
1. 在 Host 先將憑證都轉換成 `.der` 格式
- 這部份可以找 Ken 詢問
1. 使用 JSON 格式,內部須包含 key
- DAC
- DAC_pub_key
- DAC_pri_key
- PAI
- CD
```json
{
"DAC": "...",
"DAC_pub_key": "...",
"DAC_pri_key": "...",
"PAI": "...",
"CD": "..."
}
```
1. Value use base64
1. 範例:
```JSON
{
"DAC": "MIIB2DCCAX+gAwIBAgIIAwfs1pB1A2owCgYIKoZIzj0EAwIwQDEoMCYGA1UEAwwfTWF0dGVyIFBBSSBmb3IgQ29udG9zbyAyMDIzMDExNDEUMBIGCisGAQQBgqJ8AgEMBEZGRjEwIBcNMjMxMDExMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMEExEzARBgNVBAMMCktlbk1ha2VJdDIxFDASBgorBgEEAYKifAIBDARGRkYxMRQwEgYKKwYBBAGConwCAgwEODE4OTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABM2pi3PCU5cWqU46EYPOdAWzxf5G3LhHmMSoYs8kZmVszj40mTCD2w9KrvJQekXZYOgAoQ3x+/77Jt+mnkBpi3WjYDBeMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAURm9SgJWr3HuN7zS7h+VZJIj2KP8wHQYDVR0OBBYEFM9DuuJe+DIviufCVsM8fr2QilugMA4GA1UdDwEB/wQEAwIHgDAKBggqhkjOPQQDAgNHADBEAiAHFX1U2+nnRwSjsJBG1f1VouxSzlNz0n82WghUWpsYEwIgMbTSuRO7ArxdGLPppH6UQg/vpv1RPFxH5e+KIyBQ8Yo=",
"DAC_pub_key": "BM2pi3PCU5cWqU46EYPOdAWzxf5G3LhHmMSoYs8kZmVszj40mTCD2w9KrvJQekXZYOgAoQ3x+/77Jt+mnkBpi3U=",
"DAC_pri_key": "04cda98b73c2539716a94e3a1183ce7405b3c5fe46dcb84798c4a862cf2466656cce3e34993083db0f4aaef2507a45d960e800a10df1fbfefb26dfa69e40698b75",
"PAI":"MIIB7zCCAZWgAwIBAgIIDyDSajmKu8AwCgYIKoZIzj0EAwIwUTELMAkGA1UEBhMCQ0gxEDAOBgNVBAoMB1dJU2VLZXkxMDAuBgNVBAMMJ1dJU2VLZXkgUm9vdCBDQSBmb3IgTWF0dGVyIFBLSSAyMDIzMDExNDAgFw0yMzAxMTUwMzAxMjBaGA85OTk5MTIzMTIzNTk1OVowQDEoMCYGA1UEAwwfTWF0dGVyIFBBSSBmb3IgQ29udG9zbyAyMDIzMDExNDEUMBIGCisGAQQBgqJ8AgEMBEZGRjEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASW04hStn+JHWagKgie9fKo6Sp9r0bnHAXBQVxzTmFQLG+T6rFTTugf1zfVybAU8WF5ACno9gVPz+iPfZqUYhPgo2YwZDASBgNVHRMBAf8ECDAGAQH/AgEAMB8GA1UdIwQYMBaAFKRdxF2nJYIxpngKmxG1pqQ6PwCYMB0GA1UdDgQWBBRGb1KAlavce43vNLuH5VkkiPYo/zAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwIDSAAwRQIhAOm8awp7J3u70vc4jShCjbsIL/ySjGGgHVZXcA6ssnWzAiBUDvsVbaK3PZU9yFBJCjRHCvovL/oxUIr9lgJb2VzOmA==j",
"CD": "MIHqBgkqhkiG9w0BBwKggdwwgdkCAQMxDTALBglghkgBZQMEAgEwRQYJKoZIhvcNAQcBoDgENhUkAAElAfH/NgIFiYEYJQM0EiwEE1pJRzIwMTQxWkIzMzAwMDEtMjQkBQAkBgAlB3aYJAgAGDF+MHwCAQOAFGL6gjNZrPqplj4c+hQK3fUE83FgMAsGCWCGSAFlAwQCATAKBggqhkjOPQQDAgRIMEYCIQDtIe2KMsYANYaUboMtzWEsY6NVFG0Z6xPWyXwp5gW3EwIhAI2NyBDByrxD2yH+KgTCjECe7cecm7cSt2OfVc4/FrWs"
}
```
---
---
## API
### set_comm_key
- 設定並取得 Comm_key
1. request
| key | value type | value | required | descript |
|-----|------------|--------------|----------|---------------|
| api | string | set_comm_key | Y | const string |
| key | string | | Y | encode base64 |
| sn | string | | | |
- key
- Randomly generating
- It's 16 bytes : 0x61, 0x61, 0x62, 0x62, 0x63, 0x63, 0x64, 0x64, 0x65, 0x65, 0x66, 0x66, 0x67, 0x67, 0x68, 0x68, 0x0a # "aabbccddeeffgghh"
- Encrypting using $Static_key with output in base64
- sn : Marking the message of the request API
```JSON
{
"api": "set_comm_key",
"key": "hHX/CdUxj5Bp14YT9tVsSVgsj4IoqoSB5PeF7JdVk8g="
}
```
1. Response format
| key | value type | value | required | descript |
|----------|------------|--------------|----------|------------------------------|
| api | string | set_comm_key | Y | const string |
| ret_code | number | | Y | 0 is success, other is fail |
| msg | string | | Y | detailed message of ret_code |
| key | string | | Y | encode base64 |
| sn | string | | | |
- key
- Randomly generating
- It's 16 bytes : 0x72, 0x72, 0x74, 0x74, 0x79, 0x79, 0x75, 0x75, 0x69, 0x69, 0x6f, 0x6f, 0x70, 0x70, 0x6c, 0x6c, 0x0a # "rrttyyuuuuiioppll"
- Encrypting using $Static_key with output in base64
- sn : Response request sn's value
```JSON
{
"api": "get_pub_key",
"ret_code": 0,
"msg": "success",
"key": "yvlOWUaCsvF8bbrgGxHOvEB9aN4jDKFcftzD9ZIgAjY="
}
```
---
### send_dac_package
- 傳送加密後的 $DAC_package
1. request
| key | value type | value | descript |
|-------------|------------|---------------|--------------|
| api | string | send_dac_package | const string |
| dac_package | string | | hex string |
- dac_package
- 使用 $Comm_key 對 $DAC_package 進行加密,請參閱 (範例5)
- $DAC_package 請參閱 (註1)
```JSON
{
"api": "send_dac_package",
"dac_package":
"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"
}
```
1. Response format
| key | value type | value | descript |
|----------|------------|-------------|-------------------------------------|
| ret_code | number | 0 | 0 表示成功, 其餘皆為失敗,可參閱 msg 欄位 |
| msg | string | success | success 表示成功其餘街失敗內容 |
```JSON
{
"api": "send_comm_key",
"ret_code": 0,
"msg": "success",
}
```
# AES c
## Encryptor
- encryptor.c
- build : gcc encryptor.c -o encryptor -lssl -lcrypto
```c
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <string.h>
#include <stdio.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
int aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *ciphertext)
{
if (!plaintext || plaintext_len <= 0 || !key || !ciphertext)
return -1;
EVP_CIPHER_CTX *ctx = NULL;
int len = 0;
int ciphertext_len = 0;
if (!(ctx = EVP_CIPHER_CTX_new()))
{
ciphertext_len = -2;
goto err;
}
if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_ecb(), NULL, key, NULL))
{
ciphertext_len = -3;
goto err;
}
if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
{
ciphertext_len = -4;
goto err;
}
ciphertext_len = len;
if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
{
ciphertext_len = -5;
goto err;
}
ciphertext_len += len;
err:
EVP_CIPHER_CTX_free(ctx);
return ciphertext_len;
}
int base64_encode(const unsigned char *input, int length, char *out, int out_len)
{
if (!input || length < 0 || !out || out_len < 0)
return -1;
memset(out, 0, out_len);
BIO *bio = NULL;
BIO *b64 = NULL;
FILE *stream;
int encoded_size = 4 * ((length + 2) / 3);
if (out_len < encoded_size)
return -2;
int ret = 0;
stream = fmemopen(out, encoded_size + 1, "w");
if (!stream)
{
ret = -3;
goto err;
}
b64 = BIO_new(BIO_f_base64());
if (!b64)
{
ret = -4;
goto err;
}
bio = BIO_new_fp(stream, BIO_NOCLOSE);
if (!bio)
{
ret = -5;
goto err;
}
if (!BIO_push(b64, bio))
{
ret = -6;
goto err;
}
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
if (0 > BIO_write(b64, input, length))
{
ret = -7;
goto err;
}
BIO_flush(b64);
err:
BIO_free_all(b64);
fclose(stream);
return 0;
}
int main(void)
{
char *plaintext = "{\"DAC\":\"MIIB2DCCAX+gAwIBAgIIAwfs1pB1A2owCgYIKoZIzj0EAwIwQDEoMCYGA1UEAwwfTWF0dGVyIFBBSSBmb3IgQ29udG9zbyAyMDIzMDExNDEUMBIGCisGAQQBgqJ8AgEMBEZGRjEwIBcNMjMxMDExMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMEExEzARBgNVBAMMCktlbk1ha2VJdDIxFDASBgorBgEEAYKifAIBDARGRkYxMRQwEgYKKwYBBAGConwCAgwEODE4OTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABM2pi3PCU5cWqU46EYPOdAWzxf5G3LhHmMSoYs8kZmVszj40mTCD2w9KrvJQekXZYOgAoQ3x+/77Jt+mnkBpi3WjYDBeMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAURm9SgJWr3HuN7zS7h+VZJIj2KP8wHQYDVR0OBBYEFM9DuuJe+DIviufCVsM8fr2QilugMA4GA1UdDwEB/wQEAwIHgDAKBggqhkjOPQQDAgNHADBEAiAHFX1U2+nnRwSjsJBG1f1VouxSzlNz0n82WghUWpsYEwIgMbTSuRO7ArxdGLPppH6UQg/vpv1RPFxH5e+KIyBQ8Yo=\",\"DAC_pub_key\":\"BM2pi3PCU5cWqU46EYPOdAWzxf5G3LhHmMSoYs8kZmVszj40mTCD2w9KrvJQekXZYOgAoQ3x+/77Jt+mnkBpi3U=\",\"DAC_pri_key\":\"04cda98b73c2539716a94e3a1183ce7405b3c5fe46dcb84798c4a862cf2466656cce3e34993083db0f4aaef2507a45d960e800a10df1fbfefb26dfa69e40698b75\",\"PAI\":\"MIIB7zCCAZWgAwIBAgIIDyDSajmKu8AwCgYIKoZIzj0EAwIwUTELMAkGA1UEBhMCQ0gxEDAOBgNVBAoMB1dJU2VLZXkxMDAuBgNVBAMMJ1dJU2VLZXkgUm9vdCBDQSBmb3IgTWF0dGVyIFBLSSAyMDIzMDExNDAgFw0yMzAxMTUwMzAxMjBaGA85OTk5MTIzMTIzNTk1OVowQDEoMCYGA1UEAwwfTWF0dGVyIFBBSSBmb3IgQ29udG9zbyAyMDIzMDExNDEUMBIGCisGAQQBgqJ8AgEMBEZGRjEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASW04hStn+JHWagKgie9fKo6Sp9r0bnHAXBQVxzTmFQLG+T6rFTTugf1zfVybAU8WF5ACno9gVPz+iPfZqUYhPgo2YwZDASBgNVHRMBAf8ECDAGAQH/AgEAMB8GA1UdIwQYMBaAFKRdxF2nJYIxpngKmxG1pqQ6PwCYMB0GA1UdDgQWBBRGb1KAlavce43vNLuH5VkkiPYo/zAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwIDSAAwRQIhAOm8awp7J3u70vc4jShCjbsIL/ySjGGgHVZXcA6ssnWzAiBUDvsVbaK3PZU9yFBJCjRHCvovL/oxUIr9lgJb2VzOmA==j\",\"CD\":\"MIHqBgkqhkiG9w0BBwKggdwwgdkCAQMxDTALBglghkgBZQMEAgEwRQYJKoZIhvcNAQcBoDgENhUkAAElAfH/NgIFiYEYJQM0EiwEE1pJRzIwMTQxWkIzMzAwMDEtMjQkBQAkBgAlB3aYJAgAGDF+MHwCAQOAFGL6gjNZrPqplj4c+hQK3fUE83FgMAsGCWCGSAFlAwQCATAKBggqhkjOPQQDAgRIMEYCIQDtIe2KMsYANYaUboMtzWEsY6NVFG0Z6xPWyXwp5gW3EwIhAI2NyBDByrxD2yH+KgTCjECe7cecm7cSt2OfVc4/FrWs\"}";
int plaintext_len = strlen(plaintext);
// hexstring "3131323233333434353536363737383839393030393938383737363635353434"
unsigned char key[] = {0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x35, 0x36, 0x36, 0x37, 0x37, 0x38, 0x38, 0x39, 0x39, 0x30, 0x30, 0x39, 0x39, 0x38, 0x38, 0x37, 0x37, 0x36, 0x36, 0x35, 0x35, 0x34, 0x34};
int cipher_buf_len = ((plaintext_len + 15) / 16) * 16; // Adjusting the buffer size for the ciphertext
unsigned char ciphertext[cipher_buf_len];
memset(ciphertext, 0, cipher_buf_len);
int ciphertext_len = aes_encrypt((unsigned char *)plaintext, plaintext_len, key, ciphertext);
if (ciphertext_len < 0)
{
printf("Error aes encrypto fail:%d\n", ciphertext_len);
return 1;
}
int encoded_size = 4 * ((ciphertext_len + 2) / 3);
char base64_output[encoded_size];
memset(base64_output, 0, encoded_size);
int ret = base64_encode(ciphertext, ciphertext_len, base64_output, encoded_size);
if (ret < 0)
{
printf("base64_encode error:%d\n", ret);
return 2;
}
printf("%s\n", base64_output);
return 0;
}
```
## Decryptor
- encryptor.c
- build : gcc decryptor.c -o decryptor -lssl -lcrypto
```c
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <string.h>
#include <stdio.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
int aes_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *plaintext)
{
if (!ciphertext || ciphertext_len <= 0 || !key || !plaintext)
return -1;
EVP_CIPHER_CTX *ctx = NULL;
int len = 0;
int plaintext_len = 0;
if (!(ctx = EVP_CIPHER_CTX_new()))
{
plaintext_len = -2;
goto err;
}
if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_ecb(), NULL, key, NULL))
{
plaintext_len = -3;
goto err;
}
if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
{
plaintext_len = -4;
goto err;
}
plaintext_len = len;
if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len))
{
plaintext_len = -5;
goto err;
}
plaintext_len += len;
err:
EVP_CIPHER_CTX_free(ctx);
return plaintext_len;
}
int base64_decode(const char *input, unsigned char *output, int out_len)
{
if (!input || !output || out_len < 0)
return -1;
BIO *bio = NULL;
BIO *b64 = NULL;
int decoded_size = strlen(input) * 3 / 4;
int ret = 0;
bio = BIO_new_mem_buf((void *)input, -1);
if (!bio)
{
ret = -2;
goto err;
}
b64 = BIO_new(BIO_f_base64());
if (!b64)
{
ret = -3;
goto err;
}
bio = BIO_push(b64, bio);
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
int len = BIO_read(bio, output, strlen(input));
if (len < 0)
{
ret = -4;
goto err;
}
ret = len;
err:
BIO_free_all(b64);
return ret;
}
int main(void)
{
char *base64_ciphertext = "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";
unsigned char key[] = {0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x35, 0x36, 0x36, 0x37, 0x37, 0x38, 0x38, 0x39, 0x39, 0x30, 0x30, 0x39, 0x39, 0x38, 0x38, 0x37, 0x37, 0x36, 0x36, 0x35, 0x35, 0x34, 0x34};
int encoded_size = strlen(base64_ciphertext);
unsigned char ciphertext[encoded_size];
memset(ciphertext, 0, encoded_size);
int ciphertext_len = base64_decode(base64_ciphertext, ciphertext, encoded_size);
if (ciphertext_len < 0)
{
printf("Base64 decode error:%d\n", ciphertext_len);
return 1;
}
int plain_buf_len = ciphertext_len;
unsigned char plaintext[plain_buf_len + 1];
memset(plaintext, 0, sizeof(plaintext));
int plaintext_len = aes_decrypt(ciphertext, ciphertext_len, key, plaintext);
if (plaintext_len < 0)
{
printf("AES decrypt error:%d\n", plaintext_len);
return 2;
}
printf("%s\n", plaintext);
return 0;
}
```