This assignment aims to deepen understanding of file system operations and encryption mechanisms by building a simple in-memory file system using the FUSE (Filesystem in Userspace) framework, followed by integrating AES-256 encryption to ensure data security.
Resources:
Assignment: Link
Setting Up FUSE environment
sudo apt-get install fuse libfuse-dev
Building a Basic In-Memory File System with FUSE: Using the FUSE framework, create a simple in-memory file system. This file system should support basic operations such as:
- Create, read, and write files.
- Open and close files.
- Create and remove directories.
- List directory contents.
memfs
memfs/
├── Makefile
├── main.c # 主程式,包含Initlize 和 FUSE 的入口點
├── node.c # 節點操作(如Create, LookUP)相關操作
├── node.h # header file of node.c
├── encryption.c # 與資料加密和解密相關操作
├── encryption.h # header file of encryption.c`
├── operations.c # FUSE 各種函數的實現(如: read, write, mkdir)
├── operations.h # headre file of operations.c
└── memfs.h # global header file,定義核心結構、global vaviable,root等
Makefile
CC = gcc
CFLAGS = `pkg-config fuse3 --cflags` -Wall -g
LDFLAGS = `pkg-config fuse3 --libs` -lssl -lcrypto
SOURCES = main.c node.c encryption.c operations.c
OBJECTS = $(SOURCES:.c=.o)
HEADERS = memfs.h node.h encryption.h operations.h
all: memfs
memfs: $(OBJECTS)
$(CC) $(CFLAGS) -o memfs $(OBJECTS) $(LDFLAGS)
%.o: %.c $(HEADERS)
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f memfs $(OBJECTS)
Makefile 說明:
執行 make 時,會先找到 all,all 依賴於 memfs,所以去執行memfs ,memfs 依賴於 $(OBJECTS),所以實際上會先去檢查所有的.o檔是否存在,
- 如果
.ofile 不在,就先把對應的.c檔編譯成.ofile - 如果
.ofile 存在,就直接執行memfs的生成
pkg-config fuse3 --cflags 及pkg-config fuse3 --libs 表示 provide the compiler the proper arguments to include “fuse3” library.
-Wall 表示啟用所有常用的編譯器警告
編譯成功後會出現一個可執行檔 memfs
將memfs 掛載到 /tmp/memfs
./memfs -f -d /tmp/memfs
-f : 表示讓process在foreground運作。主要目的是在terminal中看到程式的输出,類似於 dmesg (查看kernel 內的訊息)。
-d : Debug模式,可以用來查看更詳細的運作訊息,包含每個指令實際執行到的function、nodeid、pid、error message等等
結束後,在另一個terminal 中輸入:
cd /tmp/memfs
即可開始對file system進行各種操作。
創建新directory
mkdir testdir
可以發現,mkdir 實際上會先去LOOKUP /testdir,得到 error: NO such file or directory,
接下來會真正執行MKDIR 產生 testdir 這個目錄
建立新檔案
touch testfile
在Foreground中會出現:
可以發現創立檔案的流程:
LOOKUP /testfile得到 error: NO such file or directoryCREATE /testfile在nodeid 為 1(root directory)下創建testfileSETATTR對testfile設定一些屬性(如:atimes,mtimes),RELEASE關閉testfile,得到success。
寫入檔案
echo "Hello" > testfile
在Foreground中會出現:
可以發現共寫入6個bytes,"Hello\n" 共6bytes。
讀取檔案
cat testfile
列出directory內容
ls -l
delete file
rm testfile
delete directory
rmdir testdir
- Integrating AES-256 Encryption
- Encrypted with a different key
- Ensure all file operations (read, write, etc.) handle encrypted data correctly
- Testing and Validation
AES-256 Encryption如何運作?
EVP_CIPHER_CTX_new(): returns a pointer to a newly created EVP_CIPHER_CTX for success and NULL for failure.EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)EVP_EncryptUpdate(ctx, *ciphertext, &len, plaintext, plaintext_len)EVP_EncryptFinal_ex(...)EVP_CIPHER_CTX_free(ctx)
Implement a mechanism for managing encryption keys, ensuring that each file can be encrypted with a different key. Design the system so that the encryption key must be supplied to open a file.
寫入時加密: 可以在mount 上資料夾之前,先設幾個斷點,到時候方便檢查是否確實加密
- 讓
memfsmount 上/tmp/memfs:
gdb --args ./memfs -f -d /tmp/memfs
gdb寫入斷點:
break memfs.c:545 // before ending memfs_write()
break memfs.c:456 // before ending memfs_read()
gdb執行程式:
run
在另一邊的terminal 打入:
echo "123456789123456789" > testfile
可以看到自動生成的AES key(32-bits)及IV(16-bits),
停在中斷點後,在 gdb中打入指令,查看memory中的加密資料內容:
x/32bx encrypted_data
可以看到這串資料使用了AES-256加密演算法,且加密資料 encrypted_data 的內容與原始寫入資料: 123456789123456789\n 沒有任何關係
讀取時解密: 若要查看解密資料是否正確
- 先打:
cat testfile
- 停在中斷點後,在
gdb打入指令,查看memory中的解密資料內容:
x/32bx decrypted_data
這次可以看到,解密的資料為正確資料,因為根據ASCII-Table:
1為0x312為0x32- ...
9為0x39\n為0x0a
可以得到結論,寫入的資料經過AES-256加密過後,在未解密的情況下讀取,確實會是一串和原始資料不相關的資料,證實有正確實現加密檔案的動作,
而解密過後的資料decrypted_data 資料為: 123456789123456789\n,確實為寫入資料,因此驗證AES-256在寫入時有正確加密,不夠的位元也有做padding,而在讀取資料時才做解密的動作,且解密資料為寫入資料正確無誤。
測試多個檔案生成不同的key
touch testfile_2
touch testfile_3
Testing and Validation
測試: 若給予錯誤的AES key,是否能解密資料
更改memfs_read() 為:
// Use wrong key to decrypted data
int memfs_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi) {
// ...
// 定義錯誤的 AES 金鑰(與正確金鑰不同)
unsigned char wrong_key[AES_KEY_SIZE] = "wrongkey12345678901234567890abcd";
// 使用錯誤的金鑰進行解密
int decrypted_size = decrypt_data((unsigned char *)node->data, node->size,
wrong_key, node->aes_iv, &decrypted_data);
// ...這個memfs_read()內預設了錯誤的AES key,在讀取時會使用到錯誤的key,
並且return -EIO,所以在command line 會看到 Input/output error
執行結果:
可以看到,使用錯誤的AES key讀取已經加密的資料,無法讀取
卸载file system
fusermount -u /tmp/memfs




















