Tải bản đầy đủ (.pdf) (25 trang)

Cài đặt thuật toán AES 128

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.27 MB, 25 trang )

HỌC VIỆN KỸ THUẬT MẬT MÃ
KHOA AN TOÀN THÔNG TIN


BÁO CÁO BÀI TẬP LỚN MÔN HỌC
MẬT MÃ HỌC NÂNG CAO
Chủ đề số 14
CÀI ĐẶT THUẬT TOÁN AES - 128

Giảng viên:

TS. Nguyễn Tuấn Anh

Thực hiện:

Sinh viên lớp AT9B

1. Đỗ Huy Hùng
2. Nguyễn Thành Đạt
3. Nguyễn Thị Thêu

HÀ NỘI, 2016


MỤC LỤC
BẢNG KÝ HIỆU ...................................................................................................... 2
DANH MỤC BẢNG BIỂU ...................................................................................... 2
DANH MỤC HÌNH VẼ ........................................................................................... 2
LỜI NÓI ĐẦU .......................................................................................................... 3
CHƯƠNG I. GIỚI THIỆU VỀ AES – Advanced Encryption Standard............ 4
1.1. Lịch sử AES. ................................................................................................. 4


1.2. Sơ lược về thuật toán AES. .......................................................................... 4
CHƯƠNG II. CẤU TẠO, HOẠT ĐỘNG CỦA AES............................................ 5
2.1 Thông số thuật toán .......................................................................................... 5
2.2. Quá trình mã hóa. ............................................................................................ 5
2.2.1

Phép thay thế byte (SubBytes). .............................................................. 6

2.2.2

Phép dịch hàng (ShiftRows)................................................................... 8

2.2.3

Trộn cột (MixColumns) ......................................................................... 8

2.2.4

Cộng khóa vòng (AddRoundKey). ........................................................ 9

2.3. Quá trình mở rộng khóa. ............................................................................... 10
2.4. Quá trình giải mã........................................................................................... 11
2.4.1. Dịch hàng nghịch đảo (InvShiftRows)................................................. 12
2.4.2. Thay thế byte nghịch đảo (InvSubBytes). ............................................ 13
2.4.3. Trộn cột nghịch đảo (InvMixColumns). .............................................. 13
2.4.4. Cộng khóa vòng (AddRoundKey) trong giải mã. ................................ 14
2.5. Quá trình giải mã ngược. ............................................................................ 14
CHƯƠNG III. PHÂN TÍCH, THIẾT KẾ CHƯƠNG TRÌNH .......................... 16
3.1. Giới thiệu chương trình ................................................................................. 16
3.2. Cấu trúc chương trình ................................................................................... 16

3.3. Xây dựng các phương thức chính. ................................................................ 17
3.3.1. AESUtils.java.......................................................................................... 17
3.3.2. AES.java ................................................................................................. 19
CHƯƠNG IV. KIỂM TRA TÍNH ĐÚNG ĐẮN CỦA CHƯƠNG TRÌNH ...... 21
4.1 Nguồn dữ liệu. ................................................................................................ 21
4.2. Kiểm tra tính đúng đắn.................................................................................. 21
KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN ............................................................ 24
TÀI LIỆU THAM KHẢO ..................................................................................... 24
Cati đ

1


BẢNG KÝ HIỆU
AES Advanced Encryption Standard
NIST National Institute of Standard and Technology
FIPS Federal Information Processing Standards
DES Data Encryption Standard
ECB Electronic Codebook
CBC Cipher Block Chaning
OFB Output Feedback
CFB Cipher Feedback
DANH MỤC BẢNG BIỂU
Bảng 2. 1. Bảng thông số của AES ........................................................................... 5
Bảng 2. 2 Bảng thay thế byte (S-box) ....................................................................... 7
Bảng 2. 3. Inverse S-box: Bảng thay thế các byte nghịch đảo................................ 13
Bảng 4. 1 Bảng “test vector” cho AES - 128 .......................................................... 21
DANH MỤC HÌNH VẼ
Hình 2. 1 Giải thuật mã hóa AES .............................................................................. 6
Hình 2. 2 Mô tả phép biến đổi SubByte() ................................................................. 7

Hình 2. 3 Mô tả quá trình ShiftRows ........................................................................ 8
Hình 2. 4 Mô tả phép biến đổi MixColumns ............................................................ 9
Hình 2. 5. Mô tả phép biến đổi AddRoundKey ...................................................... 10
Hình 2. 6. Thuật toán mở rộng khóa ....................................................................... 11
Hình 2. 7. Thuật toán giải mã AES ......................................................................... 12
Hình 2. 8. Mô tả phép biến đổi InvShiftRows()...................................................... 12
Hình 2. 9. Thuật toán giải mã ngược....................................................................... 15
Hình 3. 1 Giao diện chương trình ........................................................................... 16
Hình 4. 1 Test vector 1 ............................................................................................. 21
Hình 4. 2 Test Vector 2 ........................................................................................... 22
Hình 4. 3 Nội dung file encrypt.txt ......................................................................... 22
Hình 4. 4 Nội dung file decrypt.txt ......................................................................... 23
Hình 4. 5 Test vector 3 ............................................................................................ 23

