<!-- 注意上面三行 -->
# Cryptography 01
### by AlanHacker
---
# [前測]()
---
密碼學在做什麼?
---

----
* 學破解別人的密碼
* 學製作勒索病毒
* 學很多炫炮的駭客技術
----
* ~~學破解別人的密碼~~
* 學製作勒索病毒
* 學很多炫炮的駭客技術
----
* ~~學破解別人的密碼~~
* ~~學製作勒索病毒~~
* 學很多炫炮的駭客技術
----
* ~~學破解別人的密碼~~
* ~~學製作勒索病毒~~
* ~~學很多炫炮的駭客技術~~
---
....那在學什麼?
----
* 學習把一句話說成沒人看得懂的樣子
----
* 學習把一句話說成沒人看得懂的樣子
* 學把一坨不知道什麼鬼的東西變回一句話
----
* 學習把一句話說成沒人看得懂的樣子
* 學把一坨不知道什麼鬼的東西變回一句話
* 學一堆很難的數學
----
* 學習把一句話說成沒人看得懂的樣子
* 學把一坨不知道什麼鬼的東西變回一句話
* 學一堆很難的數學
* ~~學不要用 base64 加密身分證字號~~
----

----
Crypto 真好玩~
---
## Outline
* Overview
* 加密?編碼?雜湊?
* 何謂安全
* 常用編碼練習
* 古典加密
* Overview
* 單表代換加密
* 多表代換加密
---
# Overview
---
## 加密?編碼?雜湊?
----
* 加密:將資訊轉換成無法理解的³_iÇ+?Í
* 解密:將無法理解的³_iÇ+?Í轉換成資訊
----
* ~~加密:將資訊轉換成無法理解的³_iÇ+?Í~~
* ~~解密:將無法理解的³_iÇ+?Í轉換成資訊~~
* 不只這樣!
----
* 加密(encrypt):
* 將資訊藉由**金鑰**(key)轉換成密文
* 解密(decrypt):
* 將密文藉由**金鑰**(key)轉換成資訊
----
* 加密(encrypt):
* 將資訊藉由**金鑰**(key)轉換成密文
* 解密(decrypt):
* 將密文藉由**金鑰**(key)轉換成資訊
* 金鑰是密文唯一的變數
* 金鑰是加密變得無法破解的**唯一防線**
----
* 加密(encrypt):
* 將資訊藉由**金鑰**(key)轉換成密文
* 解密(decrypt):
* 將密文藉由**金鑰**(key)轉換成資訊
* 金鑰是密文唯一的變數
* 金鑰是加密變得無法破解的**唯一防線**
* 今天的主角
----
* 編碼(encode):將資訊「翻譯」成編碼文字
* 解碼(decode):將編碼文字「解譯」成資訊
----
* 編碼(encode):將資訊「翻譯」成編碼文字
* 解碼(decode):將編碼文字「解譯」成資訊
* 有轉換規則就可以隨便加解碼,**沒有安全性可言**
----
* 編碼(encode):將資訊「翻譯」成編碼文字
* 解碼(decode):將編碼文字「解譯」成資訊
* 有轉換規則就可以隨便加解碼,**沒有安全性可言**
* Example:中文 -> 英文、英文 -> 中文
----
* 雜湊(Hash):對資訊做「特徵摘要」
----
* 雜湊(Hash):對資訊做「特徵摘要」
* 一對一單向函式,**不可逆**
----
* Example:
* 定義:Hash(人)=身高+體重+生日(年/100+月+日)+存款
* Bob 同學
* 身高 170 cm
* 體重 65 kg
* 生日 1989.6.4
* 存款 32767 NT
* Hash(Bob) = 170+65+1989+6+4+32767 = 35001
---
## 常用編碼練習
----
1. ASCII 編碼
* 把英文字+一些常用字符轉成數字方便電腦處理
* 一個字元二進位下佔 8 位 = 1 byte(位元組)
* Example: A => 65
* 儘管被取代(Unicode),但編碼方式被沿襲下去
----

