# AES
## Week 9
----
## 什麼是 AES
+ Advanced Encryption Standard
+ 中文稱作「進階加密演算法」
+ 由 NIST 於 2001 年發佈
+ 是一種對稱金鑰加密演算法
----
## 什麼是對稱加密
+ Symmetric-Key 對稱金鑰
+ 加密與解密會用到同一個金鑰
+ 有對稱就有非對稱
----
## 什麼是非對稱加密
+ Asymmetric-Key 非對稱金鑰
+ 也可稱為公開金鑰 Public-Key
+ 使用公鑰加密,使用私鑰解密
----
## 術語介紹
+ Encrypt 加密
+ Decrypt 解密
+ Symmetric 對稱
+ Asymmetric 非對稱
+ Cipher 密文
+ Padding 對齊
---
# 對稱加密的運作流程
----
## 對稱加密的事前準備
1. 準備一把主金鑰
+ 可以是 128, 192, 256 位元 (Bits)
+ 分別是 16, 24, 32 位元組 (Bytes)
2. 準備一個 4x4 的位元組矩陣
+ 這個矩陣有 16 個位元組
+ 也被稱為 Initialization Vector (IV)
----
## 對稱加密的運作流程 1
+ Step 1. AddRoundKey
+ 透過主金鑰產生一把回合金鑰 Round Key
+ 用回合金鑰跟原資料做 XOR 加法

----
## 對稱加密的運作流程 2
+ Step 2. SubBytes
+ 透過一個 S-Box 做非線性轉換
+ S-Box 其實就是一個 Mapping Table
+ 但這個 Table 是有精密設計過的

----
## 對稱加密的運作流程 3
+ Step 3. ShiftRows
+ 每一行分別向左偏移 0, 1, 2, 3 格

----
## 對稱加密的運作流程 4
+ Step 4. MixColumns
+ 對每個 Column 做線性變換
$$
\begin{bmatrix}
b_{0,j} \\ b_{1,j} \\ b_{2,j} \\ b_{3,j}
\end{bmatrix} = \begin{bmatrix}
2 & 3 & 1 & 1 \\
1 & 2 & 3 & 1 \\
1 & 1 & 2 & 3 \\
3 & 1 & 1 & 2
\end{bmatrix} \begin{bmatrix}
a_{0,j} \\ a_{1,j} \\ a_{2,j} \\ a_{3,j}
\end{bmatrix}
\qquad 0 \le j \le 3
$$

---
# 實做 AES - Python
----
## Python
+ 安裝 `pycryptodome`
+ `pip install pycryptodome`
----
## 產生金鑰
```python=
from Crypto.Random import get_random_bytes
# Generate 256 Bits Random Key
# 256 Bits = 32 Bytes
key = get_random_bytes(32) # e.g. "\xef\xf6...\xe1\xd1"
```
+ 通常會將此金鑰存成檔案或資料庫內
+ 實務上,會透過公開金鑰將對稱金鑰做加密後再存下來
----
## CBC Mode
+ Cipher Block Chaining
+ 會將明文切成固定大小,所以需要先對資料進行對齊
----
## CBC Mode Encryption
```python=
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
def encrypt(key: bytes, data: bytes):
# 以金鑰搭配 CBC 模式建立 Cipher 物件
cipher = AES.new(key, AES.MODE_CBC)
# 將輸入資料加上 Padding 後進行加密
data_pad = pad(data, AES.block_size)
encrypt_data = cipher.encrypt(data_pad)
return cipher.iv, encrypt_data
```
----
## CBC Mode Decryption
```python=
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
def decrypt(key: bytes, iv: bytes, data: bytes):
# 以金鑰搭配 CBC 模式與 IV 建立 Cipher 物件
cipher = AES.new(key, AES.MODE_CBC, iv=iv)
# 解密後進行 Unpadding
decrypt_data = cipher.decrypt(data)
decrypt_data = unpad(decrypt_data, AES.block_size)
return decrypt_data
```
----
## CFB Mode
+ Cipher Feedback
+ 不需要事先知道完整的明文,所以不需要 Padding
+ 支援 Streaming Encryption
----
## EAX Mode
+ Encrypt & Authenticate Exchange
+ 加密會產生 Nonce 與 Tag,需要一起用來解密
+ 使用 Key 與 Nonce 產生 MAC
+ Message Authentication Code
+ 具有非常高的安全性
----
## Base64
+ Base64 可以將位元組編碼成字串
+ 使位元組可以作為字串傳輸
----
## Base64 Encode
```python=
def ToJSON(data: bytes, iv: bytes) -> dict:
return {
"data": Base64Encode(data),
"iv": Base64Encode(iv)
}
def Base64Encode(b: bytes) -> str:
from base64 import b64encode
return b64encode(b).decode("UTF-8")
```
----
## Base64 Decode
```python=
def FromJSON(ciphertext: dict):
data = Base64Decode(ciphertext["data"])
iv = Base64Decode(ciphertext["iv"])
return data, iv
def Base64Decode(s: str) -> bytes:
from base64 import b64decode
return b64decode(s.encode("UTF-8"))
```
---
# 實做 AES - C 語言
----
## OpenAES
+ [GitHub](https://github.com/jhjin/OpenAES)
----
## 強迫症編譯
+ 為了落實 `-Wall -Werror`
+ `ftime` 為 Deprection 的解法
```c=
#include <sys/timeb.h>
struct timeb timer1;
ftime(&timer1);
#include <time.h>
struct timespec timer2;
clock_gettime(CLOCK_REALTIME, &timer2);
double millitm = timer2.tv_nsec / 1.0e+6;
timer2.tv_nsec = (long int)millitm;
// timer1.time == timer2.tv_sec
// timer1.millitm == timer2.tv_nsec
```
----
## OpenAES Code Flow
```c=
#include "oaes_lib.h"
OAES_CTX *ctx = oaes_alloc();
oaes_gen_key_xxx(ctx);
oaes_key_export(...);
oaes_key_import(...);
oaes_encrypt(...);
oaes_decrypt(...);
oaes_free(&ctx);
```
----
## Detail
+ 實做上 IV 會被覆寫
+ 如果是隨機產生要複製一份存下來
---
## Reference
+ [中文維基:進階加密演算法](https://w.wiki/6Rip)
+ [Wikipedia: AES](https://w.wiki/3m7z)
+ [Python PyCryptodome](https://tinyurl.com/22wkumm8)
{"title":"Week 09 - AES","metaMigratedAt":"2023-06-17T23:13:00.607Z","metaMigratedFrom":"YAML","breaks":true,"description":"地獄貓旅行團第九週心得分享","slideOptions":"{\"transition\":\"slide\"}","contributors":"[{\"id\":\"c7cbb212-2c41-4dfa-8d85-f8e7fa769bf1\",\"add\":5779,\"del\":1434}]"}