Cati đ

2


LỜI NÓI ĐẦU
Với tốc độ và khả năng xử lý ngày càng được nâng cao của các bộ vi xử lý
hiện nay, phương pháp mã hóa chuẩn (DES - Data Encryption Standard) đã trở nên
không an toàn trong bảo mật thông tin. Do đó, Viện tiêu chuẩn và công nghệ Hoa
kỳ (NIST - National Institute Standards of Technology) đã quyết định chọn một
chuẩn mã hóa mới với độ an toàn cao nhằm phục vụ nhu cầu bảo mật thông tin liên
lạc của Chính phủ Hoa Kỳ cũng như trong các ứng dụng dân sự. Thuật toán
Rijndael do Vincent Rijmen và Joan Daeman đã được chính thức chọn trở thành
chuẩn mã hóa nâng cao (AES - Advanced Encryption Standard) từ ngày 02 tháng
10 năm 2000.
Với sự phát triển ngày càng nhanh chóng của Internet và các ứng dụng giao

dịch điện tử trên mạng, nhu cầu bảo vệ thông tin trong các hệ thống và ứng dụng
điện tử ngày càng được quan tâm và có ý nghĩa hết sức quan trọng. Vì thế việc
nghiên cứu về chuẩn mật mã nâng cao và ứng dụng nó trong các lĩnh vực bảo mật
thông tin là rất cần thiết.
Báo cáo gồm 4 chương :
CHƯƠNG I. GIỚI THIỆU VỀ AES : Chương này giới thiệu về lịch sử ra đời
của AES, mô tả sơ lược về thuật toán.
CHƯƠNG II. CẤU TẠO, HOẠT ĐỘNG CỦA AES: Mô tả các thông số của
AES ứng với độ dài khóa 128, 192, hoặc 256 bits. Trình bày chi tiết thuật toán mã
hóa, giải mã, và mở rộng khóa bao gồm các phép biến đổi SubBytes, ShiftRow, …
CHƯƠNG III. PHÂN TÍCH, THIẾT KẾ CHƯƠNG TRÌNH: Giới thiệu về
chương trình mã hóa, giải mã một khối. Code chi tiết các phương thức chính.
CHƯƠNG IV. KIỂM TRA TÍNH ĐÚNG ĐẮN: Sử dụng “test vector” cho
AES được công bố bởi NIST để kiểm tra tính đúng đắn của chương trình.
Trong quá trình tìm hiểu, do hiểu biết còn hạn chế, kiến thức thực tế chưa có
nhiều, nên chúng em không tránh khỏi những thiếu sót sai lầm. Rất mong được sự
góp ý của thầy cô và các bạn. Chúng em xin cám ơn thầy TS. Nguyễn Tuấn Anh
đã nhiệt tình hướng dẫn chúng em hoàn thành bài báo cáo này.
Chúng em xin chân thành cảm ơn!

Cati đ

3


CHƯƠNG I. GIỚI THIỆU VỀ AES – Advanced Encryption Standard
1.1.

Lịch sử AES


Vào năm 1997, Viện tiêu chuẩn và công nghệ quốc gia Mỹ (NIST) đã phát
động một cuộc thi nhằm xây dựng một chuẩn mã dữ liệu mới thay thế cho chuẩn
mã dữ liệu cũ DES đã được đưa ra vào năm 1974 (Khi họ cho rằng độ dài khóa của
DES là không an toàn và đã có một hệ thống thám mã DES phá được khóa DES
trong thời gian 2 ngày).[1]
Đến khoảng tháng 8 năm 1998, đã có 15 thuật toán được đưa ra cho NIST lúc
bấy giờ. Khoảng 1 năm sau, đã có 5 thuật toán được chọn. Quá trình tuyển chọn
cuối cùng kéo dài đến tháng 10 năm 2000, NIST đã công bố chuẩn mã dữ liệu mới
được lựa chọn là thuật toán Rijndeal (thuật toán mã khối).
Thuật toán được thiết kế bởi hai nhà mật mã học người Bỉ: Joan
Deaman và Vincent Rijmen. Thuật toán được đặt tên là "Rijndael" khi tham gia
cuộc thi thiết kế AES. [2]
1.2.

Sơ lược về thuật toán AES