----
* python 轉換方式
* chr() 把數字轉成字元
* ord() 把字元轉成數字
```python=
ord('A') # 65
chr(65) # 'A'
```
----
### Lab:ASCII practice
```
65 115 99 73 73 115 79 69 97 115 89
```
----
2. 進位轉換
* 2 進位(Binary)
* 電腦只會這個
* 8 進位(Octal)
* 大家都去看 16 進位了
* 還是會用到...?
* 10 進位(Decimal)
* 生活中常用
* 16 進位(Hexadecimal)
* Programmer、Hacker 常用
----
* n 進位代表逢 n 進位
* 代表只有 n 個數字能用
* 2 進位在 python 中前面會加上 0b
* 8 進位在 python 中前面會加上 0o
* 16 進位在 python 中前面會加上 0x
----
* n 進位轉 10 進位
* 2 進位
* $\text{0b}1011=1\cdot 2^3+0\cdot 2^2+1\cdot 2^1+1\cdot 2^0=19$
* 8 進位
* $\text{0o}131=1\cdot 8^2+3\cdot 8^1+1\cdot 8^0=89$
* 10 進位
* $8964 = 8\cdot 10^3+9\cdot 10^2+6\cdot 10^1+4\cdot 10^0$
* 16 進位
* $\text{0x7c5}=7\cdot 16^2+c\cdot 16^1+5\cdot 16^0=1989$
----
* 剛剛 16 進位的 $c$ 是啥?
----
* 剛剛 16 進位的 $c$ 是啥?
* 因為是 16 「進位」,需要表示 10 ~ 15
* 所以用 a ~ f 表示
----

