You are on page 1of 24

BÁO CÁO BÀI TẬP LỚN MÔN: LÍ THUYẾT MẬT MÃ GVHD: PGS TS Đỗ Trọng Tuấn NHÓM

11 1. Nguyễn Quang Đông 20192760 2. Bùi Thọ Vinh 20193195 3. Trần Đình Khang
20182596 Hà Nội, 05/2022
---------------------------------------------------------------------------------------------------------------------
----

II. CƠ SỞ TOÁN HỌC CỦA LÍ THUYẾT MẬT MÃ 1. SỐ HỌC CÁC SỐ NGUYÊN TỐ


• Z là tập hợp các số nguyên : Z = { …,-2,-1,0,1,2,…}
• Z* là tập hợp các số nguyên không âm : Z*= {0,1,2,…}
• Tập hợp Z là đóng kín đối với các phép cộng, trừ và nhân nhưng không đóng kín đối
với phép chia.
• Cho hai số nguyên bất kì a và b, b > 1 a = q*n +r , 0 ≤ r ≤ b Trong đó: q: thương, r: s ố

• Phép chia hết: Cho biểu thức a = q*n +r
– Nếu r = 0 => a chia hết cho n, kí hiệu n | a
– Nếu r ≠ 0 => a không chia hết cho n, kí hiệu n a
• Một số tính chất:
– Nếu a | 1 thì a = ±1
– Nếu a | b và b | a thì a = ±b
– Nếu a | b và b | c thì a | c
– Nếu a | b và a | c thì a | (mb + nc)
• Ước số chung lớn nhất: d = gcd(a,b)
• Ta sử dụng thuật toán Euclide để tìm gcd(a,b). INPUT: Hai số nguyên không âm a
và b, a > b OUTPUT: ước số chung lớn nhất của a và b.
1. Trong khi còn b > 0, thực hiện: 1.1. Đặt r ← a mod b, a ← b , b ← r.
2. Cho ra kết quả. Thuật toán Euclide
• Số nguyên tố :
– Một số nguyên a>1 được gọi là số nguyên tố , nếu a không có ước số nào
ngoài 1 và chính nó, và được gọi là hợp số nếu không phải là số nguyên tố.
– Hai số a và b được gọi là nguyên tố với nhau nếu gcd(a, b) = 1
– Một số nguyên n>1 bất kì đều có thể viết dưới dạng:
Trong đó p1, p2,...,pk là các số nguyên tố khác nhau, a1, a2,...,ak là các s ố mũ
nguyên dương. 2. SỐ HỌC MODUL Mối quan hệ của phép chia (a=q×n+r)
gồm hai đầu vào (a và n) và hai đầu ra (q và r). Trong số học mô-đun, ta chỉ
quan tâm đến một đầu ra duy nhất, đó chính là số dư r, mà không cần quan
tâm đến thương q. Như vậy ta có thể thay đổi mối quan hệ trên thành một
toán tử hai ngôi với hai đầu vào là a và n, và một đầu ra là r.
Toán tử modulo Toán tử hai ngôi được nhắc đến ở trên được gọi là toán tử modulo và
được ký hiệu là mod. Đầu vào thứ hai (n) được gọi là mô-đun (tiếng Anh: modulus). Đầu
ra r được gọi là thặng dư (tiếng Anh: residue). Toán tử modulo (mod) lấy m ột s ố nguyên
(a) từ tập Z và mô-đun (n) là một số nguyên dương. Toán tử cho kết quả một thặng d ư
không âm (r). Ta nói
Một số ví dụ: 27 mod 5=2 36 mod 12=0 -18 mod 14=10 -7 mod 10=3
Tập hợp các thặng dư Z n Kết quả của phép toán modulo với mô-đun n luôn là một s ố
nguyên từ 0 đến n-1. Nói cách khác, kết quả của a mod n luôn luôn là một s ố nguyên
không âm nhỏ hơn n. Ta có thể nói rằng phép toán modulo t ạo ra m ột tập h ợp, mà trong
số học mô-đun được gọi là tập hợp các thặng dư nhỏ nhất trong modulo n, hay được viết
là Z n . Mặc dù chỉ có duy nhất một tập hợp các số nguyên (Z), nhưng ta có vô s ố tập h ợp
các thặng dư Z n ứng với mỗi giá trị của n khác nhau. Ví dụ một số tập hợp thặng dư: Zn
= {0,1,2,3,…,(n-1)}
Đồng dư Trong mật mã, ta thường dùng khái niệm đồng dư (đồng dư thức) thay vì đẳng
thức. Ánh xạ từ Z tới Z n không phải là tương ứng một đối một (one-to-one), tức là nhiều
phần tử trong Z có thể ánh xạ tới cùng một phần tử trong Z n . Vô số phần tử của tập Z có
thể ánh xạ tới một phần tử trong tập Z n . Ví dụ, kết quả của 2 mod 10=2, 12 mod 10=2, 22
mod 10=2, v.v…. Trong số học mô-đun, số nguyên như 2, 12 và 22 được gọi là đ ồng d ư
theo mod 10. Để chỉ ra hai số nguyên đồng dư, ta sử dụng toán tử đồng dư (≡). và thêm
cụm từ (mod n) vào bên phải đồng dư thức.
• Toán tử đồng dư khá giống toán tử bằng, nhưng cũng có một vài điểm khác biệt.
Thứ nhất, toán tử bằng ánh xạ một phần tử trong tập Z tới chính nó; trong khi đó
toán tử đồng dư ánh xạ các phần tử từ tập Z sang một phần tử ở tập Z n . Thứ hai,
toán tử bằng tương ứng một tới một; còn toán tử đồng dư thì tương ứng nhiều tới
một (nhiều phần tử tương ứng với một phần tử).

• Cụm từ (mod n) được thêm vào bên phải của toán tử đồng dư chỉ là dấu hiệu của
tập đích ( Z n ). Ta cần phải thêm cụm từ này để chỉ ra mô-đun nào được dùng trong
ánh xạ. Ký hiệu mod được sử dụng ở đây không được dùng với nghĩa là toán tử hai
ngôi. Nói cách khác, ký hiệu mod trong 12 mod 10 là m ột toán t ử; c ụm t ừ (mod 10)
trong 2≡12 (mod 10) có nghĩa tập đích là Z 10.