Mặc dù 2 tên AES và Rijndael vẫn thường được gọi thay thế cho nhau nhưng
trên thực tế thì 2 thuật toán không hoàn toàn giống nhau. AES chỉ làm việc với các
khối dữ liệu (đầu vào và đầu ra) 128 bít và khóa có độ dài 128, 192 hoặc 256 bít
(vì thế mà các thuật toán AES có tên khác nhau là AES – 128, AES – 192, AES –
256) trong khi Rijndael có thể làm việc với dữ liệu và khóa có độ dài bất kỳ là bội
số của 32 bít nằm trong khoảng từ 128 tới 256 bít.
Các khóa con sử dụng trong các chu trình được tạo ra bởi quá trình tạo khóa
con Rijndael. Mỗi khóa con cũng là một cột gồm 4 byte. Hầu hết các phép toán
trong thuật toán AES đều thực hiện trong một trường hữu hạn của các byte.
Mỗi khối dữ liệu 128 bit đầu vào được chia thành 16 byte (mỗi byte 8 bit),có
thể xếp thành 4 cột, mỗi cột 4 phần tử hay là một ma trận 4x4 của các byte,nó được
gọi là ma trận trạng thái, hay vắn tắt là trạng thái (tiếng Anh: state, trang thái trong
Rijndael có thể có thêm cột). Trong quá trình thực hiện thuật toán các toán tử tác
động để biến đổi ma trận trạng thái này.


Cati đ

4


CHƯƠNG II. CẤU TẠO, HOẠT ĐỘNG CỦA AES
2.1 Thông số thuật toán
Với thuật toán AES, độ dài của khối đầu vào, đầu ra, state là 128 bits.
Độ dài của khóa (key cipher) là 128, 192, hoặc 256 bits. Độ dài của khóa
được đại diện bởi Nk = 4, 6, hoặc 8, phản ánh số lượng từ 32 bits (số cột) trong
khóa.
Đối với AES, thì số vòng thực hiện mã hóa phụ thuộc vào kích thước của
khóa, và số vòng thực thi được kí hiệu là Nr.
Bảng dưới đây cho biết số các vòng mã hóa ứng với độ dài khóa tương ứng
của AES:

Bảng 2. 1. Bảng thông số của AES

Trong quá trình mã hóa và giải mã, mỗi một vòng lặp gồm 4 phép biến đổi
mật mã theo byte:
1)
2)
3)
4)

Thay thế byte (byte substitution) sử dụng một bảng thay thế (S-box)
Dịch các hàng của mảng trạng thái (State array) theo chỉ số dòng
Trộn dữ liệu trong một cột của State array
Cộng khóa vòng (round key) vào State array.


Phần tiếp theo sẽ giới thiệu về quá trình mã hóa, giải mã và cuối cùng là quá
trình sinh khóa vòng – mở rộng khóa (Key expansion).
2.2. Quá trình mã hóa
Tại bước khởi động của vòng lặp, khối dữ liệu đầu vào được gán cho State
array. Sau đó mỗi cột của State array đầu tiên lần lượt được kết hợp với khóa đầu
vào theo thứ tự từ đầu dãy khóa. Sau đó State array được biến đổi thông qua 10,
12, hoặc 14 vòng lặp (Nr), với vòng cuối cùng khác với Nr - 1 vòng trước. Sau đó
State array được gán cho dữ liệu đầu ra.

Cati đ

5


Các vòng lặp sử dụng tham số là các khóa con được sinh ra bởi quá trình mở
rộng khóa được trình bày ở phần 4 của mục này. Tập hợp khóa con là một mảng
một chiều, mỗi phần tử là 4 bytes.
Các phép biến đổi trong hình 2.2: SubBytes, ShiftRows, MixColumns, và
AddRoundKey được mô tả trong phần dưới. Mảng w[] chứa khóa được sinh bởi
hàm mở rộng khóa được mô tả tại ….
Theo hình 2.2, Nr-1 vòng thực hiện giống nhau, vòng cuối không có
MixColumns.
Quá trình mã hóa được biểu diễn bằng giải thuật dưới đây hoặc tham khảo
phần 3.3.2.a:

Hình 2. 1 Giải thuật mã hóa AES

2.2.1 Phép thay thế byte (SubBytes)
Phép biến đổi AES đầu tiên là một phép thay thế byte phi tuyến gọi là phép

biến đổi SubBytes(), nó hoạt động độc lập trên mỗi byte bằng cách sử dụng bảng
tra S – box. Bảng tra S – box này được xây dựng nên từ 2 phép biến đổi:
- Tính nghịch đảo phép nhân trong 𝐺𝐹(28 )
- Sau đó, sử dụng một phép biến đổi Affine trên nghịch đảo này
Quá trình trên được biểu diễn như sau:

Cati đ

6


Hình 2.2 sẽ biểu diễn sự thay đổi của phép biến đổi SubBytes():

Hình 2. 2 Mô tả phép biến đổi SubByte()

Bảng tra S – box sử dụng trong SubBytes() được biểu thị dưới dạng hệ 16
trong bảng 2.2 :

Bảng 2. 2 Bảng thay thế byte (S-box)

Ví dụ: muốn thay thế 𝑠1,1 = {53} trong State array chúng ta sẽ lấy chỉ số dòng
là ‘5’ và chỉ số cột là ‘3’ trong bảng trên vì thế 𝑠 ′1,1 = {𝑒𝑑}
Cati đ