----
* 10 進位轉 n 進位
* 設數字 $a$ 在 n 進位下有 $k$ 位數
* $a=a_k\cdot n^{k-1}+a_{k-1}\cdot n^{k-2}+\cdots+a_1\cdot n^0$
----
* 10 進位轉 n 進位
* 設數字 $a$ 在 n 進位下有 $k$ 位數
* $a=a_k\cdot n^{k-1}+a_{k-1}\cdot n^{k-2}+\cdots+a_1\cdot n^0$
* $a\!\!\!\mod n=a_1$
----
* 10 進位轉 n 進位
* 設數字 $a$ 在 n 進位下有 $k$ 位數
* $a=a_k\cdot n^{k-1}+a_{k-1}\cdot n^{k-2}+\cdots+a_1\cdot n^0$
* $a\!\!\!\mod n=a_1$
* $\lfloor\frac{a}{n}\rfloor=a_k\cdot n^{k-2}+a_{k-1}\cdot n^{k-3}+\cdots+a_2\cdot n^0$
* $\lfloor\frac{a}{n}\rfloor\!\!\!\mod n=a_2$
* $\cdots$
----
* 10 進位轉 16 進位
* $8964\!\!\!\mod 16=4$
* $\lfloor\frac{8964}{16}\rfloor=560$
* $560\!\!\!\mod16=0$
* $\lfloor\frac{560}{16}\rfloor=35$
* $35\!\!\!\mod16=3$
* $\lfloor\frac{35}{16}\rfloor=2$
* $2\!\!\!\mod16=2$
* $\lfloor\frac{2}{16}\rfloor=0$
----
* 10 進位轉 16 進位
* $8964=\text{0x2304}$
----
* Python 3 中的取餘數為 % 、向下取整除法為 //
```python=
print(5 % 3) # 2
print(5 // 3) # 1
```
----
* Python 中進位轉換的函式
```python=
# int() 能把任何進位的數字字串轉成 10 進位
int("11100110" , 2) # 230
int("deadbeef", 16) # 3735928559
# bin() 能把數字轉成 2 進位
bin(231) # 0b11100111
# oct() 能把數字轉成 8 進位
oct(1234) # 0o2322
# hex() 能把數字轉成 16 進位
hex(57894) # 0xe226
```
----
### Lab:numeric practice
```
請將 821091 轉成 16 進位
請將 0o337522 轉成 10 進位
請將 0b110011010 轉成 10 進位
```
----
3. 組合技(ASCII + 16 進位)
* 2 進位對電腦較友善
* 16 進位對人較友善(相對)
* 2 進位和 16 進位轉換很方便
* 8 位 2 進位轉成 16 進位長度統一 2 位
* 那就用 16 進位表示 ASCII 吧!
----
* 16 進位 v.s. 2 進位
* $16=2\cdot2\cdot2\cdot2$
* 4 個 2 進位的數能表示 16 種數字
* 1 個 16 進位的數能表示 16 種數字
* 1 個 16 進位能轉成 4 個二進位!
* 2 個 16 進位剛好表達 1 個 byte(位元組)
----
```python=
ord('A') = 65 = 0b01000001 = 0x41
ord('B') = 66 = 0b01000010 = 0x42
ord('C') = 67 = 0b01000011 = 0x43
```
----
* 可以把一句話中每個字轉成 16 進位表示
* 在串接在一起變成一個超大 10 進位整數
```python=
sentence = "Hello there"
hex_string = ""
for c in sentence:
hex_string += hex(ord(c))[2:]
print(int(hex_string, 16)) # 87521618088882658227876453
```
* 密碼學常用技巧
----
* 其實用 `bytes.fromhex()` 和 `bytes.hex()` 配合 `int()` 也可以做到同樣的事
```python=
sentence = b"Hello there"
num = int(sentence.hex(), 16)
print(num) # 87521618088882658227876453
print(bytes.fromhex(hex(num)[2:])) # b'Hello there'
```
----
### Lab:Big Integer
```
cipher = 1001379969218778717835149010429266
```
----
4. Base64
* 將**二進位資料**用 64 個可列印字元表達
* [A-Z][a-z][0-9][+/]
* = 作為填充
----
4. Base64
* base 家族有很多種編碼
* base16/32/64
* 16 進位 = base16
* base58(Bitcoin、去掉易混淆的符號)
* base85
----
* python 中的字串資料型態 `str`
* python 中的二進位資料型態 `bytes`
----
* python 中的字串資料型態 `str`
* python 中的二進位資料型態 `bytes`
```python=
my_str = "hello str"
my_bytes = b"hello bytes"
# str to bytes
my_str.encode()
# bytes to str
my_bytes.decode()
```
----
* base64 v.s. 2 進位
* $64 = 2\cdot 2\cdot 2\cdot 2\cdot 2\cdot 2$
* 所以一個 base64 編碼可以表示 6 位數 2 進位
----
* ascii 1 個字佔 1 byte
* 通常文字佔據的資料長度都為 bytes 的倍數
* example:
```
len("hello there") # 11 個字
len("你好呀!") # 4 個字
len("hello there".encode()) # 11 bytes
len("你好呀!".encode()) # 12 bytes
```
* $\frac{11}{6}=1\cdots 5$
* $\frac{12}{6}=2\cdots 0$
* 有時候長度無法對齊!
----
* 那就想辦法對齊就好啦!