Lớp thặng dư Một lớp thặng dư [a] hay [ a ] n là tập hợp các số nguyên đồng dư theo
modulo n. Nói cách khác, nó là tập hợp tất cả các số nguyên sao cho x ≡ a (mod n) Ví d ụ,
nếu n = 5, ta có tất cả năm tập hợp [0], [1], [2], [3] và [4] như dưới đây: [0]={…,-15,-10,-
5,0,5,10,15,…} [1]={…,-14,-9,-4,1,6,11,16,…} [2]={…,-13,-8,-3,2,7,12,17,…} [3]={…,-12,-7,-
5,3,8,13,18,…} [4]={…,-11,-6,-1,4,9,14,19,…} Các s ố nguyên trong tập h ợp [0] khi th ực hi ện
phép toán modulo cho 5 thì đều cho kết quả là 0. Các số nguyên trong tập [1] thì cho k ết
quả 1 khi thực hiện phép toán modulo cho 5,v.v…. Trong mỗi tập hợp sẽ có m ột phần t ử
được gọi là thặng dư nhỏ nhất (không âm). Trong tập [0], phần tử này là 0; trong tập [1],
phần tử này là 1; v.v…. Tập hợp tất cả các thặng dư nhỏ nhất chính là tập Z 5={0,1,2,3,4}.
Nói cách khác, tập hợp Z n là tập các thặng dư nhỏ nhất trong modulo n. Biểu đồ tròn
Khái niệm đồng dư có thể được hiểu rõ hơn bằng việc sử dụng một biểu đồ tròn. Giống
việc sử dụng một trục số để biểu diễn các số nguyên trong tập Z, ta có thể sử dụng một
đường tròn để biểu diễn các số nguyên trong tập Z n Các số nguyên từ 0 đến n-1 cách
đều nhau trên đường tròn. Tất cả các số nguyên đồng dư trong modulo n nằm cùng một
điểm trên đường tròn. Các số nguyên dương và nguyên âm từ tập Z được biểu diễn trên
đường tròn một cách đối xứng. Ta thường sử dụng số học đồng dư trong cuộc sống hàng
ngày của chúng ta; ví dụ như chúng ta sử dụng đồng hồ để tính thời gian. Hệ thống đồng
hồ mà ta sử dụng thể hiện một đồng dư trong modulo 12. Tuy nhiên, thay vì là 0, ta sử
dụng số 12. Cho nên, hệ thống đồng hồ bắt đầu từ 0 (hay 12) cho tới 11. Bởi vì một ngày
kéo dài 24 giờ, cho nên kim giờ sẽ được quay hai vòng, vòng đầu tiên cho buổi sáng và vòng
thứ hai cho buổi chiều. Phép toán trong Z n Ba phép toán hai ngôi (phép cộng, phép trừ
và phép nhân) đối với tập Z cũng có thể định nghĩa trong tập Z n . Kết quả của toán tử
trong Z n sẽ cần được ánh xạ tới tập Z n bằng việc sử dụng toán tử mod. Thực ra, có hai
loại toán tử đã được sử dụng ở đây. Loại thứ nhất đó là một trong các toán t ử hai ngôi
(+,-,×); và thứ hai là toán tử mod. Ta cần sử dụng dấu ngoặc đơn để thể hiện thứ tự ưu
tiên của các phép toán. Đầu vào (a và b) có thể là các phần t ử trong tập Z ho ặc tập Z n .
Tính chất Ta đã từng đề cập tới việc hai đầu vào của phép toán hai ngôi trong s ố học mô-
đun có thể nằm trong tập Z hoặc Z n . Tính chất sau đây cho phép chúng ta ánh xạ hai đầu
vào tới tập Z n (nếu chúng tới từ tập Z) trước khi thực hiện ba phép toán hai ngôi (+,-,×).
Quá trình trước và sau khi áp dụng những tính chất trên Mặc dù quá trình xử lý sẽ dài
hơn nếu ta sử dụng các tính chất trên, nhưng trong mật mã ta sẽ phải xử lý với những con
số rất lớn. Ví dụ, nếu ta nhân hai số nguyên lớn với một số nguyên lớn khác, ta sẽ được
môt số nguyên quá lớn để lưu trữ trong máy tính. Áp dụng các tính chất trên, trước tiên
làm cho hai toán hạng nhỏ đi, sau đó mới thực hiện phép nhân. Ví d ụ:
1. (1,723,345 + 2,124,945) mod 11 = (8 + 9) mod 11 = 6
2. (1,723,345 − 2,124,945) mod 16 = (8 − 9) mod 11 = 10
3. (1,723,345 × 2,124,945) mod 16 = (8 × 9) mod 11 = 6 Trong s ố học, ta th ường c ần
tìm số dư lũy thừa của 10 khi chia cho một số nguyên. Ví dụ, ta cần tính 10 mod 3,
102 mod 3, 103 mod 3, v.v… Hay ta cần tính 10 mod 7, 102 mod 7, 103 mod 7, v.v…
Tính chất thứ ba của toán tử mod ở trên sẽ làm công việc trở nên dễ dàng hơn.
Nghịch đảo Khi ta làm việc trong số học mô-đun, ta thường cần tìm nghịch đảo c ủa m ột
số trong phép tính. Ta thường cần tìm nghịch đảo cộng (liên quan tới phép cộng) hoặc
nghịch đảo nhân (liên quan đến phép nhân). Nghịch đảo cộng Trong tập Z n , hai số a và
b là nghịch đảo cộng của nhau nếu: a + b ≡ 0 (mod n) Trong Z n , nghịch đảo cộng của a có
thể được tính bằng b = n - a. Ví dụ, nghịch đảo cộng của 4 trong Z 10 là 10 - 4 = 6
Lưu ý rằng trong số học mô-đun, mỗi một số sẽ có một nghịch đảo cộng và phần t ử
nghịch đảo đó là duy nhất; mỗi số có một và chỉ một nghịch đảo cộng. Tuy nhiên, nghịch
đảo cộng của một số có thể là chính nó.
Nghịch đảo nhân Trong Z n , hai số a và b là nghịch đảo nhân của nhau nếu a × b ≡ 1 (mod
n) Ví dụ, nếu xét mô-đun 10, nghịch đảo nhân của 3 là 7. Nói cách khác, ta có (3×7) mod 10
= 1.
Người ta chứng minh được rằng a có nghịch đảo nhân trong Zn (hay nói a khả nghịch) khi
và chỉ khi gcd⁡(n,a)=1. Khi đó, a và n được gọi là hai số nguyên tố cùng nhau. Ví dụ: Không
tồn tại nghịch đảo nhân của 8 trong Z10 vì gcd⁡(10,8) = 2 ≠ 1. Hay nói cách khác, ta không
thể tìm được bất kỳ số nguyên nào từ 0 đến 9 mà khi nhân với 8 cho kết quả đồng dư với
1 trong modulo 10 Trong Z10 có ba cặp nghịch đảo nhân là (1,1), (3,7), (9,9). Các s ố 0, 2, 4,
6, 8 không có nghịch đảo nhân (1×1) mod 10 = 1 (3×7) mod 10 = 1 (9×9) mod 10 = 1 S ố
nguyên a trong tập Zn tồn tại nghịch đảo nhân khi và chỉ khi gcd⁡(n,a)≡1 (mod n)
Thuật toán Euclid mở rộng có thể tìm nghịch đảo nhân b trong Z n khi đã biết n và b và tồn
tại nghịch đảo nhân (khả nghịch). Để chứng tỏ điều đó, ta sẽ thay số nguyên đầu tiên a
bằng n. Bằng thuật toán Euclid, ta có thể tìm được s và t trong phương trình
s×n+b×t=gcd⁡(n,b). Tuy nhiên, nếu tồn tại nghịch đảo nhân của b, gcd⁡(n,b) phải bằng 1. Do
đó, phương trình sẽ là (s×n)+(b×t)=1
Sử dụng toán tử modulo vào cả hai vế của phương trình. Hay nói cách khác, ta ánh x ạ c ả
hai vế tới tập Z n . Ta sẽ có (s×n+b×t) mod n=1 mod n [(s×n) mod n]+[(b×t) mod n]=1 mod
n 0+[(b×t) mod n]=1 (b×t) mod n=1 → t là phần tử nghịch đảo nhân của b trong Z n Lưu
ý, biểu thức [(s×n) mod n] ở dòng thứ ba bằng 0 vì nếu ta chia (s×n) cho n, th ương tìm
được là s và số dư là 0. Thuật toán Euclid mở rộng tìm được nghịch đảo nhân của b trong
Zn khi biết n, b và gcd⁡(n,b)=1. Nghịch đảo nhân của b là giá trị của t sau khi ánh xạ tới Zn.
Cách tìm nghịch đảo nhân và thuật toán
Ví dụ tìm nghịch đảo nhân của 11 trong Z 26 :
Ta có gcd⁡(26,11) = 1, cho nên tồn tại nghịch đảo nhân của 11. Thuật toán Euclid mở rộng
tìm được t 1 = -7. Nghịch đảo nhân cần tìm là (-7) mod 26 = 19. Như vậy, 11 và 19 là nghịch
đảo nhân của nhau trong Z 26 . Thật vậy, (11×19) mod 26 = 209 mod 26 = 1.
Bảng cộng và nhân Trong bảng cộng, mỗi số nguyên đều có một phần tử nghịch đảo
cộng. Các cặp phần tử nghịch đảo được tìm thấy khi kết quả của phép cộng bằng 0. Chúng
ta có các cặp (0, 0), (1, 9), (2, 8), (3, 7), (4, 6), và (5, 5). Trong b ảng nhân, ta có ba c ặp
nghịch đảo nhân của nhau là (1, 1), (3, 7), và (9, 9). Các c ặp này được tìm thấy trong b ảng
khi phép nhân cho kết quả bằng 1. Cả hai bảng đều đối xứng qua đường chéo hướng từ
góc trên bên trái xuống góc dưới bên phải, điều này thể hiện tính giao hoán của phép nhân
và phép cộng (a+b=b+a và a×b=b×a). Bảng cộng cũng cho thấy mỗi hoàng hoặc cột là m ột
hoán vị của một hàng hoặc cột khác. Điều này không đúng trong bảng nhân. Một số tập
hợp khác cho phép cộng và phép nhân
• Trong mật mã ta thường làm việc với các phần tử nghịch đảo. Nếu người gửi sử
dụng một số nguyên (làm khóa cho mã hóa), người nhận sẽ phải sử dụng phần tử
nghịch đảo của số nguyên đó (là Sm khóa giải mã). Nếu phép toán (trong thuật
toán mã hóa/giải mã) là phép cộng, tập Z n có thể được sử dụng làm tập hợp các
khóa khả thi vì mỗi số nguyên trong tập hợp này đều có một phần tử nghịch đảo
cộng tương ứng. Mặt khác, nếu phép toán (trong thuật toán mã hóa/giải mã) là
phép nhân, Z n không thể là tập khóa khả thi vì chỉ một số phần tử trong tập hợp
này tồn tại phần tử nghịch đảo nhân. Ta cần một tập hợp khác để biểu diễn. Tập
hợp mới là tập con của Z n , chỉ bao gồm các số nguyên khả nghịch trong Z n . Tập
hợp này được gọi là Z ( n ).
¿