7


2.2.2 Phép dịch hàng (ShiftRows)
Trong phép dịch hàng, lượng dịch Shift(𝑟, 𝑁𝑏) phụ thuộc vào số hàng 𝑟. Các
khối đầu vào và đầu ra là các khối 128 bits gồm 𝑁𝑏 = 4 word

Phép biến đổi ShiftRows() được biểu thị như sau:
𝑠 ′ 𝑟,𝑐 = 𝑠 𝑟 (𝑐 + 𝑠ℎ𝑖𝑓𝑡(𝑟, 𝑁𝑏)) 𝑚𝑜𝑑 𝑁𝑏 trong đó 0 ≤ 𝑐 < 𝑁𝑏
Như vậy hàng đầu tiên sẽ không dịch, tức là 𝑠ℎ𝑖𝑓𝑡(0, 4) = 0
Với các hàng còn lại lượng dịch sẽ tùy theo số hàng:
𝑠ℎ𝑖𝑓𝑡(1, 4) = 1
𝑠ℎ𝑖𝑓𝑡(2, 4) = 2
𝑠ℎ𝑖𝑓𝑡(3, 4) = 3
Phép dịch ở đây là phép dịch vòng, bit cao nhất được chuyển xuống bit thấp
nhất và các bits thấp được đẩy lên các bit cao, hình 2. 3 mô tả quá trình dịch các
hàng:

Hình 2. 3 Mô tả quá trình ShiftRows

2.2.3 Trộn cột (MixColumns)
Phép biến đổi MixColumns() được dùng để trộn dữ liệu trong một cột của
State array. Các cột được xem như các đa thức trong 𝐺𝐹(28 ). Đầu ra của
MixColumns() là 𝑠′(𝑥) được tạo bằng cách nhân cột của 𝑠(𝑥) với đa thức 𝑎(𝑥)
và rút gọn theo modulo (𝑋 4 + 1) :
𝑠 ′ (𝑥) = 𝑎(𝑥) ⊗ 𝑠(𝑥)
Trong đó: 𝑎(𝑥) = 03𝐻 𝑥 3 + 01𝐻 𝑥 + 02𝐻
Ở dạng ma trận có thể viết như sau:

Cati đ

8


Kết quả được biểu diễn như sau:

Hình 2. 4 mô tả quá trình biến đổi của MixColumns():


Hình 2. 4 Mô tả phép biến đổi MixColumns

2.2.4 Cộng khóa vòng (AddRoundKey)
Trong phép biến đổi này, Round Key được kết hợp với từng cột của State
array bằng phép XOR (cộng modulo 2). Mỗi một Round Key chứa 4 word, được
thêm vào mỗi cột của State array như sau:
[𝑠 ′ 0,𝑐 , 𝑠 ′1,𝑐 , 𝑠 ′ 2,𝑐 , 𝑠 ′ 3,𝑐 ] = [𝑠 0,𝑐 , 𝑠 0,𝑐 , 𝑠 0,𝑐 , 𝑠 0,𝑐 ] ⊕ [𝑤𝑟𝑜𝑢𝑛𝑑∙𝑁𝑏+𝑐 ]
𝑣ớ𝑖 0 ≤ 𝑐 ≤ 𝑁𝑏

Cati đ

9


Với [𝑤𝑖 ] là các cột của khóa vòng tương ứng trong bảng phân phối khóa sẽ
được mô tả ở phần sau và round là giá trị nằm trong đoạn [0;Nr]. Trong quá trình
mã hóa, bước khởi động vòng lặp xảy ra khi round = 0, lúc này khóa đầu vào
được thêm vào State array đầu tiên.
Phép biến đổi của AddRoundKey() được miêu tả như hình 2. 5 với l = round
* Nb:

Hình 2. 5. Mô tả phép biến đổi AddRoundKey

2.3. Quá trình mở rộng khóa
Thuật toán AES lấy khóa K và thực hiện quá trình mở rộng khóa để thu được
bảng phân phối khóa (Key Schedule). Quá trình mở rộng khóa sẽ tạo ra tổng cộng
𝑁𝑏(𝑁𝑟 + 1) từ 32 bits: thuật toán yêu cầu một tập khởi tạo đầu vào 𝑵𝒃 từ 32 bits,
và mỗi vòng trong Nr vòng mã hóa cần 𝑁𝑏 từ 32 bits làm khóa. Mỗi kết quả của
bảng phân phối khóa là một từ 4 bytes, kí hiệu là 𝑤𝑖 , với 0 ≤ 𝑖 < 𝑁𝑏(𝑁𝑟 + 1)

