許振揚 Jhen-Yung Hsu
6 min readMay 28, 2019

密碼學 — AES(Advanced Encryption Standard) C語言實作

本文中,將介紹一個現代的高強度加解密方法,稱為 Advanced Encryption Standard (AES),並Implement AES algorithm。

先簡介一下AES歷史(參考至Wiki): AES是美國政府公開徵選用來取代 DES 加密法的一種新型加密法,目前已經廣泛用於很多加密標準當中。AES出現原因主要是DES加密法已經被證實為不安全的加密方式,原因有只能一次加密64bit (耗時)、Key僅56bit (不安全)等等。

AES 由美國國家標準與技術研究院(NIST)於2001年11月26日發布於FIPS PUB 197,並在2002年5月26日成為有效的標準。2006年,進階加密標準已然成為對稱金鑰加密中最流行的演算法之一。

接下來,簡介一下實作 AES 需要知道的概念:

本文的 AES 加密,明文區段輸入固定為128 bits,金鑰長度則可以是128,192或256 bits,加密過程中使用的金鑰是由Rijndael金鑰生成方案產生。(註:而 Rijndael 使用的金鑰和區段長度均可以是128,192或256位元。 嚴格地說, AES 和 Rijndael 加密法並不完全一樣(雖然在實際應用中兩者可以互換))

輸入的 128bit 輸入區塊會先做預先處理 — 以每 8 bit切成 16個小區塊

輸入128bit 依序切成 b0, b1, ... b15 (16個 8bit 小區塊),然後重新排列
概念圖如下:
[b0, b1, …., b15] -> [ b0 b4 b8 b12
b1 b5 b9 b13
b2 b6 b10 b14
b3 b7 b11 b15 ]
記得要以column major 來排列

簡介AES 加密主要原理 下面處理皆用上述16個小區塊(byte)處理

AES主要有4大加密函數
1. Add round key - 輸入資料區塊(128 bit) ⊕ 回合金鑰
2. SubBytes - 透過 S-Box 將 每個 Byte 做轉換
3. ShiftRows - 每row中 4 個小區塊進行 circular shift
4. MixColumns - 每column的 4 個小區塊進行 linear transform

AES-128 將有 10 個加密回合, AES-192(12), AES-256(14) [註:round 0不算]

主要加密步驟如下

共有 round 0 ~ round N (( N根據Key長度不同而不同AES-128 (N = 10), AES-192 (N = 12), AES-256 (N = 14)
a. round0 進行下列動作1. AddRoundKey()b. round1 ~ round (N - 1)1. SubBytes()2. ShiftRows()3. MixColumns()4. AddRoundKey()c. round N1. SubBytes()2. ShiftRows()3. AddRoundKey()

解密動作就是將加密動作完全以相反方式執行(不像DES加密,加解密方式完全相同步驟),AES解密動作歸納後如下:

round(回合數)以相反方向開始a. round N 進行下列動作1. AddRoundKey()2. ShiftRows()3. SubBytes()b. round (N - 1)~ round 11. AddRoundKey()2. MixColumns()3. ShiftRows()4. SubBytes()c. round 01. AddRoundKey()

至於Key Expansion的部分請參考reference 這邊就不多贅述

若要深入理解 AES 需要了解除了基本的 可逆函數、線性轉換、 Euclidean algorithm等等,比較困難的是還需要懂Galois Field(GF)的概念 以及GF(²⁸)下如何對多項式進行快速加法與乘法(S-Box製作、MixColumn會使用到)。我在AES 實作上研究比較久的也是在於這部分

懂了大致概念就可以開始實作囉,實作上將加密與解密分為兩個檔案

Input、output(plaintext、ciphertext)格式 =>ASCII 格式,AES每個小區塊為 8 bit,故以軟體實作用char的資料型態很好實作

(先只貼Gist程式碼在此,有空再整理,註解都有寫)

加密檔案:

解密檔案 (AES 加解密極其相似,函數仍有些許不同,但只需稍作修改即可完成),Expanded Key產生則是完全相同,並以相反順序使用Key:

心得:

AES實作我花比較的地方在於理解MixColumn()函數的原理與實作方面。

Key Expanded上理解與實作也花了不少時間 AES-128, AES-192, AES-256 在擴展金鑰上也有些不同差異,這部分有寫在程式碼註解中與reference資料中,應該很好理解,這邊就不解釋了。

基本上其餘部分就不難了(S-Box, SihftRows, AddRoundKey...),且加解密這部分也即為相似,只需改部分程式碼片段即可。

AES相對於較為老舊的 DES 加密法,AES 可以直接在Char(字元)的資料型態上操作,因此在「軟體及硬體」上都可以快速的加解密,軟體實作上也相對減輕了實作難度。

不像 DES,因為基本上軟體中沒有bit的資料型態等等原因,軟體上執行會較慢,只能在「硬體」上快速的加解密,造成在純軟體實作上的速度會過慢。

reference:

1.程式碼部分參考自翻轉工作室(想學習網路相關知識的很推翻轉工作室網站~) : http://www.tsnien.idv.tw/Security_WebBook/security.htm

2. http://www.codedata.com.tw/social-coding/aes/
3. https://en.wikipedia.org/wiki/Rijndael_key_schedule
4. https://en.wikipedia.org/wiki/Rijndael_MixColumns

5. AES-128, AES-192, AES-256, Key Expanded:

http://eportfolio.lib.ksu.edu.tw/user/4/9/4970E011/repository/%E8%B3%87%E8%A8%8A%E5%AE%89%E5%85%A8/Chapter%207-2.ppt

*我的Github連結:

https://github.com/Yunyung/Cryptography-AES-implement-in-C

許振揚 Jhen-Yung Hsu

I am a student in Taiwan, majoring in CSIE @software engineer