* 位元數非 6 的倍數、或 Bytes 數非 3 ($3\times 8=24$)的倍數
* 就往後補 0 ,填充位元用 = 表示
----
* python base64
```python=
from base64 import b64encode, b64decode
b64_str = b64encode(b"abcdefg")
print(b64_str) # b'YWJjZGVmZw=='
print(b64decode(b64_str)) # b'abcdefg'
```
----
* python 中手打二進位資料 `\x??`
```python=
binary = b"\x41\x42\x0a\x43\x44"
print(binary) # b'AB\nCD'
print(binary.decode())
# AB
# CD
```
----
* base64 處理二進位資料
```python=
from base64 import b64encode, b64decode
binary = b"\x41\x42\x0a\x43\x44"
print(b64encode(binary)) # b'QUIKQ0Q='
```
* 這才是 base64 本來的用途!
* ~~別拿來加密東西~~
----
* python 中讀寫檔案:`open(filename, mode)`
* filename:檔案名稱
* mode:定義打開檔案的方式
* r:預設。讀取檔案
* w:寫入檔案
* rb、rw:以二進位模式讀取、寫入檔案
----
* python 中讀寫檔案:`open(filename, mode)`
```
with open("test.txt", "r") as f:
f.read() # 讀檔,str 型態
with open("filename", "w") as f:
f.write() # 寫檔,只允許 str 型態
with open("test.txt", "rb") as f:
f.read() # 讀檔,bytes 型態
with open("filename", "wb") as f:
f.write() # 寫檔,只允許 bytes 型態
```
----
### Lab:encode Misc Challenge
hint 1:Big Integer + base64
hint 2:jpg
```pyt=
import sys
sys.set_int_max_str_digits(500000) # 數字太長,需要這行
```
[Download Here](https://drive.google.com/file/d/1ezJd1_6RXapxdoihDTzQkyPG03aBbEY9/view?usp=sharing)
---
## 何謂安全
----
* 加密演算法:利用金鑰,將明文轉換成難以理解的密文
* 解密演算法:利用金鑰,將密文轉換回有意義的明文
----
### 資訊安全 CIA 三要素
* Confidentiality(機密性)
* Integrity(完整性)
* Authentication(認證性)
----
### 資訊安全 CIA 三要素
假設小明和小華正在進行一場安全的加密對話
* Confidentiality(機密性)
* 駭客無法解讀小明和小華的加密對話內容
* Integrity(完整性)
* 小明將自己的銀行帳號傳給小華,讓小華匯錢
* 駭客無法竄改訊息讓銀行帳號變自己的
* Authentication(認證性)
* 小明和小華彼此都能確定對方身分,而非駭客偽裝的
----
### 柯克霍夫原則(Kerckhoffs's principle)
* 即便做不到數學上不可破解,系統也應在實際層面上無法破解
* 系統內不應含任何機密物,即使落入敵人手中也不會造成困擾
* 密鑰必須易於溝通和記憶,而不須寫下;且雙方可以容易的改變密鑰
* 系統應可以用於電訊
* 系統應可以攜帶,應只要一個人就能使用
* 系統應容易使用,不致讓使用者的腦力過份操勞,也無需記得長串的規則
----
### 柯克霍夫原則(Kerckhoffs's principle)
簡單來說...
----
### 柯克霍夫原則(Kerckhoffs's principle)
* 就算數學上系統能被破解,但如果破解成本夠高,實際上還是安全的
* 確保就算加密演算法被公開,系統安全性仍不變
----
# 不要自己發明加密演算法
----
* 系統在加密上會被破解,通常都不是加密演算法的問題
* 而是用它的人的問題
----

----
* 密碼不是靠暴力破解
* 而是靠旁道攻擊(Side channel attack)
----

---
## 古典加密
---
### Overview
----
* 替換式密碼(Substitution ciphers)
* 位移式密碼(Transposition ciphers)
----
* 替換式密碼(Substitution ciphers)
* 將每個字母代換成其他字母
* Example: i => c, j => n, k = m
* Example: ijk => cnm
* 位移式密碼(Transposition ciphers)
----
* 替換式密碼(Substitution ciphers)
* 位移式密碼(Transposition ciphers)
* 字母本身不變
* 按照某種規則改變明文的排列
* Example: 1234 => 1324
* Example: abcd => acbd
----
* 替換式密碼(Substitution ciphers)
* 單表替換加密
* 凱薩密碼(Caesar Cipher)
* 簡單替換密碼(Simple Substitution Cipher)
* 多表替換加密
* 維吉尼亞密碼(Vigenère square)
* 位移式密碼(Transposition ciphers)
* 籬笆密碼法(Rail Fence cipher)
* 密碼棒(Scytale)
---
### 工具介紹
----
### 攻擊手法
* 密鑰可能性少 => 暴力硬幹
* 密文夠長 => 詞頻分析相關攻擊
----
### 詞頻分析相關攻擊?
----
* 分析字母出現的頻率,與對應語言的頻率比較
* [英文的字母頻率](https://www3.nd.edu/~busiforc/handouts/cryptography/Letter%20Frequencies.html#Relative_frequencies_of_letters)
* Example:如果密文中 `"x"` 的頻率與英文中的 `"a"` 相近,可以猜測 `"x" = "a"`
* 對**大部分古典加密**都有用
----
### 種類
* frequency alanysis
* 分析「單字」頻率,與對應語言頻率比較
* 秒殺單表替換加密
* 就算是多表也能分析出密鑰長度、加密類型
* 有一次統計一個字、有[兩個字(Bigram)](https://pi.math.cornell.edu/~mec/2003-2004/cryptography/subs/digraphs.html)、[三個字(Trigram)](https://en.wikipedia.org/wiki/Trigram)
* Index of Coincidence(重合指數)
----
### 種類
* frequency alanysis
* Index of Coincidence(重合指數)
* 分析隨機兩字母的重合機率
* 算是統計「整體」字母分布
* 自然語言不隨機,重合率偏高(英文:0.0667)
* 若密文 IC >= 自然語言:單表替換、位移式密碼
* 若密文 IC << 自然語言:多表替換
----
### 種類
* frequency alanysis
* Index of Coincidence(同步指數)
* 主要用途
* 判斷加密類型
* 判斷密鑰長度
----
* [dCode.fr](https://www.dcode.fr/):一個一大堆奇怪古典加密工具的網站
* [當你要算 IC 值](https://www.dcode.fr/index-coincidence)
* [當你想 frequency analysis](https://www.dcode.fr/frequency-analysis)
* [當你看到奇怪的加密符號](https://www.dcode.fr/symbols-ciphers)
* [當你想知道密文是哪種加密](https://www.dcode.fr/cipher-identifier)
---
### 替換式密碼(Substitution ciphers)
----
### 單表替換加密
----
* 凱薩密碼(Caesar Cipher)
* 將明文在單字表中的位置向後偏移固定數目
* 超出單字表重新從 `"A"` 開始
* Example(key = 3):
* 明文:ABYZ
* 密文:DEBC
* key = 13 時被稱為 ROT13
* key = 47 時被稱為 ROT47
----
* 凱薩密碼(Caesar Cipher)

----
* 攻擊方向
* 嘗試 key 的所有可能(通常就 26 種)
* 肉眼找明文 or 頻率分析找最有可能的
* ~~靠工具~~
----
* 工具
* [當單字表只有字母和數字](https://www.dcode.fr/caesar-cipher)
* [當單字表包含 ascii 所有可列印字元](https://www.dcode.fr/rot-cipher)
* [當你想換個口味時(guess key 功能不錯)](https://www.xarg.org/tools/caesar-cipher/)
* [單表替換通用工具 1](https://www.dcode.fr/monoalphabetic-substitution)、[單表替換通用工具 2](https://www.guballa.de/substitution-solver)、[單表替換通用工具 3](https://quipqiup.com/)
----
* Python Script
```python=
def encrypt(pt:str, key:str, charset:str):
cipher = ""
for char in pt:
if char in charset:
index = charset.index(char)
cipher += charset[(index + key) % len(charset)]
else:
cipher += char
return cipher
from string import ascii_lowercase as charset
encrypt("hello", 3, charset)
# khoor
```
----
* 簡單替換密碼(Simple Substitution Cipher)
* 密鑰為單字表的排列
* 加密時,單字轉換成密鑰對應位置的單字
----
* 簡單替換密碼(Simple Substitution Cipher)

----
* 攻擊方向
* 通常單字表長度為 26,硬幹總共 $26!=4.0329146\times10^{26}$ 個排列實在不是個好主意....
* 頻率分析!
----
* 工具
* [單表替換通用工具 1](https://www.dcode.fr/monoalphabetic-substitution)
* [單表替換通用工具 2](https://www.guballa.de/substitution-solver)
* [單表替換通用工具 3](https://quipqiup.com/)
----
* Python Script
```python=
def encrypt(pt:str, key:str, charset:str):
cipher = ""
dictionary = dict(zip(charset, key))
for i in pt:
if i in charset:
cipher += dictionary[i]
else:
cipher += i
return cipher
from string import ascii_lowercase as charset
key = 'nzhkgqwuvprlxyoijtmscabefd'
encrypt("hello", key, charset)
# ugllo
```
----
### Lab:Caesar Cipher
```
# 請嘗試解密 cipher
cipher = "VTXLTKVBIAXKATVDXKWBLVHOXKLMAXABWWXGLXVKXML"
```
----
### Lab:Simple Substitution Cipher
```
# 請嘗試解密 cipher
cipher = "EHOLKOVSDFWKRWSMSKSMVZDOSSOHWPIXOWBHFGSNTIBXOHOQIPMVOGISSOHVWIVJHOUOIDSTOWOBHOSPOWWIZOCMSTMVBNJO"
```
----
### 多表替換加密
----
* 維吉尼亞密碼(Vigenère cipher)
* 一系列的 Caesar 組合的簡單多表加密
* 加密時根據表格生成密文
* 差異
* Caesar:文字偏移量固定
* Vigenère:文字偏移量由對應的 key 決定
* 密鑰長度小於明文會自動擴展到相同長度
----
* key = `"KEY"`
* 明文:
* `UNITED STATES`
* key stream:
* `KEYKEY KEYKEY`
* 密文:
* `ERGDIB CXYDIQ`
----

----
* 攻擊方向
* 暴力不用想了
* 卡西斯基試驗
* 常出現的單詞 (e.g. the) 有可能被同樣的密鑰部分加密
* 如果能找到多組重複的密文,就有機會猜出密鑰長度
* 弗里德曼試驗
* 頻率分析
----
* 攻擊方向
* 暴力不用想了
* 卡西斯基試驗
* 弗里德曼試驗
* 使用Index of Coincidence(重合指數)估計密鑰長度
* 可作為卡西斯基試驗的補充
* 頻率分析
----
* 攻擊方向
* 暴力不用想了
* 卡西斯基試驗
* 弗里德曼試驗
* 頻率分析
* 知道密鑰長度
* 將密文寫成多列,列數與密鑰長度對應
* 每列可視為凱薩加密、偏移量為密鑰對應的字母
----
* 攻擊方向
* 善用現有線索
* 是否有已知的明文?(e.g. dear???)
* 是否有已知的密鑰?(e.g. key???)
* 如果頻率分析結果部分錯誤、想辦法通靈錯誤的字(e.g. mo?ey -> money)
----
* 工具
* [dCode](https://www.dcode.fr/vigenere-cipher)
* [codebreaker](https://www.mygeocachingprofile.com/codebreaker.vigenerecipher.aspx)
* [guballa](https://www.guballa.de/vigenere-solver)
* [quipquip](https://quipqiup.com/)
----
* Python Script
```python=
def encrypt(pt:str, key:str, charset: str):
cipher = ""
i = 0
for c in pt:
if c in charset[0]:
index = ord(key[i % len(key)]) - ord("A")
cipher += charset[index][ord(c) - ord('A')]
i += 1
else:
cipher += c
return cipher
from string import ascii_uppercase
charset = [ascii_uppercase[i:len(ascii_uppercase)] + ascii_uppercase[0:i] for i in range(26)]
print(encrypt("HELLO", "KEY", charset))
# RIJVS
```
----
### Lab:Vigenère cipher
hint:Index of Coincidence
```
# 請找出加密的 key
cipher = "KVCFNDIDJEYJDYSHKAJUWOEBNMBSMXPORTHKXHOUYIYLUWLYEHNVNEDDXKPGVZIRQSFTDIIMVEENEYZXHMUCQCFNDJWZCTOSFKJUHJKPAOMNEDUDQPOBFKPEGVHQNUHFWHTVOLIDIBNGPDDUUCLJIOBWJWEBJALJQRMCFHTSTJDYVJOHXGPJVCUCZOGHYFPODZJOIHNRCHQRVCGYXYHHJXAMKHFYFZSPRSVFCUPNVRNDRMMKCXELYWZMJEUCJAASFFTRNDELFCYSUWGJNWWUVLHNQCQBOSXSIUPMZOEMKAPLNVCCFCYBYJWZMTJFZGUAUOYARWMHQCTVNLFNPHFYFVOZESTPJETIYEDDCHYMPDWFGCYYXUXMXLLSZOTZAWKRBBXMKDSMZOUDRKDRCOUPGVXSUWGJNEEKCBDTQOVPRSHSUXJIYCACPXLXUGQRRFMMUBXAZZBSYXYKIMEGFGMNBBHVYWUBIBAVNZTZLHAJCQCVXWARFYDKIMUENHBTDQCYOSABYTTTUJVBVGVWYCXIVEENEHYKJPDBESWDUQGNGLPDIMSKPZWPBZBAUIDIVWKMVEJOUGQLQCYUELTMOJEMKAPSKYIRBTTAQIIJXPWMFYXGVZHGNZIWEIEZMTPXFGPNWITPRRRJQHHGVEAQKAPTGBHMVGLYYBAGVYCTZLSOPBYLGVXHEHCZMDKERFPXKXQLFCVNUJNVIOBHEWDNKHICYTTSUNXGZTJGZLZCPGQLQGHBUXPQZNKLVAPXGOEBNMMTTHPHVEEYVTDNCHUDHZVTDTXODZJHETDKPNUURVTAUSDHZEKNLKYGVDELFQTUYJPGOZYZJALIJZSIJVXSJXTVMNDHKXNZUJVMHFKJFKQGDNSQFMPZJZCYTBBKYSTIOHKQULZLVCUABBLYYJJODZJZEWENGYUAYOKFJYDIJQEMUXAKPYULPSMMUOLZMPOHXGTTIVFPBABXIEGTIZPDKHHNKXXCISKDQCTMDNWMNTDZQAQJYVXNHJWDNYKSVPLYCKHMZWLJJXPOVWHLVGJKUWBYPYFJDQHRZWHZJPSOVZCCAKHZBTQZBFWQRGEKGYJFRIGFBYTIVMHDIBRNVNEDYWYJBYQZMEUZEWENGKKPFIBYEVWVKAEMVLD"
```
---
### 位移式密碼
* 通常都基於幾何來設計
* 透過 IC 判斷 + 排除法後可以確定
----
* 籬笆密碼法(Rail Fence cipher)
* 又稱 zig zag cipher
* 在矩陣中 V 型的填入明文
* 最後水平閱讀則成密文
* key = 列數、下圖 key = 3

----
* 攻擊方向
* 這其實算挺弱的密碼,因為列數最多不能超過總字數
* 靠工具解就好
----
* 工具
* [dCode](https://www.dcode.fr/rail-fence-cipher)
----
* 密碼棒(Scytale)
* 由左到右填入明文、由上到下閱讀密文
* key = 行數
* 可以想成是籬笆密碼的變體
* 明文:"HELPMEIAMUNDERATTACK"
* 密文:"HENTEIDTLAEAPMRCMUAK"
```
加密:
H E L P M
E I A M U
N D E R A
T T A C K
解密:
H E N T
E I D T
L A E A
P M R C
M U A K
```
----

----
* 攻擊方向
* 這也密碼也挺弱的
* 一樣靠工具解
----
* 工具
* [dCode](https://www.dcode.fr/scytale-cipher)
---
### 還有其他加密法嗎?
* 各種圖案替換加密法、隱寫術
* Bacon's cipher
* Dancing men
* Pigpen cipher
* ....
----
### 還有其他加密法嗎?
* Playfair Cipher
* Hill Cipher
* ...
----
### Advanced Resource
* [CryptoHack](https://cryptohack.org/)
* [SCIST 資訊安全課程](https://www.youtube.com/playlist?list=PLN7NYsAnUHW5JXCB0gR_1Ny8XOEa7K2PO)
* 李榮三教授和魏國瑞教授的密碼學
---
# [後測]()
---
{"title":"Crypto 01","slideOptions":"{\"theme\":\"night\",\"transition\":\"fade\"}","description":"abc","contributors":"[{\"id\":\"b700cab6-685f-4ba8-87b8-088044d9367d\",\"add\":18209,\"del\":1596}]"}