Quá trình sinh khóa vòng được biểu thị qua giải thuật như hình 2.6 hoặc tham
khảo mục 3.3.2.c
Trong giải thuật ta có hai hàm SubWord() và RotWord():
- SubWord(): là hàm thay thế mỗi byte ở đầu vào bằng một byte trong bảng
tra S-box
- RotWord(): thực hiện phép dịch vòng các byte từ một từ 4 bytes. Từ từ 4
bytes [𝑎0 𝑎1 𝑎2 𝑎3 ] sau phép dịch vòng [𝑎1 𝑎2 𝑎3 𝑎0 ].
- Sau đó từ 4 bytes này được kết hợp với một mảng 4 bytes gọi là Rcon[𝑖]
được cho như sau [𝑥 𝑖−1 , {00}, {00}, {00}] với 𝑥 𝑖−1 là bậc của 𝑥 (𝑥 là kí hiệu của
{02}) trong trường 𝐺𝐹(28 ) (𝑖 chạy từ 1, không phải từ 0).
Trong thuật toán trên, ta có thể thấy ở 𝑁𝑘 từ mã đầu tiên của khóa vòng được
lấp bởi khóa đầu vào. Mọi từ mã tiếp theo, 𝑤𝑖 , là kết quả của phép XOR của từ
mã trước đó, 𝑤𝑖−1 , với từ mã trước nó 𝑁𝑘 vị trí, 𝑤𝑖−𝑁𝑘 . Đối với các từ mã ở vị trí
Cati đ

10


bằng một số nguyên lần của 𝑁𝑘, từ mã được RotWord(), sau đó được SubWord(),
và cuối cùng XOR với Rcon[𝑖]
Riêng đối với AES – 256 khi 𝑁𝑘 = 8 và 𝑖 − 4 là bội của 𝑁𝑘 thì từ mã sẽ
được SubWord().

Hình 2. 6. Thuật toán mở rộng khóa

2.4. Quá trình giải mã
Quá trình mã hóa được mô tả ở phần trên có thể thực hiện theo thứ tự đảo
nghịch đảo để sinh ra quá trình giải mã của thuật toán AES. Những phép biến đổi
thực hiện trong quá trình giải mã là: InvShiftRows(), InvSubBytes(),
InvMixColumns(), và AddRoundKey().

Giải thuật sau đây mô tả quá trình giải mã:

Cati đ

11


Hình 2. 7. Thuật toán giải mã AES

2.4.1. Dịch hàng nghịch đảo (InvShiftRows)
InvShiftRows là phép biến đổi nghịch đảo với phép ShiftRows trong quá trình
mã hóa. Các bytes ở 3 hàng cuối của State array được dịch vòng với lượng dịch
khác nhau.
Hàng đầu tiên giữ nguyên, 3 hàng còn lại được dịch vòng theo công thức:
Hình 2. 8 miêu tả phép biến đổi InvShiftRows:

Hình 2. 8. Mô tả phép biến đổi InvShiftRows().

Cati đ

12


2.4.2. Thay thế byte nghịch đảo (InvSubBytes)
Đây là phép biến đổi nghịch đảo với phép SubBytes trong quá trình giải mã.
Mỗi byte của State array được thay thế độc lập bằng cách tra bảng thế S–box
nghịch đảo (inverse S-box). Đây cũng là kết quả của phép biến đổi Affine nghịch
đảo sau đó nhân State array với ma trận nghịch đảo trong 𝐺𝐹(28 ).
Bảng S-Box sử dụng trong InvSubBytes() được cho mô tả như bảng dưới.


Bảng 2. 3. Inverse S-box: Bảng thay thế các byte nghịch đảo

2.4.3. Trộn cột nghịch đảo (InvMixColumns)
Phép biến đổi InvMixColumns là một phép biến đổi nghịch đảo với phép
MixColumns trong quá trình mã hóa. Các cột được xem như các đa thức trong
𝐺𝐹(28 ) và được nhân với modulo (𝑋 4 + 1) với một đa thức cố định cho sẵn
𝑎−1 (𝑥):

Ở dạng ma trận có thể viết như sau:

Kết quả của phép nhân trên được biểu thị như sau:

Cati đ

13


2.4.4. Cộng khóa vòng (AddRoundKey) trong giải mã
Phép biến đổi này trong quá trình giải mã tương tự với quá trình mã hóa.
2.5.

Quá trình giải mã ngược

Các phép biến đổi trong quá trình giải mã ở trên có thứ tự ngược với các phép
biến đổi trong quá trình mã hóa, khi mà khóa mã hóa và khóa giải mã là giống
nhau (đặc điểm nổi bật của hệ mật khóa bí mật). Tuy nhiên, một vài tính chất của
thuật toán AES cho phép sử dụng quá trình giải mã tương đương có cùng thứ tự
các phép biến đổi như quá trình mã hóa.
Hai tính chất cho phép sử dụng quá trình giải mã tương đương được giải thích
như sau:

1. Phép SubBytes() và ShiftRows() có tính chất giao hoán, có nghĩa là, một
phép SubBytes() được thực hiện thì kế đến là một phép ShiftRows() cũng
tương đương với một phép ShiftRows() được thực hiện kế đến là một
phép SubBytes(). Cũng tương đương như vậy với hai phép biến đổi
InvShiftRows() và InvSubBytes().
2. Phép biến đổi trộn cột – MixColumns() và InvMixColumns() là tuyến
tính với các đầu vào cột, có nghĩa là:
InvMixColumns(state XOR Round Key) =
InvMixColumns(state) XOR InvMixColumns(Round Key).