• Mỗi phần tử của Z n đều có nghịch đảo cộng, nhưng chỉ một số phần tử mới tồn tại
nghịch đảo nhân. Mỗi phần tử của Z ( n¿ ) lại đều có nghịch đảo nhân, nhưng chỉ một
vài phần tử là có nghịch đảo cộng (trong Z ( n ) ¿.
¿
Hai tập hợp khác
• Mật mã thường dùng hai tập khác là Z p và Z ( p¿ ). Phần mô-đun trong hai tập là một
số nguyên tố. Số nguyên tố là số chỉ có hai ước là 1 và chính nó.
• Tập Z p giống với tập Z n , trừ việc n là một số nguyên tố. Z p chứa tất cả các số
nguyên từ 0 đến p-1. Mỗi phần tử trong Z p đều có nghịch đảo cộng và mỗi phần
tử khác 0 đều có nghịch đảo nhân.
• Tương tự, tập Z ( p ) cũng giống tập Z ( n ) với n là một số nguyên tố. Z ( p ) chứa tất
¿ ¿ ¿

cả các số nguyên từ 1 đến p-1. Mỗi phần tử trong Z ( p ) đều tồn tại cả nghịch đảo
¿

cộng và nghịch đảo nhân. Z ( p ) là một trường hợp rất tốt trong việc chọn một tập
¿

hợp có cả nghịch đảo cộng và nghịch đảo nhân.


Phương trình đồng dư tuyến tính là phương trình có dạng ax ≡ b (mod n) trong đó a, b, n là
các số nguyên, n > 0 và x là ẩn số. Cách giải: Tính gcd(a, n) = d, nếu d b thì ph ương trình vô
nghiệm, nếu d | b thì phương trình có d nghiệm. Các bước tìm nghiệm: Chia cả 2 vế cho d
Nhân cả 2 vế với nghịch đảo của a/d, ta được nghiệm x0 Các nghiệm còn lại x = x0 +
k(n/d) với k = 0,1,...,(d-1) 4. MA TRẬN Định nghĩa
Ma trận A kích thước m*n (m hàng, n cột) với a i j là một phần tử hàng i, cột j
Một số phép toán về ma trận Cộng ma trận Nhân ma trận Nhân ma trận với m ột s ố Ma
trận phụ đại số chuyển vị
Định thức Ma trận nghich đảo Nghịch đảo cộng Nghich đảo nhân

• Sau đó, ta thực hiện quá trình mã hóa theo sơ đồ sau:

• VD: Mã hóa bản tin P = “VIETNAM” bằng mật mã nhân với khóa k = 5 21 =>
Encryption: (21 x 05) mod 26 = 01 B 08 => Encryption: (08 x 05) mod 26 = 14 O 04
=> Encryption: (04 x 05) mod 26 = 20 U 19 => Encryption: (19 x 05) mod 26 = 17 R
13 => Encryption: (13 x 05) mod 26 = 13 N 00 => Encryption: (00 x 05) mod 26 = 00
A 12 => Encryption: (12 x 05) mod 26 = 08 I => C = “BOURNAI”

• Để giải mã, ta thực hiện theo sơ đồ sau:

• Trong công thức này k − 1 là nghịch đảo nhân của k trong Z26

• VD: Giả sử thu được ciphertext như ví dụ ở trên, biết khóa k = 5. Tìm plaintext? k =
5 => k − 1 = 21 01 => Decryption: (01 x 21) mod 26 = 21 V 14 => Decryption: (14 x
21) mod 26 = 08 I 20 => Decryption: (20 x 21) mod 26 = 04 E 17 => Decryption: (17
x 21) mod 26 = 19 T 13 => Decryption: (13 x 21) mod 26 = 13 N 00 => Decryption:
(00 x 21) mod 26 = 00 A 08 => Decryption: (08 x 21) mod 26 = 12 M => P =
“VIETNAM”

• CODE PYTHON MINH HỌA:


# MULTIPLICATIVE CIPHER
# It's implemented by NGUYEN QUANG DONG in Group 11.
#as we all know, a number in Zn have multiply inverse, gcd(a, n) = 1
#function to find UCLN a, b
def UCLN(a, b):
if(b == 0):
return a
return UCLN(b, a % b)

#function to find Multiply inverse


def multiply_Inverse(a, b):
if(UCLN(a, b) == 1):
for i in range(b):
if (((a * i) % b) == 1):
return i

#function to encrypt follow Multiplicative Cipher


def encrypt_AdditiveCipher(data, key):
data_encrypt = ""
for i in range(len(data)):
if(data[i].isupper()):
a = 65 + (((ord(data[i]) - 65) * key) % 26)
data_encrypt += chr(a)
else:
a = 90 + (((ord(data[i]) - 97) * key) % 26)
data_encrypt += chr(a)
return data_encrypt

#function to decrypt follow Multipli Cipher


def decrypt_AdditiveCipher(data, Key):
data_decrypt = ""
keyInverse = multiply_Inverse(Key, 26)
for i in range(len(data)):
if(data[i].isupper()):
a = 65 + (((ord(data[i]) - 65) * keyInverse) % 26)
data_decrypt += chr(a)
else:
a = 90 + (((ord(data[i]) - 97) * keyInverse) % 26)
data_decrypt += chr(a)
return data_decrypt
if __name__ == '__main__':
#data = input("Enter data need encrypt: data = ")
#Key = int(input("Enter your key: key = "))
data_encrypt = encrypt_AdditiveCipher("VIETNAM", 5)
print("Data after encrypt follow AdditiveCipher: " + data_encrypt)
data_decrypt = decrypt_AdditiveCipher(data_encrypt, 5)
print("Data after decrypt follow AdditiveCipher: " + data_decrypt)

Data after encrypt follow AdditiveCipher: BOURNAI


Data after decrypt follow AdditiveCipher: VIETNAM
• NHẬN XÉT VỀ MULTIPLICATIVE CIPHER

• Ưu điểm: Đơn giản, phổ biến Dễ triển khai

• Nhược điểm

Mật mã Multiplicative dễ bị phá hủy khi ra để lộ ra key.

• Sau đó, ta thực hiện quá trình mã hóa theo sơ đồ sau:

• Ở đây, khóa k là một số nguyên có giá trị thuộc tập Z 26 = {0,1,2,…,25} VD: Mã hóa
bản tin P = “VIETNAM” bằng mật mã cộng với khóa k = 5

V 21 => Encryption: (21 + 05) mod 26 = 00 A


I 08 => Encryption: (08 + 05) mod 26 = 13 N
E 04 => Encryption: (04 + 05) mod 26 = 09 J
T 19 => Encryption: (19 + 05) mod 26 = 24 Y
N 13 => Encryption: (13 + 05) mod 26 = 18 S
A 00 => Encryption: (00 + 05) mod 26 = 05 F
M 12 => Encryption: (12 + 05) mod 26 = 17 R

=> C = “ANJYSFR”

• Để giải mã, ta thực hiện theo sơ đồ sau:

• Trong công thức này, -k là phần tử nghịch đảo cộng của k trong tập Z 26 : (k + (-k))
mod 26 = 0 VD: Giả sử thu được ciphertext như ví dụ ở trên, biết khóa k = 5. Tìm
plaintext?

k = 5 => -k = 21
A 00 => Decryption: (00 + 21) mod 26 = 21 V
N 13 => Decryption: (13 + 21) mod 26 = 08 I
J 09 => Decryption: (09 + 21) mod 26 = 04 E
Y 24 => Decryption: (24 + 21) mod 26 = 19 T
S 18 => Decryption: (18 + 21) mod 26 = 13 N
F 05 => Decryption: (05 + 21) mod 26 = 00 A
R 17 => Decryption: (17 + 21) mod 26 = 12 M

=> P = “VIETNAM”

• CODE PYTHON MINH HỌA


# ADDITIVE CIPHER
# It's implemented by NGUYEN QUANG DONG in Group 11.

# the first we need to find plus inverse


# function to find plus inverse
def plus_Inverse(Key, doimain):
return doimain - Key

#the next we create function to encrypt PlaintText


def encrypt_AdditiveCipher(data, Key):
data_encrypt = ""
for i in range(len(data)):
if(data[i].isupper()):
a = 65 + (((ord(data[i]) + Key) - 65) % 26)
data_encrypt += chr(a)
else:
a = 90 + (((ord(data[i]) + Key) - 90) % 26)
data_encrypt += chr(a)
return data_encrypt

#next we create function to decrypt CipherText follow AdditiveCipher


type
def decrypt_AdditiveCipher(data, Key):
data_decrypt = ""
plus_InverseKey = plus_Inverse(Key, 26)
for i in range(len(data)):
if(data[i].isupper()):
a = 65 + (((ord(data[i]) + plus_InverseKey) - 65) % 26)
data_decrypt += chr(a)
else:
a = 90 + (((ord(data[i]) + plus_InverseKey) - 90) % 26)
data_decrypt += chr(a)
return data_decrypt

# function main

if __name__ == '__main__':
#data = input("Enter your PlainText: PlainText = ")
#key = int(input("Enter your key: key = "))
data_encrypt = encrypt_AdditiveCipher("VIETNAM", 5)
print("PlainText after encrypt: " + data_encrypt)
data_decrypt = decrypt_AdditiveCipher(data_encrypt, 5)
print("CipherText after decrypt: " + data_decrypt)

PlainText after encrypt: ANJYSFR


CipherText after decrypt: VIETNAM

• NHẬN XÉT VỀ ADDITIVE CIPHER

• Ưu điểm: Đơn giản, phổ biến Dễ triển khai

• Nhược điểm

Mật mã Additive(Caesar) rất dễ bị phá, ngay cả trong trường hợp người giải mã chỉ
có trong tay các bản mật mã. Có hai tình huống được xem xét: Người giải mã biết
(hoặc đoán) rằng một số dạng mật mã thay thế đơn giản đã được sử dụng, nhưng
không biết cụ thể đó là mật mã Caesar Người giải mã biết chính xác m ật mã
Caesar được sử dụng, nhưng không biết giá trị khóa mã

• Mật mã Affine là một dạng mật mã thay thế dùng một bảng chữ cái, trong đó mỗi
chữ cái được ánh xạ tới một số, sau đó được mã hóa thông qua một hàm bậc nhất
có dạng: y = ax + b

• Để thực hiện mật mã hóa Affine, trước tiên ta cần ánh xạ các kí tự trong bảng chữ
cái (La tinh) thành các số tương ứng 0..25

• Sau đó, thực hiện quá trình mã hóa theo sơ đồ sau

• Trong công thức này, 2 khóa a và b là 2 số nguyên thuộc tập Z 26 , trong đó a và 26 là


hai số nguyên tố cùng nhau (gcd(a, 26) = 1) VD: Mã hóa bản tin P = “VIETNAM”
bằng mật mã Affine với khóa a = 17 và b = 5

V 21 => Encryption: (17.21 + 05) mod 26 = 24 Y


I 08 => Encryption: (17.08 + 05) mod 26 = 11 L
E 04 => Encryption: (17.04 + 05) mod 26 = 21 V
T 19 => Encryption: (17.19 + 05) mod 26 = 16 Q
N 13 => Encryption: (17.13 + 05) mod 26 = 18 S
A 00 => Encryption: (17.00 + 05) mod 26 = 05 F
M 12 => Encryption: (17.12 + 05) mod 26 = 01 B
=> C = “YLVQSFB”

• Để giải mã, ta thực hiện theo sơ đồ sau:

Ở đây, a − 1 là phần tử nghịch đảo nhân của a và –b là phần tử nghịch đảo cộng của
b trong tập Z26: a.a − 1 mod 26 = 1 và (b + (-b)) mod 26 = 0

• Mật mã cộng là một trường hợp đặc biệt của mật mã Affine với a = 1

• Mật mã nhân là một trường hợp đặc biệt của mật mã Affine với b = 0

VD: Giả sử thu được ciphertext như ví dụ ở trên, biết khóa a = 17 và b = 5. Tìm
plaintext?

a = 17 => a^-1 = 23
b = 05 => -b = 21
Y 24 => Decryption: 23(24 + 21) mod 26 = 21 V
L 11 => Decryption: 23(11 + 21) mod 26 = 08 I
V 21 => Decryption: 23(21 + 21) mod 26 = 04 E
Q 16 => Decryption: 23(16 + 21) mod 26 = 19 T
S 18 => Decryption: 23(18 + 21) mod 26 = 13 N
F 05 => Decryption: 23(05 + 21) mod 26 = 00 A
B 01 => Decryption: 23(01 + 21) mod 26 = 12 M
=> P = “VIETNAM”

• CODE PYTHON MINH HỌA


# Affine Cipher
# It's implemented by NGUYEN QUANG DONG in group 11

# The first we must define function to find UCLN to test require of


Multiply inverse
def UCLN(a, b):
if(b == 0):
return a
return UCLN(b, a % b)

def multiply_Inverse(a, b):


if(UCLN(a, b) == 1):
for i in range(b):
if((a * i) % b == 1):
return i

# next if function to find plus_inverse


def plus_Inverse(a, doimain):
return doimain - a

#function to encrypt
def encrypt_Affine(data, Key):
data_encrypt = ""
for i in range(len(data)):
if(data[i].isupper()):
a = (((Key[0] * (ord(data[i]) - 65)) + Key[1]) % 26) + 65
data_encrypt += chr(a)
else:
a = (((Key[0] * (ord(data[i]) - 97)) + Key[1]) % 26) + 97
data_encrypt += chr(a)
return data_encrypt

#define to decrypt

def decrypt_Affine(data, Key):


data_decrypt = ""
multiply_InverseKey = multiply_Inverse(Key[0], 26)
plus_InverseKey = plus_Inverse(Key[1], 26)
for i in range(len(data)):
if(data[i].isupper()):
a = ((multiply_InverseKey * ((ord(data[i]) - 65) +
plus_InverseKey)) % 26) + 65
data_decrypt += chr(a)
else:
a = ((multiply_InverseKey * ((ord(data[i]) - 97) +
plus_InverseKey)) % 26) + 97
data_decrypt += chr(a)
return data_decrypt
if __name__ == '__main__':
#data = input("Enter PlainText: PlainText = ")
#key1 = int(input("Enter Key1: Key1 = "))
#key2 = int(input("Enter Key2: Key2 = "))
#Key = [key1, key2]
Key = [17, 5]
data_encrypt = encrypt_Affine("VIETNAM", Key)
print("CipherText is: " + data_encrypt)
data_decrypt = decrypt_Affine(data_encrypt, Key)
print("CipherText after decrypt: " + data_decrypt)

CipherText is: YLVQSFB


CipherText after decrypt: VIETNAM

• NHẬN XÉT VỀ AFFINE CIPHER

• Ưu điểm: Đơn giản, phổ biến Dễ triển khai

• Nhược điểm Mật mã affine vẫn là một mật mã thay thế đơn pha, nên nó kế thừa
những điểm yếu của loại mật mã đó Nếu phát hiện ra bản rõ của hai ký tự mật mã
thì khóa có thể nhận được bằng cách giải một phương trình đồng thời. Kể từ khi
chúng tôi biết a và m tương đối chính

• Do mật mã cộng, mật mã nhân và mật mã Affine có không gian khóa nhỏ nên chúng
rất dễ bị tấn công và kẻ tấn công có thể dễ dàng giải mã tìm ra nội dung bản tin rõ
bằng cách vét cạn hết khóa trong không gian khóa.

• Có một giải pháp tốt hơn đó là tạo một ánh xạ giữa mỗi kí tự trong bản tin rõ với
một kí tự tương ứng trong bản tin mã hóa. Trước tiên, người gửi tin và người nhận
tin thống nhất một bảng thể hiện ánh xạ cho mỗi kí tự trong bảng chữ cái (nói theo
cách khác là đảo vị trí của các kí tự trong bảng chữ cái). Bảng này chính là chìa khóa
để mã hóa và giải mã tin.

• Sơ đồ thực hiện mã hóa và giải mã như sau:

• Để hiểu rõ hơn về Substitution Cipher. Ta xét ví dụ sau đây:

• Cho bảng

• Từ bảng này ta sẽ hiểu rằng, A sẽ được mã hóa thành E, B sẽ mã hóa thành P, t ương
tự...

• Ví dụ: Giả sử P = "LITHUYETMATMA" ==> Dựa vào bảng mã trên ta thu được bản
mã C = "YWZXGIHZDEZDE"

• CODE PYTHON MINH HỌA


#Substitution Cipher
#It's implemented by NGUYEN QUANG DONG in group 11
#Substitution Cipher is just simple replace follow given mapping
anphabe_Upper = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z']
anphabe_Lower = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z']

anphabe_UpperCipher = ['E', 'P', 'K', 'O', 'H', 'A', 'T', 'X', 'W',
'R', 'N', 'Y', 'D', 'M', 'B', 'L', 'F', 'U', 'Q', 'Z', 'G', 'J', 'C',
'S', 'I', 'V']
anphabe_LowerCipher = ['e', 'p', 'k', 'o', 'h', 'a', 't', 'x', 'w',
'r', 'n', 'y', 'd', 'm', 'b', 'l', 'f', 'u', 'q', 'z', 'g', 'j', 'c',
's', 'i', 'v']

#define function to encrypt


def encrypt_SubstitutionCipher(data):
data_encrypt = ""
for i in range(len(data)):
if(data[i].isupper()):
for j in range(26):
if(data[i] == anphabe_Upper[j]):
data_encrypt += anphabe_UpperCipher[j]
break
else:
for j in range(26):
if(data[i] == anphabe_Lower[j]):
data_encrypt += anphabe_LowerCipher[j]
break
return data_encrypt

#define function to decrypt


def decrypt_SubstitutionCipher(data):
data_decrypt = ""
for i in range(len(data)):
if(data[i].isupper()):
for j in range(26):
if(data[i] == anphabe_UpperCipher[j]):
data_decrypt += anphabe_Upper[j]
break
else:
for j in range(26):
if(data[i] == anphabe_LowerCipher[j]):
data_decrypt += anphabe_Lower[j]
break
return data_decrypt

if __name__ == '__main__':
#data = input("Enter PlainText: PlainText = ")
data_encrypt = encrypt_SubstitutionCipher("LITHUYETMATMA")
print("PlainText after encrypt: " + data_encrypt)
data_decrypt = decrypt_SubstitutionCipher(data_encrypt)
print("CipherText after decrypt: " + data_decrypt)

PlainText after encrypt: YWZXGIHZDEZDE


CipherText after decrypt: LITHUYETMATMA

• NHẬN XÉT VỀ SUBSTITUTION CIPHER

• Ưu điểm: Đơn giản, dễ hiểu Dễ triển khai trên các ngôn ngữ lập trình

• Nhược điểm Chỉ có 26! khóa nên rất dễ bị phá bởi Brute Force

• Mật mã Vigenere là một phương pháp mã hóa kí tự bằng cách dùng một loạt các
chuỗi đan xen mật mã Caesar dựa trên các chữ cái của một từ khóa. Đây là m ột
dạng mật mã hóa đối xứng thay thế đa kí tự.
• Để thực hiện mật mã hóa Vigenere, trước tiên ta cần ánh xạ các kí tự trong bảng
chữ cái (La tinh) thành các số tương ứng 0..25

• Sơ đồ mã hóa như sau:

• Sơ đồ giải mã như sau:

• Trong sơ đồ này, khóa K được lặp đi lặp lại cho đến khi nào độ dài bằng với
PlainText

• Tóm tắt quá trình: Từ bằng kí tự anphabe được đánh số thứ tự lần lượt: A là 0, B là
1, C là 2... Mỗi kí tự tương ứng của bản rõ(PlainText) ta đổi sang số thứ tự tương
ứng, Từ khóa K ta cũng làm tương tự. Ta cộng 2 số này lại rồi mod 26 và đây là kết
quả mã hóa.
VD: Mã hóa bản tin P = “ILOVELITHUYETMATMA” bằng mật mã Vigenere với khóa
K = “HAPPY”

Mã hóa Vigenere
• Từ đây ta thu được bản mã là: C = "PLDNCSIIWSFEIBYAMP"

• Giả sử bây giờ ta nhận được bản tin mã hóa C = “PLDNCSIIWSFEIBYAMP”, biết
khóa K = “HAPPY”. Để khôi phục lại bản tin rõ ta làm như sau: Giải mã Vigenere

• Từ đây ta thu được bản rõ là: P = "ILOVELITHUYETMATMA"

• CODE PYTHON MINH HỌA


#Vigenere_Cipher
#It's implemented by NGUYEN QUANG DONG in Group 11
#function to find plus Inverse
def plus_Inverse(a, doimain):
return doimain - a

#function to encrypt follow Vigenere_Cipher


def encrypt_Vigenere(data, Key):
data_encrypt = ""
full_Key = list(Key)
if(len(data) == len(Key)):
full_Key = Key
else:
count = len(Key)
flag = False
while True:
for i in range(len(Key)):
if(count != len(data)):
full_Key.append(Key[i])
count = count + 1
else:
flag = True
break
if (flag == True):
break
for i in range(len(data)):
if(data[i].isupper() & full_Key[i].isupper()):
a = (((ord(data[i]) - 65) + (ord(full_Key[i]) - 65)) % 26)
+ 65
data_encrypt += chr(a)
elif(data[i].islower() & full_Key[i].islower()):
a = (((ord(data[i]) - 97) + (ord(full_Key[i]) - 97)) % 26)
+ 97
data_encrypt += chr(a)
elif(data[i].isupper() & full_Key[i].islower()):
a = (((ord(data[i]) - 65) + (ord(full_Key[i]) - 97)) % 26)
+ 65
data_encrypt += chr(a)
else:
a = (((ord(data[i]) - 97) + (ord(full_Key[i]) - 65)) % 26)
+ 97
data_encrypt += chr(a)
return data_encrypt

#function to decrypt follow Vigenere Cipher


def decrypt_Vigenere(data, Key):
data_decrypt = ""
full_Key = list(Key)
if(len(data) == len(Key)):
full_Key = Key
else:
count = len(Key)
flag = False
while True:
for i in range(len(Key)):
if(count != len(data)):
full_Key.append(Key[i])
count = count + 1
else:
flag = True
break
if (flag == True):
break
for i in range(len(data)):
if(data[i].isupper() & full_Key[i].isupper()):
a = 65 + (((ord(data[i]) - 65) +
plus_Inverse(ord(full_Key[i]) - 65, 26)) % 26)
data_decrypt += chr(a)
elif(data[i].islower() & full_Key[i].islower()):
a = 97 + (((ord(data[i]) - 97) +
plus_Inverse(ord(full_Key[i]) - 97, 26)) % 26)
data_decrypt += chr(a)
elif(data[i].isupper() & full_Key[i].islower()):
a = 65 + (((ord(data[i]) - 65) +
plus_Inverse(ord(full_Key[i]) - 97, 26)) % 26)
data_decrypt += chr(a)
else:
a = 97 + (((ord(data[i]) - 97) +
plus_Inverse(ord(full_Key[i]) - 65, 26)) % 26)
data_decrypt += chr(a)
return data_decrypt

if __name__ == '__main__':
#data = input("Enter PlainText: PlainText = ")
#Key = input("Enter Key: Key = ")
data_encrypt = encrypt_Vigenere("ILOVELITHUYETMATMA", "HAPPY")
print("PlainText after encrypt is: " + data_encrypt)
data_decrypt = decrypt_Vigenere(data_encrypt, "HAPPY")
print("CipherText after decrypt is: " + data_decrypt)

PlainText after encrypt is: PLDKCSIIWSFEIBYAMP


CipherText after decrypt is: ILOVELITHUYETMATMA

• NHẬN XÉT VỀ VIGENERE CIPHER

• Ưu điểm: Dễ triển khai Khó phá vỡ hơn so với các loại mật mã trước

• Nhược điểm Tuy nhiên nếu khóa ngắn thì việc thám mã khá dễ dàng
• Trong mật mã học cổ điển, mật mã Hill là một dạng mật mã hóa thay thế đa kí tự
dựa trên cơ sở môn đại số tuyến tính, cụ thể ở đây là thực hiện các phép toán với
ma trận như nhân hai ma trận, tìm ma trận nghịch đảo.
• Chìa khóa trong hệ mật này là một ma trận vuông K có bậc m và ma trận K phải
khả nghịch.

• Để thực hiện quá trình mã hóa, trước tiên ta cần chuyển bản tin rõ P thành một ma
trận có kích thước m x n (n là bậc của ma trận chìa khóa K). Trong tr ường h ợp
chiều dài của bản tin rõ nhỏ hơn m x n thì tại những ô còn trống trong ma trận P ta
điền kí tự ‘Z’ (giá trị số tương ứng là 25). Sau đó thực hiện mã hóa theo sơ đồ sau:

• Để thực hiện giải mã, trước tiên ta cần tìm ma trận nghịch đảo K-1 của ma tr ận
khóa K (chú ý tính theo module 26). Sau đó thực hiện giải mã theo s ơ đ ồ sau:

• CODE PYTHON MINH HỌA


# Python3 code to implement Hill Cipher

keyMatrix = [[0] * 3 for i in range(3)]

# Generate vector for the message


messageVector = [[0] for i in range(3)]

# Generate vector for the cipher


cipherMatrix = [[0] for i in range(3)]

# Following function generates the


# key matrix for the key string
def getKeyMatrix(key):
k = 0
for i in range(3):
for j in range(3):
keyMatrix[i][j] = ord(key[k]) % 65
k += 1

# Following function encrypts the message


def encrypt(messageVector):
for i in range(3):
for j in range(1):
cipherMatrix[i][j] = 0
for x in range(3):
cipherMatrix[i][j] += (keyMatrix[i][x] *
messageVector[x][j])
cipherMatrix[i][j] = cipherMatrix[i][j] % 26
def HillCipher(message, key):

# Get key matrix from the key string


getKeyMatrix(key)

# Generate vector for the message


for i in range(3):
messageVector[i][0] = ord(message[i]) % 65

# Following function generates


# the encrypted vector
encrypt(messageVector)

# Generate the encrypted text


# from the encrypted vector
CipherText = []
for i in range(3):
CipherText.append(chr(cipherMatrix[i][0] + 65))

# Finally print the ciphertext


print("Ciphertext: ", "".join(CipherText))

# Driver Code
def main():

# Get the message to


# be encrypted
message = "LTMM"

# Get the key


key = "ADASSSASSARE"

HillCipher(message, key)

if __name__ == "__main__":
main()

Ciphertext: FCM

• Vào những năm đầu thập kỷ 70, nhu cầu có một chuẩn chung về thuật toán mật
mã đã trở nên rõ ràng. Các lý do chính là: Sự phát triển của công nghệ thông tin và
của nhu cầu an toàn & bảo mật thông tin: sự ra đời của các mạng máy tính tiền
thân của Internet đã cho phép khả năng hợp tác và liên lạc số hóa giữa nhiều công
ty, tổ chức trong các dự án lớn của chính phủ Mỹ. Các thuật toán ‘cây nhà lá vườn’
(ad hoc) không thể đảm bảo được tính tin cậy đòi hỏi cao. Các thiết b ị khác nhau
đòi hỏi sự trao đổi thông tin mật mã thống nhất, chuẩn. Một chuẩn chung cần thiết
phải có với các thuộc tính như: 1. Bảo mật ở mức cao 2. Thuật toán được đặc tả và
công khai hoàn toàn, tức là tính bảo mật không được phép dựa trên những phần
che giấu đặc biệt của thuật toán. 3. Việc cài đặt phải dễ dàng để đem lại tính kinh
tế 4. Phải mềm dẻo để áp dụng được cho muôn vàn nhu cầu ứng dụng Năm 1973,
Cục quản lý các chuẩn quốc gia của Mỹ đã có văn bản cổ động cho việc tạo lập các
hệ mật mã chuẩn ở cơ quan đăng ký liên bang của Mỹ. Điều này đã dẫn đến sự
công bố vào năm 1977 của cục An ninh Quốc gia Mỹ (NSA) về Data Encryption
Standard, viết tắt là DES. Thực chất, DES được phát triển bởi IBM như là sự s ửa đ ổi
của một hệ mã trước kia được biết với cái tên Lucifer. Trong khoảng 2 thập kỷ tiếp
theo, DES là hệ mã được dùng rộng rãi nhất và cũng là gây ra nhiều nghi ngờ, tranh
cãi trong lĩnh vực này: xung quanh các nguyên tắc thiết kế đảm bảo tính mật, chiều
dài khóa tương đối ngắn và khả năng NSA còn che giấu cửa sau (backdoor) đ ể có
thể bẻ khóa, phá mã ít tốn kém hơn thông thường.
• Các hình vẽ sau cung cấp sơ đồ khái quát và chi tiết của thuật toán sinh mã trong
DES Hình 1. Sơ đồ cơ bản của DES: đầu vào của DES là khối độ dài 64 bits, đầu ra
64 bits và khóa là 56 bits. Hình 2. Sơ đồ giải thuật sinh mã DES với cấu trúc 16
vòng lặp

• Sơ đồ hình vẽ 2 cho thấy DES được cấu tạo bởi 16 bước lặp với bước lặp cơ sở gọi
hàm chuyển đổi phi tuyến f; 16 bước lặp này được kẹp vào giữa hai tác tử giao
hoán IP và IP-1. Hai tác từ này không có ý nghĩa gì về mặt bảo mật mà hoàn toàn
nhằm tạo điều kiện cho việc cài đặt phần cứng, ‘chip hóa’ thuật toán DES. Hàm c ơ
sở f là nguồn gốc của sức mạnh bảo mật trong thuật toán DES này. Sự lặp lại nhiều
lần các bước lặp với tác dụng của f là nhằm tăng cường tính confusion và diffusion
đã có trong f.

Thuật toán sinh khóa con


• Đầu tiên, từ 64 bit ban đầu của khóa, 56 bit được chọn (Permuted Choice 1, hay PC-
1); 8 bit còn lại bị loại bỏ. 56 bit thu được được chia làm hai phần bằng nhau, m ỗi
phần được xử lý độc lập. Sau mỗi chu trình, mỗi phần được dịch đi 1 hoặc 2 bit
(tùy thuộc từng chu trình, nếu đó là chu trình 1,2,9,16 thì đó là dịch 1 bit, còn l ại thì
sẽ được dich 2 bit). Các khóa con 48 bit được tạo thành b ởi thuật toán l ựa chọn 2
(Permuted Choice 2, hay PC-2) gồm 24 bit từ mỗi phần. Quá trình d ịch bit (đ ược ký
hiệu là "<<<" trong sơ đồ) khiến cho các khóa con sử dụng các bit khác nhau của
khóa chính; mỗi bit được sử dụng trung bình ở 14 trong tổng số 16 khóa con.
• Quá trình tạo khóa con khi thực hiện giải mã cũng diễn ra tương tự nhưng các khóa
con được tạo theo thứ tự ngược lại. Ngoài ra sau mỗi chu trình, khóa sẽ đ ược d ịch
phải thay vì dịch trái như khi mã hóa.

• Qua sơ đồ thuật toán sinh khóa con có thể thấy rằng thực sự chỉ có 56 bit của khóa
chính được sử dụng, 8 bit còn lại là mã kiểm tra chẵn lẻ (parity bits) và bị lọc ra ở
biến đổi PC1. Các bộ biến đổi PC1 và PC2 chỉ đơn giản là các bộ vừa chọn lọc vừa
hoán vị (PC = permuted choice = lựa chọn có hoán vị). Các biến đ ổi R1 và R2 (left
rotate 1 bit và 2 bit) tương ứng là các phép đẩy bit trái 1 và 2 vị trí.
Cấu trúc cụ thể hàm f
• Sơ đồ biến đổi cụ thể của hàm f được minh họa trong hình 2.5. Trước hết, 32 bit
của thành phần Ri-1 được mở rộng thành 48 bit thông qua biến đổi E (expansion:
mở rộng với sự lặp lại một số bit) rồi đem XOR với 48 bit của khóa Ki. Tiếp theo,
48 bit kết quả sẽ được phân thành 8 nhóm 6 bit. Mỗi nhóm này sẽ đi vào m ột biến
đổi đặc biệt gọi là biến đổi S-box (có 8 S-box khác nhau ứng với mỗi nhóm 6 bit) và
cho ra kết quả là 8 nhóm 4 bit. Từ đó, 32 bit hợp thành (sau khi qua 8 S-box khác
nhau) sẽ được hoán vị lại theo hàm hoán vị P để đưa ra kết quả cuối cùng của hàm
f (tức nhân của Fi).
Cấu trúc của các S-Box
• Như ta biết mỗi một trong 8 nhóm 6 bit sẽ đi vào mỗi trong 8 bộ biến đ ổi S1,S2 ...
S8. Mỗi S-box bao gồm 4 bảng biến đổi dòng, thực chất là một biến đ ổi hoán vị cho
16 tổ hợp của 4 bits. Trong 6 bits đầu vào thì hai bit ngoài cùng (bit 1 và 6) đ ược
dùng để chỉ định 1 trong 4 bảng biến đổi dòng này; vì thế chúng được gọi là các bit
điều khiển trái và phải (CL và CR). Còn lại 4 bit chính (các bit 2-5) c ủa nhóm 6 bit
đầu vào sẽ là tổ hợp 4 bits bị biến đổi.
Hình 4. Bảng biến đổi S5: đầu vào 6 bits 011011 sẽ được biến đổi thành 1001 (ô vàng)
Các thuộc tính của S-Box
• Các nguyên tắc thiết kế của 8 S-box được đưa vào lớp thông tin mật ‘Classified
information’ ở Mỹ. Mặc dù vây, NSA đã tiết lộ 3 thuộc tính của S-boxes, những
thuộc tính này bảo đảm tính confusion & diffusion của thuật toán.
1. Các bít vào (output bit) luôn phụ thuộc không tuyến tính vào các bít ra (input bit).
2. Sửa đổi ở một bit vào làm thay đổi ít nhất là hai bit ra.
3. Khi một bit vào được giữ cố định và 5 bit con lại cho thay đổi thì S-boxes th ể hiện
một tính chất được gọi là ‘phân bố đồng nhất ‘ (uniform distribution): so sánh s ố
lượng bit số 0 và 1 ở các đầu ra luôn ở mức cân bằng. Tính chất này khiến cho việc
áp dụng phân tích theo lý thuyết thông kê để tìm cách phá S-boxes là vô ích.
• Rõ ràng, 3 tính chất này đảm bảo tốt confusion & diffusion. Thực tế, sau 8 vòng l ặp
tất cả các bit ra của DES sẽ chịu ảnh hưởng của tất cả các bit vào và tất cả các bit
của khóa. Hơn nữa sự phụ thuộc này là rất phức tạp. Tuy nhiên sau này một số tấn
công mới đã được đề xuất và cho thấy 8 vòng lặp này là chưa đủ để bảo mật (điều
này cho thấy NSA đã biết trước các dạng tấn công này nên mới qui định số vòng lặp
là 16 ngay từ đầu).
• Trong suốt những năm gần đây, các chuyên gia đã tìm được một số điểm yếu trong
DES.

• Điểm yếu:

a. Điểm yếu trong S-box.


b. Điểm yếu trong P-box.
c. Điểm yếu trong khóa.
• S-box: Ít nhất điểm yếu được đề cập trong văn bản về S-box.
a. Trong S-box 4 , 3 bit đầu ra cuối cùng có thể được rút theo cùng cách như
của bit đầu vào bằng việc bổ sung một vài bit đầu vào.
b. Hai đầu vào được chọn cho S-box có thể tạo ra đầu ra giống nhau.
c. Có thể đạt được đầu ra giống nhau trong một vòng duy nhất bằng việc thay
đổi bit trong chỉ 3 S-box liền kề.
• P-box: Một điều bí ẩn và là điểm yếu được tìm thấy trong thiết kế của P-box:

a. Chưa rõ ràng về lý do tại sao các nhà thiết kế DES sử dụng hoán vị đầu và
cuối; những hoán vị trên không đem lại lợi ích về bảo mật.
b. Trong quá trình mở rộng hoán vị( trong hàm), những bit đầu tiên và bit thứ
tư trong mỗi 4 bit sẽ được lặp lại.
• Kích thước khóa: Các chuyên gia tin rằng điểm yếu nghiêm trọng nhất của DES là
nằm trên trong kích thước chìa khóa của nó. Để tấn công theo kiểu brute force m ột
khối văn bản mã hóa, đối phương cần kiểm tra 2^56 khóa khác nhau.

a. Với công nghệ hiện nay, ta có thể kiểm tra hàng triệu key mỗi giây. Điều này
có nghĩa ta cần hơn hai nghìn năm để tấn công brute-force DES chỉ dùng một
máy tính và một bộ xử lý. Nếu ta có thể tạo ra máy tính với hàng triệu con
chip(xử lí song song với nhau), thì ta có thể kiểm tra toàn bộ các khóa trên
trong xấp xỉ 20 giờ. Khi DES được giới thiệu, giá của một máy tính như vậy
vào khoảng vài triệu đô la, tuy nhiên giá cả đã hạ rất nhanh. Một chiếc máy
tính đặc biệt được xây dựng vào năm 1998 tìm được chìa khóa đó trong 112
giờ.
b. Mạng lưới máy tính có thể giả lập việc xử lý song song. Năm 1977, một
nhóm gồm các nhà nghiên cứu sử dụng 3500 máy tính gắn với mạng
internet để tìm ra một khóa trong 120 ngày , thử thách trên được đưa ra bời
phòng thí nghiệm RSA. Nếu 3500 mạng lưới máy tình có thể tìm ra chìa khóa
trong 120 ngày, một cộng đồng bí mật với 42000 thành viên có thể tìm ra
chìa khóa trên trong 10 ngày.
• Trong 2^56 trường hợp mà khóa K có 4 khóa có độ an toàn rất kém đó là các khoa 0
hoặc 1.

• Hãy thử một key yếu đầu tiên để mã hóa một khối hai lần. Sau khi 2 lần được mã
hóa với cùng một key, khối văn bản thô ban đầu được tạo ra. Lưu ý răng chúng ta
đã sử dụng thuật toán mã hóa 2 lần, không một lần mã hóa nào đi kèm với giải.

• Các semi-weak keys: đó là 6 cặp key được gọi là semi-weak keys. Sáu c ạp key trên
được thể hiện trong bảng trên. Một semi-weak key tạo ra chỉ hai key vòng khác
nhau, và mỗi cái được lặp lại 8 lần. Ngoài ra, key vòng được tạo ra từ m ỗi cặp là
như nhau.

• Hoàn thiện chìa khóa: trong miền chìa khóa(2^56), chắc chắn một nửa số chìa khóa
trên là điều hoàn thiện cho nửa còn lại. Một key completement có thể đ ược t ạo ra
bằng cách đảo ngược mỗi bit trong key. Liệu key completement có đ ơn giản hóa
công việc của phân tích mật mã? Có. Eve có thể sử dụng chỉ một nửa của 2^56 key
để thực hiện một brute-force attack. Bởi vì
• Hay nói cách khác, nếu ta mã hóa completement của plaintext bằng completement
của key, ta sẽ có completement của ciphertext. Eve không c ần ph ải th ử 2^56 key, cô
ấy chỉ cần thử một nửa trong số đó và hoàn thiện kết quả thôi.

• RC4 được thiết kế bởi Ron Rivest của RSA Security vào năm 1987. Mặc dù nó đ ược
gọi chính thức là “Rivest Cipher 4”, nhưng từ viết tắt RC được hiểu theo cách khác
là viết tắt của “Ron Code”
• RC4 ban đầu là một bí mật thương mại, nhưng vào tháng 9 năm 1994, một mô tả
về nó đã được đăng ẩn danh lên danh sách gửi thư của Cypherpunks. Nó s ớm đ ược
đăng trên nhóm tin sci.crypt, nơi nó được phân tích trong vòng vài ngày b ởi Bob
Jenkins. Từ đó, nó lan ra nhiều trang trên Internet. Mã b ị rò r ỉ đã đ ược xác nh ận là
chính hãng, vì đầu ra của nó khớp với mã của phần mềm độc quyền sử dụng RC4
được cấp phép. Bởi vì thuật toán đã được biết đến, nó không còn là bí m ật kinh
doanh. Tên RC4 đã được đăng ký nhãn hiệu, vì vậy RC4 thường được gọi là
ARCFOUR hoặc ARC4 (có nghĩa là RC4 bị cáo buộc) để tránh các vấn đề về nhãn
hiệu. RSA Security chưa bao giờ chính thức phát hành thuật toán; Tuy nhiên, Rivest
đã liên kết đến bài báo Wikipedia tiếng Anh về RC4 trong ghi chú khóa học của
chính anh ấy vào năm 2008 và xác nhận lịch sử của RC4 và mã của nó trong một bài
báo năm 2014 của anh ấy
• RC4 đã trở thành một phần của một số giao thức và tiêu chuẩn mã hóa thường
được sử dụng, chẳng hạn như WEP năm 1997 và WPA năm 2003/2004 cho thẻ
không dây; và SSL vào năm 1995 và TLS kế nhiệm của nó vào năm 1999, cho đ ến
khi nó bị cấm đối với tất cả các phiên bản TLS bởi RFC 7465 vào năm 2015, do các
cuộc tấn công RC4 làm suy yếu hoặc phá vỡ RC4 được sử dụng trong SSL / TLS. Các
yếu tố chính dẫn đến thành công của RC4 đối với một loạt các ứng dụng là tốc độ
và sự đơn giản của nó: việc triển khai hiệu quả cả phần mềm và phần cứng đều
rất dễ phát triển.

• KSA được sử dụng để khởi tạo hoán vị trong mảng "S".


• Biến “keylength” được định nghĩa là số byte trong khóa (1 ≤ keylength ≤ 256),
thường là từ 5 đến 16, tương ứng với độ dài khóa là 40 - 128 bit.
• Đầu tiên, mảng “S” được khởi tạo để hoán vị danh tính.
• Sau đó, S được xử lý 256 lần lặp theo cách tương tự như PRGA chính, nhưng đồng
thời cũng trộn theo byte của khóa.

• Tăng i. <br>
• Tìm phầ n tửthứ i của S (S[i]), thêm phầ n tửđó vào j.<br>
• Trao đổ i các giá trị của S[i] và S[j], sau đó sửdụng tổng
S[i] và S[j] (mod 256) làm chỉ sốđểtìm nạp phầ n tửthứ ba của S (Giá
trị dòng khóa K bên dưới).<br>
• Sau đó XOR với byte tiế p theo của thông tin đểtạo ra byte
tiếp theo của bản mã hoặc bản rõ.<br>
• Mỗ i phần tửcủa S được hoán đổ
i với phầ
n tửkhác ít nhấ
t
một lầ
n sau mỗi 256 lần lặp.

Sơ đồ thuật toán hàm PRGA


• Hóa ra byte thứ 2 của keystream sẽ bằng 00 với xác suất 1/128 (gấp đôi so với
1/256, do có 256 giá trị byte từ 00 đến ff). Thật ra, những byte đầu tiên của
keystream đều không "ngẫu nhiên" và có thể được sử dụng để thu được key gốc.
Cơ bản thì ta có thể bỏ vài byte đầu (thường là 3072 byte) của keystream để che
lấp sơ hở này.
• Tuy nhiên, khi phân tích khoảng vài GB output của RC4, tính thiên vị khác được
phát hiện: Xác suất để 2 byte kề nhau là (00, 00) là 1/2562 + 1/2563, cao hơn
nhiều so với xác suất thông thường 1/2562.
• Hầu hết những tấn công lợi dụng sơ hở này của RC4 cũng như những tương quan
giữa key và keystream.
• Dẫu vậy, trước năm 2015, RC4 vẫn được sử dụng phổ biến trong SSL/TLS, vì thời
bấy giờ, RC4 miễn nhiễm trước tấn công BEAST, một tấn công làm khốn đốn nhiều
cryptosystem sử dụng trong SSL/TLS. Hơn nữa, cách thức sử dụng RC4 trong
SSL/TLS làm giảm thiểu các thiên vị trên, dẫn đến những tấn công "đặc chế" nhằm
phá RC4 trong SSL/TLS.
• Một ví dụ nổi bật là tấn công NOMORE, có thể phá 1 HTTP cookie 16-byte trong
khoảng 75 tiếng đồng hồ bằng cách gửi khoảng 2^30 yêu cầu.
• Vì vậy, tiêu chuẩn RFC 7465 do IEFT vào năm 2015 đã cấm RC4 trong TLS. Nhiều
biến thể của RC4 cũng được tạo ra hòng làm chặt chẽ thuật toán tạo keystream,
như RC4+ hay Spritz, nhưng chúng đều theo vết xe đổ của RC4.
BƯỚC 1. INSTALL CRYPTOOL 1
• Nhóm em sử dụng CrypTool, 1 làm công cụ mã hóa của nhóm. CrypTool là m ột công
cụ giáo dục mã nguồn mở. Có thể tải xuống từ https://www.cryptool.org/en/ct1/
BƯỚC 2. CHỌN VĂN BẢN VÀ MÃ HÓA
• Sau khi tải và khởi động chương trình, màn hình chương trình ban đầu:

• Nhấn vào biểu tượng Open như trên hình để mở file cần mã hóa. Ở đây nhóm em
mã hóa 1 file có tên là Caesar.txt chứa thông tin về Caesar.

• Nhấp vào menu Encrypt / Decrypt

• Trỏ đến Symmetric (hiện đại) rồi chọn RC4 như hình trên

• Cửa sổ sau sẽ xuất hiện

BƯỚC 3. CHỌN KHÓA MÃ HÓA VÀ TIẾN HÀNH MÃ HÓA


• Chọn 24 bit làm khóa mã hóa
• Đặt giá trị thành 00 00 00
• Nhấp vào nút Mã hóa (Encrypt)
• Ta sẽ nhận được mật mã luồng sau
Bước 1. BẮT ĐẦU PHÂN TÍCH
• Từ đoạn mã hóa đó, ta nhấp vào trình phân tích

• Trỏ đến Mã hóa đối xứng (hiện đại) rồi chọn RC4 như hình trên
• Ta sẽ nhận được cửa sổ sau

• Hãy nhớ rằng khóa bí mật ta sử dụng là 24 bit. Vì vậy, hãy đảm bảo rằng ta đã chọn
24 bit làm độ dài khóa.
• Bấm vào nút Bắt đầu. Ta sẽ nhận được cửa sổ sau

BƯỚC 2. PHÂN TÍCH KẾT QUẢ


• Khi phân tích xong, bạn sẽ nhận được kết quả sau.

• Lưu ý: số Entropy thấp hơn có nghĩa là nó có nhiều khả năng là kết quả chính xác
nhất. Có thể giá trị Entropy cao hơn giá trị thấp nhất được tìm thấy có thể là kết
quả chính xác.

• Chọn dòng có ý nghĩa nhất sau đó nhấp vào nút Chấp nhận lựa chọn khi hoàn t ất

• Chọn loại mã hóa DES và thực hiện tương tự các bước như RC4.
• TCP/IP là một tập hợp các giao thức (protocol) điều khiển truyền thông giữa tất cả
các máy tính trên Internet. Cụ thể hơn, TCP/IP chỉ rõ cách thức đóng gói thông tin
(gói tin), được gửi và nhận bởi các máy tính có kết nối với nhau. Có thể bạn chưa
biết, TCP/IP không phải là 1 giao thức duy nhất mà là tập hợp của 2 giao thức/
thành phần riêng biệt bao gồm:

TCP là viết tắt của Transmission Control Protocol, tạm


dịch: Giao thức kiểm soát truyền tải.
IP là viết tắt của Internet Protocol, tạm dịch: Giao thức
Internet.

• Hiểu đơn giản, TCP/IP là bộ giao thức cho phép kết nối các hệ thống mạng không
đồng nhất với nhau. Đây là 2 giao thức đầu tiên trên thế giới được định nghĩa.

• Hệ thông truyền thông bảo mật của nhóm em có sơ đồ như sau:

• Do thời gian có hạn, chúng em chỉ demo code và kết quả để báo cáo. Chúng em sẽ có
một buổi để trình bày với lớp về phần này.
• Nhóm chúng em sử dụng phương thức truyền thông TCP/IP thông qua module
socket của Python hỗ trợ, sử dụng để truyền thông giữa 1 server - 1 client

• Trước hết chúng em tạo một file dành cho server


import socket
import RC4
Key = "LITHUYETMATMA"
HOST = "192.168.1.133"
PORT = 2001
host_port = (HOST, PORT)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(host_port)
s.listen(10)
while True:
client, addr = s.accept()
with client:
print(f"Connected with port {addr[1]}")
print("Server listenning...")
while True:
data_real = client.recv(1024)
data_real1 = data_real.decode("utf8")
print(f"Data is received from client: Data =
{data_real1}")
data_real2 = RC4.decrypt(Key, data_real1)
print(f"Data is decrypted: Data = {data_real2}" )

• Tiếp theo sẽ tạo 1 file dành cho client để giao tiếp với server
import socket
import RC4
Key = "LITHUYETMATMA"
HOST = "192.168.1.133"
PORT = 2001
host_port = (HOST, PORT)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect(host_port)
while True:
fileName = input("Enter your file: File = ")
f = open("Text.txt", 'rb')
data_read = (f.read(1024)).decode("utf8")
l = RC4.encrypt(Key, data_read)
s.sendall(bytes(l,"utf8"))

• Và dưới đây là kết quả mà chúng em đã thu được khi dùng TCP/IP để truyền một
file Text đã được mã hóa bằng RC4, sau khi đến tới server thì phía server sẽ thực
hiện giải mã.
• File Text.txt của chúng em có nội dung như sau: "First let me send my best wishes to
everyone. I would like to introduce, I am Nguyen Quang Dong, a 3rd year student at
Hanoi Polytechnic University"

You might also like