Cati đ

14


Hình 2. 9. Thuật toán giải mã ngược

Cati đ

15


CHƯƠNG III. PHÂN TÍCH, THIẾT KẾ CHƯƠNG TRÌNH
3.1. Giới thiệu chương trình
Ngôn ngữ lập trình được sử dụng: Java.
IDE được sử dụng: Eclipse.
Giao diện chương trình gồm 2 phần:
- Phần 1: bao gồm hộp thoại lựa chọn file dữ liệu, lựa chọn kích thước
khóa tương ứng, và nút thực thi chương trình.
- Phần 2: khung hiển thị nhật kí: dữ liệu trong file input, quá trình sinh

key, mã hóa, giải mã.

Hình 3. 1 Giao diện chương trình

Cách sử dụng:
Tiến hành chọn file dữ liệu để tiến hành mã hóa, giải mã trong thư mục “test
vector” đi kèm. Sau đó, chọn độ dài khóa tương ứng với dữ liệu. Nhấn nút
“Execute” để chương trình tiến hành mã hóa, và giải mã dữ liệu nhận được.
Sau khi hoàn tất quá trình mã hóa, giải mã, dữ liệu sẽ được ghi xuống file
“encrypt.txt” và “decrypt.txt” tại thư mục chứa chương trình. Đồng thời dữ liệu
cũng được hiển thị bên phần log (bao gồm quá trình sinh key, block sau mỗi vòng
mã hóa, giải mã)
3.2. Cấu trúc chương trình
Dựa vào thuật toán AES, các yêu cầu của bài tập lớn, cũng như việc xây dựng
giao diện chương trình sao cho thân thiện. Tiến hành xây dựng chương trình với 4
class.
- AES.java: Chứa 3 phương thức chính: keyExpansion (mở rộng khóa),
encrypt (mã hóa dữ liệu), decrypt (giải mã).
- AESUtils.java: Chứa tất cả các phương thức phục vụ cho quá trình mở
rộng khóa, mã hóa cũng như giải mã của AES. VD: SubByte, ShiftRow,
MixColumn, AddRoundKey, …
Cati đ

16


- Utils.java: Chứa các phương thức StringToArray (chuyển đồi một chuỗi
về mảng để phục vụ cho việc tính toán), readFile (đọc dữ liệu từ file
input), writeFile, …
- GUI.java: Xây dựng giao diện cho chương trình, xử lý các sự kiện tương

tác với người sử dụng.
3.3. Xây dựng các phương thức chính
Phần này sẽ giới thiệu nội dung chi tiết (code) của các phương thức chính
được sử dụng trong chương trình. Phần thiết kế giao diện (GUI.java) và các
phương thức phụ (Utils.java) xin phép không trình bày.
3.3.1. AESUtils.java
SubByte, InvSubByte
Thực hiện bằng cách tra bảng sBox đối với SubByte và sBoxRev đối với
InvSubByte.
public char[] subByte(char[] state, boolean reverse) {
char[] output = new char[state.length];
for (int i = 0; i < state.length; i++) {
// Sub Byte
if (!reverse) output[i] = sBox[(int) state[i]];
// Inv SubByte
else output[i] = sBoxRev[(int) state[i]];
}
return output;
}

ShiftRow, InvShiftRow
Tiến hành dịch trái các hàng với số lần dịch bằng số thứ tự của hàng. Với
InvShiftRow sẽ tiến hành dịch trái với số lần (Nb – số thứ tự của hàng).
1. public static char[] shiftRows(char[] state, boolean reverse
) {
2.
for (int i = 0; i < 4; i++) {
1. public static char[] shiftARow(
3.
char[] row = new char[4];

char[] row, int loop) {
4.
// Get row from state
2.
char temp;
5.
row[0] = state[i];
3.
for (int i = 1; i <= loop; i
6.
row[1] = state[i + 4];
++) {
7.
row[2] = state[i + 8];
4.
temp = row[0];
8.
row[3] = state[i + 12];
5.
row[0] = row[1];
9.
if (!reverse) {
6.
row[1] = row[2];
10.
row = shiftARow(row, i);
7.
row[2] = row[3];
11.
} else {

8.
row[3] = temp;
12.
row = shiftARow(row, 4 - i);
9.
}
13.
}
10.
return row;
14.
state[i] = row[0];
11.
}
15.
state[i + 4] = row[1];
16.
state[i + 8] = row[2];
17.
state[i + 12] = row[3];
18.
}
19.
return state;
20.
}

Cati đ

17



MixColumn, InvMixColum
Tiến hành bằng cách lấy cột s(x) nhân với đa thức a(x) (đối với MixColumn)
và ar(x) đối với InvMixColumn.
Gmul: nhân hai số trong 𝐺𝐹(28 )
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.

25.
26.

public static char[] mixColumns(char[] state, boolean inverse) {
char[] temp = new char[4];
for (int i = 0; i < 4; i++) {
System.arraycopy(state, 4 * i, temp, 0, 4);
temp = MixAColumn(temp, inverse);
System.arraycopy(temp, 0, state, 4 * i, 4);
}
return state;
}
public static char[] MixAColumn(char[] state, boolean reverse) {
char[] tmp = new char[state.length];
for (int i = 0; i < state.length; i++) {
tmp[i] = 0x00;
for (int j = 0; j < state.length; j++) {
if (!reverse) {
// MixColumn
tmp[i] ^= gmul(state[j], ax[4 * i + j]);
} else {
// InvMixColumn
tmp[i] ^= gmul(state[j], arx[4 * i + j]);
}
}
}
return tmp;
}

AddRoundKey

Do các dữ liệu được biểu diễn dưới mảng một chiều nên AddRoundKey sẽ
tương đương với việc xor từng phần tử trong hai mảng với nhau.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.

public static char[] addRoundKey(char[] input, char[] roundKey) {
return xor2char(input, roundKey);
}
public static char[] xor2char(char[] first, char[] two) {
if (first.length == 0 || two.length == 0 || first.length != two.length)
return null;
char[] result = new char[first.length];
for (int i = 0; i < first.length; i++)
result[i] = (char) (first[i] ^ two[i]);
return result;
}

public static char[] rotWord(char[] columns) {
return shiftARow(columns, 1);
}

Cati đ

18


3.3.2. AES.java
Với việc mô tả cách hoạt động của AES tại Chương I, ta có các phương thức
mã hóa, giải mã, mở rộng khóa như sau:
a. Mã hóa (encrypt)
1. public char[] encrypt(char[] data, char[] key) {
2.
char[] cipher = new char[16];
3.
char[] roundKey = new char[16];
4.
// Expansion key
5.
char[] expandedKey = keyExpansion(key);
6.
System.arraycopy(expandedKey, 0, roundKey, 0, 16);
7.
8.
cipher = AESUtils.addRoundKey(data, roundKey);
9.
// Loop
10.

int i = 1;
11.
for (; i < nr; i++) {
12.
cipher = AESUtils.subBytes(cipher, false);
13.
cipher = AESUtils.shiftRows(cipher, false);
14.
cipher = AESUtils.mixColumns(cipher, false);
15.
16.
System.arraycopy(expandedKey, i * 16, roundKey, 0, 16);
17.
cipher = AESUtils.addRoundKey(cipher, roundKey);
18.
}
19.
// Final Round
20.
cipher = AESUtils.subBytes(cipher, false);
21.
cipher = AESUtils.shiftRows(cipher, false);
22.
System.arraycopy(expandedKey, i * 16, roundKey, 0, 16);
23.
cipher = AESUtils.addRoundKey(cipher, roundKey);
24.
return cipher;
25. }


b.

Giải mã (decrypt)
1. public char[] decrypt(char[] data, char[] key) {
2.
char[] plain = new char[16];
3.
char[] roundKey = new char[16];
4.
char[] expandedKey = keyExpansion(key);
5.
System.arraycopy(expandedKey, 4 * nb * nr, roundKey, 0, 16);
6.
plain = AESUtils.addRoundKey(data, roundKey);
7.
// Loop
8.
int i = nr - 1;
9.
for (; i > 0; i--) {
10.
plain = AESUtils.shiftRows(plain, true);
11.
plain = AESUtils.subBytes(plain, true);
12.
System.arraycopy(expandedKey, i * 16, roundKey, 0, 16);
13.
plain = AESUtils.addRoundKey(plain, roundKey);
14.
plain = AESUtils.mixColumns(plain, true);

15.
}
16.
// Final round
17.
plain = AESUtils.shiftRows(plain, true);
18.
plain = AESUtils.subBytes(plain, true);
19.
20.
System.arraycopy(expandedKey, i * 16, roundKey, 0, 16);
21.
plain = AESUtils.addRoundKey(plain, roundKey);
22.
return plain;
23. }

Cati đ

19


c. Mở rộng khóa (KeyExpansion)

1. public char[] keyExpansion(char[] key) {
2.
char[] expandedKey = new char[4 * nb * (nr + 1)];
3.
// Copy key -> key schedule
4.

System.arraycopy(key, 0, expandedKey, 0, nk * 4);
5.
// Calculate key schedule
6.
char[] temp = new char[4];
7.
for (int i = nk; i < nb * (nr + 1); i++) {
8.
// Copy Wi_1 -> temp
9.
System.arraycopy(expandedKey, nb * (i - 1), temp, 0, nb);
10.
11.
if (i % nk == 0) {
12.
// Nk <= 6
13.
// First 4 bytes of expanded key
14.
temp = AESUtils.subBytes(AESUtils.rotWord(temp), false);
15.
temp[0] ^= AESUtils.Rcon[i / nk - 1];
16.
} else if (nk == 8 && i % nk == 4) {
17.
// Nk = 8
18.
temp = AESUtils.subBytes(temp, false);
19.
}

20.
// Get Wi_nk
21.
char[] Wi_nk = new char[4];
22.
System.arraycopy(expandedKey, nb * (i - nk), Wi_nk, 0, nb);
23.
// Wi = Wi-nk + temp
24.
char[] Wi = AESUtils.xor2char(Wi_nk, temp);
25.
System.arraycopy(Wi, 0, expandedKey, nb * i, nb);
26.
}
27.
return expandedKey;
28. }

Cati đ

20


CHƯƠNG IV. KIỂM TRA TÍNH ĐÚNG ĐẮN CỦA CHƯƠNG TRÌNH
4.1 Nguồn dữ liệu
Để kiểm tra việc cài đặt thuật toán có đúng hay không, ta có thể sử dụng “test
vector” – hiểu nôm na là tập hợp bộ dữ liệu chuẩn (bao gồm: input, output, key,
…) cho một thuật toán nào đó.
Chương trình này sử dụng các “test vector” dành cho AES được công bố
trong NIST Special Publication 800-38A [4].

AES ECB 128-bit encryption mode
Encryption key: 2b7e151628aed2a6abf7158809cf4f3c
Test vector

Cipher text

6bc1bee22e409f96e93d7e117393172a

3ad77bb40d7a3660a89ecaf32466ef97

ae2d8a571e03ac9c9eb76fac45af8e51

f5d3d58503b9699de785895a96fdbaaf

30c81c46a35ce411e5fbc1191a0a52ef

43b1cd7f598ece23881b00e3ed030688

f69f2445df4f9b17ad2b417be66c3710

7b0c785e27e8ad3f8223207104725dd4

Bảng 4. 1 Bảng “test vector” cho AES - 128

4.2. Kiểm tra tính đúng đắn
Mở chương trình, chạy với bộ test thứ nhất – 128 bits.

Hình 4. 1 Test vector 1

Cati đ


21


Với plain text là: 6bc1bee22e409f96e93d7e117393172a chương trình mã hóa
thu được cipher: 3ad77bb40d7a3660a89ecaf32466ef97 hoàn toàn trùng khớp với
bộ test. Quá trình giải mã cũng thu được plain text ban đầu.
Tương tự với bộ test thứ 2:

Hình 4. 2 Test Vector 2

Với các bộ test còn lại,
chương trình đều cho ra kết
quả như mong muốn. Khẳng
định, chương trình đã cài đặt
thành công.
Bên cạnh là dữ liệu
chương trình ghi vào file
“encrypt.txt”

Hình 4. 3 Nội dung file encrypt.txt

Cati đ

22


Hình bên cạnh là dữ liệu
chương trình ghi vào file
“decrypt.txt”

Ngoài ra, chương trình
còn hỗ trợ mã hóa, giải mã một
khối với độ dài khóa là 192,
256 bits.

Hình 4. 4 Nội dung file decrypt.txt

Test vector với khóa 192 bits
Key:

8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b

Plain: 6bc1bee22e409f96e93d7e117393172a
Cipher: bd334f1d6e45f25ff712a214571fa5cc

Hình 4. 5 Test vector 3

Cati đ

23


KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN
Trong khoảng thời gian thực hiện, nhóm đã đạt được tất cả các yêu cầu mà
chủ đề đưa ra, bao gồm:
- Tìm hiểu về lịch sử ra đời của AES.
- Trình bày được cấu tạo, cách thức mã hóa, giải mã một khối, cũng như
quá trình mở rộng khóa của AES
- Xây dựng được chương trình mô phỏng mã hóa, giải mã một khối với
độ dài khóa 128, 192, 256 bits

- Chương trình cho ra các kết quả đúng, ứng với các test vector trong tài
liệu của NIST [4].
Hướng phát triển cho ứng dụng:
- Triển khai thêm các chế độ mã hóa, giải mã: CBC, CFB, OFB, CTR.
- Tìm hiểu đệm (padding) cho dữ liệu.
- Xây dựng chương trình mã hóa, giải mã một file bất kì.

TÀI LIỆU THAM KHẢO
Wikipedia, Mã hóa khối, />Wikipedia, Advanced Encryption Standard,
/>[3]. FIPS, FIPS-197 - Advanced Encryption Standard,
/>[4]. NIST, NIST SP800-38a - Recommentdation for Block Cipher Modes of
Operation, />[5]. Wikipedia, Rijindael mix columns,
/>[6]. TS. Nguyễn Ngọc Cương, TS. Nguyễn Tuấn Anh, Ths. Trần Thị Lượng,
Mật mã ứng dụng trong an toàn thông tin, Học viện Kỹ thuật mật mã, 2013.
[1].
[2].

Cati đ

24


×