2. MỤC LỤC
I – Mã hoá với khoá bí mật và công khai...............................................................................3
I.1. Mã hoá với khoá bí mật (private key encryption)........................................................3
I.1.1. Độ tương tự của các bản rõ ..................................................................................3
I.1.2. Độ sai khác của các bản rõ và bản mã..................................................................4
I.1.3. Thời gian mã hoá..................................................................................................4
I.1.4. Lược đồ tổng quát.................................................................................................5
I.2. Thuật toán mã hoá với khoá bí mật DES.....................................................................5
I.2.1. Thuật toán mã hoá các khối .................................................................................5
I.2.2. Thuật toán sinh khoá trong khối MK48................................................................6
I.2.3. Thuật toán mã hoá trong khối DES64..................................................................8
I.2.4. Thuật toán COMB..............................................................................................11
I.2.5. Kiểm chứng triển khai DES................................................................................13
I.2.6. Mã hoá các tập tin có độ dài bất kỳ....................................................................13
I.2.7. Mã hoá với khoá dài bất kỳ................................................................................15
I.3. Mã hoá với khoá công khai (public key encryption).................................................16
I.4. Thuật toán mã hoá với khoá công khai RSA.............................................................16
I.4.1. Ví dụ về thuật toán RSA.....................................................................................17
I.4.2. Thiết kế thuật toán..............................................................................................17
I.4.3. Các tính chất sử dụng thiết kế thuật toán............................................................18
I.4.4. Tính toán trên số lớn (large number calculus)....................................................19
I.5. Kết hợp giữa DES và RSA........................................................................................20
II – Mã hoá hàm băm...........................................................................................................21
II.1. Giới thiệu..................................................................................................................21
II.2. Hàm băm..................................................................................................................24
II.2.1. Định nghĩa.........................................................................................................24
II.2.2. Đặc trưng...........................................................................................................24
II.2.3. Tính chất............................................................................................................25
II.2.4. Các thuật toán băm............................................................................................26
II.2.4.1. Khái niệm “Thông điệp đệm”.....................................................................26
II.2.4.2. Hàm băm MD4 ..........................................................................................28
II.2.4.3. Hàm băm MD5...........................................................................................32
II.2.4.4. Hàm băm chuẩn SHA ................................................................................38
II.2.4.5. Một số hàm băm khác.................................................................................45
KẾT LUẬN..........................................................................................................................47
2
3. I – Mã hoá với khoá bí mật và công khai
Hai vấn đề cơ bản nhất trong an toàn mạng là xác thực (authentication) và bọc gói
(encapsulation). Xác thực nghĩa là xác định xem đối tượng đang truy nhập từ xa vào hệ thống
có đúng là đối tượng được phép đi vào hệ thống hay không và có đúng là được quyền thao tác
trên các tài nguyên của hệ thống hay không. Còn bọc gói nghĩa là gói bản tin lại sao cho chỉ
người gửi và người nhận biết được nội dung bản tin, những người khác có thể có được bản tin
đã được gói nhưng không đọc được bản tin. Hai vấn đề cơ bản này dựa trên các thuật toán mã
hoá khác nhau. Trong tài liệu này, chúng tôi sẽ giới thiệu các tư tưởng chung nhất về các thuật
toán của từng loại và một số thuật toán tiêu biểu cho mỗi loại.
I.1. Mã hoá với khoá bí mật (private key encryption)
Tư tưởng chung của các phương pháp mã hoá với khoá bí mật là dựa vào một khoá k và
một thuật toán mã hoá E để biến đổi bản tin f thành bản tin f' không thể đọc để lưu trữ hoặc
truyền đi một cách an toàn. Quá trình này cũng được coi như bọc gói (encapsulation) hay bỏ
vào phong bì (envelop) bản tin.
E(k, f) = Ek(f) = f'
Người đọc hoặc người nhận được bản tin mã hoá f' phải dùng thuật toán giải mã D và cùng
với khoá k để biến đổi bản tin f' thành bản tin f'' có thể đọc được. Quá trình này cũng gọi là
quá trình mở gói (uncover) theo nghĩa thông thường, ví dụ như người đọc nhận được thư và
mở phong bì để đọc nội dung.
D(k, f') = Dk(f') = f''
Có thể bản tin f'' có một số thay đổi so với tập tin f' nhưng một hệ mã hoá (kể cả công khai
và bí mật) hoàn hảo cần có ít nhất các ràng buộc sau
f = f'' hay Dk(Ek(f)) = f
f ≠ f' hay Ek(f) ≠ f
Các tạp tin f và f'' được gọi là các bản rõ (plaintext), nghĩa là các bản có thể đọc được
(readable). Còn tập tin f' được gọi là bản mã (ciphertext), nghĩa là bản không thể đọc được
(unreadable) theo nghĩa nó không mang cùng nội dung của bản rõ ngay cả chúng được mở.
Trong quá trình triển khai các hệ thống mã hoá, chúng ta cần có các chỉ số cụ thể để đánh
giá về hiệu suất của quá trình mã hoá và chất lượng của quá trình mã hoá. Để làm được như
vậy, chúng ta cần xem xét một số nội dung sau đây
I.1.1. Độ tương tự của các bản rõ
Tập tin ban đầu f và tập tin được giải mã Dk(Ek(f)) gọi tắt là f'' phải hoàn toàn giống nhau.
Trong đó, chúng ta đánh giá độ giống nhau (similarity) hay độ khác nhau (difference) với giả
sử một tập tin là chuỗi các giá trị do đó việc so sánh là các giá trị tương ứng.
f = { f1, f2, .., fn }
g = { g1, g2, .., gn }
3
4. Với n là độ dài tối thiểu của hai tập tin, nghĩa là n = min(sizeof(f), sizeof(g)), chúng ta có
định nghĩa hai tập tin bằng nhau
(f=g) ≡ (∀i fi=gi) ≡ (f1=g1 ∧ f2=g2 ∧..∧ fn=gn) ≡ (0 =
n
∑f
i =1
i
− gi )
Nếu so sánh bằng nhau hoàn toàn, chúng ta cần phải bắt buộc độ dài của hai tập tin là như
nhau. Nhưng trong một số trường hợp, chúng ta có thể không quan tâm đến phần sau của tập
tin.
I.1.2. Độ sai khác của các bản rõ và bản mã
Tập tin ban đầu f và tập tin được mã hoá Ek(f) được gọi tắt là f' phải hoàn toàn khác nhau.
Không có tiêu chí nào đánh giá sự khác nhau của hai tập tin, nhưng ít nhất chúng ta có thể
dùng các chỉ tiêu sau
1. Bảng chữ cái của hai tập tin càng khác nhau càng tốt, ví dụ nếu văn bản đầu vào f tạo từ
các chữ cái từ a tới z thì tập tin đầu ra f' phải được tạo từ các chữ cái không phải từ a tới
z có nghĩa là f' không đọc được.
2. Tần suất của các ký tự là không giống nhau. Vì các nhân viên thám mã có thể dựa vào
tần suất của các ký tự trong các bản tin để tạo ánh xạ giữa bản mã và bản rõ. Ví dụ chữ c
trong f xuất hiện 24 lần, và một chữ k trong f' cũng xuất hiện 24 lần, thì có nhiều khả
năng c và k có liên quan.
Từ các tiêu chí nói trên, chúng ta có thể viết được các thủ tục đơn giản để kiểm tra chất
lượng của tập tin được mã hoá. Các kiểm tra này nói chung hoàn toàn đơn giản nhưng chưa
đủ thuyết phục để trở thành lý thuyết đánh giá chất lượng của một thuật toán mã hoá.
I.1.3. Thời gian mã hoá
Thời gian mã hoá có thể không được quan tâm đối với người dùng máy tính cá nhân, vì
đơn giản họ chỉ mã hoá để cất giữ an toàn. Nhưng thời gian và dung lượng nhớ rất quan trọng
đối với các ứng dụng truyền tải trên mạng. Chúng ta cần mã hoá trước khi gửi và giải mã sau
khi nhận, do đó quá trình từ lúc người gửi ra lệnh gửi cho tới lúc người nhận đọc được văn
bản bao gồm thời gian truyền tC, thời gian mã hoá tE, và thời gian giải mã tD.
t = tE + tC + tD
Do đó chúng ta cần thuật toán mã hoá và giải mã càng nhanh càng tốt, và chúng ta cũng
cần một thước đo thời gian mã hoá. Gọi thời gian τ(f) là thời gian cần thiết để mã hoá và giải
mã tập tin f, nghĩa là thời gian tính từ lúc bắt đầu mã hoá tới lúc xuất hiện tập tin f'', chúng ta
có thể viết
τ(f) = τE(f) + τD(f')
Tất nhiên với mỗi tập tin dài ngắn khác nhau thì thời gian mã hoá khác nhau, do đó chúng
ta cần có một con số đánh giá trung bình như sau
4
5. n
T ( D, E ) = T ( f 1 , f 2 ,.., f n ) =
∑τ ( f
i =1
i
)
n
Việc đánh giá thời gian mã hoá trên một tập tin có ý nghĩa thực tế hơn việc đánh giá thời
gian mã hoá trên một khối tin, nghĩa là KB trên giây hoặc MB trên giây, vì trong quá trình mã
hoá tập tin, chúng ta thường phải thêm một số các thông tin tiêu đề và các thông tin độn.
I.1.4. Lược đồ tổng quát
Có rất nhiều lược đồ yêu cầu đối với các hệ mã hoá với khoá bí mật. Chúng có thể được
đặt ra bởi các nhà lý thuyết một cách hình thức (ví dụ lược đồ của Shannon) hay chúng được
đặt ra bởi yêu cầu thương mại (ví dụ của NBS). Chúng tôi đưa ra đây một số ràng buộc như là
lược đồ tổng quát mà tất cả các hệ triển khai cần phải đạt được.
1. Với mọi tập tin f và mọi khoá k, quá trình mã hoá và giải mã phải thuận nghịch
∀k ∀f Dk(Ek(f)) = f hay f = f''
2. Với mọi tập tin f và mọi khoá k, quá trình mã hoá phải an toàn
∀k ∀f Ek(f) ≠ f hay f ≠ f'
3. Hai tập tin khác nhau phải có hai bản mã khác nhau
∀k ∀f1 ∀f2 f1≠f2 ↔ Ek(f1)≠Ek(f2)
4. Hai khoá khác nhau phải tạo ra hai bản mã khác nhau với cùng tập tin
∀f ∀k1 ∀k2 k1≠k2 ↔ Ek1(f)≠Ek2(f)
I.2. Thuật toán mã hoá với khoá bí mật DES
Dựa trên lược đồ tổng quát về mã hoá bí mật, hãng IBM đưa ra thuật toán mã hoá DES
(Data Encryption Standard). Mặc dù thuật toán mã hoá DES có cấu tạo rất phức tạp nhằm
tăng mức độ bảo mật, thành phần chính của nó vẫn là hai phép thay thế (substitution) và hoán
vị (transposition) đã được sử dụng rất lâu trong các thuật toán mã hoá cổ điển.
I.2.1. Thuật toán mã hoá các khối
Để hiểu được thuật toán mã hoá bản tin K bất kỳ với khoá mã K bất kỳ, chúng ta cần hiểu
thuật toán mã hoá bản tin f dài 64 bít với khoá k dài 64 bít. Sơ đồ khối của thuật toán mã hoá
này như sau
kho¸ k
dµi 64 bÝ
t
b¶n tin f
gäi lµ b¶n râ
dµi 64 bÝ
t
biÕ ®æ kho¸ thµnh 16 kho¸ ,
n i
mçi kho¸ dµi 48 bÝ
t
MK48
16 kho¸
mçi kho¸ dµi 48 bÝ
t
k1, k2,..k16
m· ho¸ b¶n tin f ví i 16 kho¸
sö dông tõ ®iÓ thay thÕ
n
DES64
Hình 1: Mã hoá với bản tin dài 64 bit
5
b¶n tin f’
gäi lµ b¶n m·
dµi 64 bÝ
t
6. Trong đó khối chức năng ký hiệu MK48 có tác dụng biến đổi khoá k ban đầu thành 16
khoá k1, k2,..,k16 trong đó mỗi khoá ki đều dài 48 bít. Và khối chức năng có ký hiệu DES64 có
tác dụng biến đổi bản tin f dài 64 bít thành bản tin f' cũng dài 64 bit sử dụng 16 khoá, mỗi
khoá dài 48 bit do bộ MK48 tạo ra. Về mặt triển khai, chúng ta có thể biến đổi sơ đồ khối trên
thành các hàm như sau
void mk48(key64_t ink, key16x48_t outk);
void des64(block64_t inf, key16x48_t key, block64_t outf, int enc);
Bảng 1 : Các hàm mã hoá với khối 64bit
Để giải mã một tập tin được mã hoá bởi DES64, người ta cũng dùng thủ tục mã hoá
DES64 nhưng đầu vào lúc này là bản mã các khoá theo thứ tự ngược lại từ k16, k15,.., k1
I.2.2. Thuật toán sinh khoá trong khối MK48
Trước hết, chúng ta tìm hiểu chức năng MK48 chuyển khoá thô có độ dài 64 bít thành 16
khoá chế có độ dài 48 bít. Sơ đồ khối của thuật toán như sau
kho¸ ik dµi 64 bÝ
t
k0 = key_tr56(ik)
phÐp chuyÓ vÞ
n
KEY_TR56
kho¸ kt0 dµi 56 bÝ
t
phÐp quay 1 lÇn
ROTATE(1, 56)
kho¸ kt1
dµi 56 bÝ
t
phÐp chuyÓ vÞ
n
KEY_TR48
kho¸ ok1
dµi 48 bÝ
t
k1 = rotate56(k0)
ok1 = key_tr48(k1)
kho¸ kt2
dµi 56 bÝ
t
phÐp chuyÓ vÞ
n
KEY_TR48
kho¸ ok2
dµi 48 bÝ
t
k2 = rotate56(k1)
ok2 = key_tr48(k2)
kho¸ kt3
dµi 56 bÝ
t
phÐp chuyÓ vÞ
n
KEY_TR48
kho¸ ok3
dµi 48 bÝ
t
k3 = rotate56(k2)
k3 = rotate56(k3)
ok3 = key_tr48(k3)
kho¸ kt4
dµi 56 bÝ
t
phÐp chuyÓ vÞ
n
KEY_TR48
kho¸ ok4
dµi 48 bÝ
t
kho¸ kt1 dµi 56 bÝ
t
phÐp quay 1 lÇn
ROTATE(1, 56)
kho¸ kt2 dµi 56 bÝ
t
phÐp quay 2 lÇn
ROTATE(2, 56)
kho¸ kt3 dµi 56 bÝ
t
phÐp quay 2 lÇn
ROTATE(2, 56)
k4 = rotate56(k3)
k4 = rotate56(k4)
ok3 = key_tr48(k3)
kho¸ kt4 dµi 56 bÝ
t
...
...
...
kho¸ kt15 dµi 56 bÝ
t
phÐp quay 1 lÇn
ROTATE(1, 56)
kho¸ kt16
dµi 56 bÝ
t
phÐp chuyÓ vÞ
n
KEY_TR48
kho¸ ok16
dµi 48 bÝ
t
kho¸ kt4 dµi 56 bÝ
t
Hình 2 : Thuật toán sinh khoá 48bit
6
k16 = rotate56(k15)
ok16 = key_tr48(k15)
7. Thuật toán sinh khoá do đó đã được phân tích đầy đủ và trọn vẹn đến mức có thể triển
khai. Chúng ta có đoạn chương trình
void mk48(key64_t ink, key16x48_t outk) {
key56_t kt; int i, j;
//kt = key_tr56(ik)
for(i=0; i<56; i++) kt[i] = ink[ KEY_TR56_M[i]-1 ];
for(i=0; i<16; i++) {
//kt = rotate56(k0, ROTNUM[i])
if(ROTNUM[i]==1) rotate56(kt); else { rotate56(kt); rotate56(kt); }
//ok = key_tr48(kt)
for(j=0; j<48; j++) outk[i][j] = kt[ KEY_TR48_M[i]-1 ];
}
}
Bảng 2 : Thủ tục tạo khoá
Trong sơ đồ chúng ta thấy số lần quay là khác nhau với các khoá khác nhau, cụ thể hơn,
các khoá số k1, k2, k9, và k16 quay 1 lần và các khoá còn lại quay 2 lần. Trong triển khai để
tăng tốc thuật toán, chúng ta sẽ cần một mảng cục bộ trong triển khai của thuật toán. Tham
khảo mảng ROTNUM
int ROTNUM [16] = {
1, 1, 2, 2, 2, 2, 2, 2,
1, 2, 2, 2, 2, 2, 2, 1
};
Bảng 3 : Bảng số lần quay để tạo khoá
Phép hoán vị KEY_TR56 được thực hiện bằng một vòng lặp và một ma trận chuyển đổi vị
trí, tham khảo ma trận KEY_TR56_M. Quá trình biến đổi hoán vị từ khoá dài 64 bít về khoá
dài 58 bít là quá trình biến đổi mất thông tin, cứ mỗi đoạn 8 bít thì có 7 bít đầu được giữ lại,
và 1 bít cuối cùng bị bỏ đi. Chúng ta có thể kiểm tra dễ dàng điều này bằng cách nhìn vào
bảng chuyển vị KEY_TR56_M, trong bảng này không thấy các số như 8, 16, 24, 32, 40, 48,
56, 64. Do đó chúng ta không được đưa các khoá dài 64 bít mà trong đó các vị trí kể trên có
giá trị 1, vì các giá trị này bị bỏ qua dẫn tới khoá đưa vào có thể trùng với khoá khác có các vị
trí tương ứng bằng 0.
static int KEY_TR56_M [7*8] = {
57, 49, 41, 33, 25, 17, 9,
1,
58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7,
62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4,
};
Bảng 4 : Ma trận hoán vị khoá 56 vị trí
7
8. Phép hoán vị KEY_TR48 được thực hiện bằng một vòng lặp và một ma trận chuyển đổi vị
trí, tham khảo ma trận KEY_TR48_M.
static int KEY_TR48_M [6*8] = {
14, 17, 11, 24, 1, 5, 3, 28,
15, 6, 21, 10, 23, 19, 12, 4,
26, 8, 16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55, 30, 40,
51, 45, 33, 48, 44, 49, 39, 56,
34, 53, 46, 42, 50, 36, 29, 32,
};
Bảng 5 : Ma trận hoán vị khoá 48 vị trí
Thủ tục quay ROTATE giống như việc quay các bít về phía trái và bít đầu tiên sẽ được đặt
xuống cuối cùng, nhưng việc quay tiến hành tại hai nửa độc lập, do đó thủ tục quay được viết
void rotate56(key56_t k) {
char l0 = k[0], r0 = k[28];
for(int i=0; i<56; i++) k[i] = k[i+1];
k[27] = l0; k[55] = r0;
}
Bảng 6 : Thủ tục quay khoá
I.2.3. Thuật toán mã hoá trong khối DES64
Đầu tiên, bản tin mã hoá dài 64 bít sẽ được đưa qua phép hoán vị khởi đầu INITIAL_TR.
Sau đó bản tin này sẽ được tác thành 2 phần lp1 và rp1, mỗi phần 32 bít và được biến đổi dựa
trên khoá k1 (hoặc k16 nếu dùng để giải mã) thành lp2 và rp2 theo công thức. Trong công
thức này chúng ta sử dụng hai phép toán XOR và COMB sẽ được trình bày trong phần tiếp
theo. Các bước sau lặp lại tương tự với khoá k2, k3,..,k16. Kết quả của bước cuối cùng được
đưa vào hoán vị rồi qua phép chuyển vị kết thúc FINAL_TR và ta có kết quả bản mã.
8
9. giả sử l0 = t0, r0 = t0 + 32
và giả sử l1 = t1, r1 = t1 + 32
b¶n tin inf dµi 64 bÝ
t
phÐp chuyÓ vÞ
n
INITIAL_TR
khèi l0
dµi 32 bÝ
t
t0 = INITIAL_TR(inf)
khèi r0
dµi 32 bÝ
t
COMB
kho¸ k1
gi¶i m· dï ng k16
l1 = r0
r1 = COMB(r0, k1)
r1 = XOR(r1, l0)
khèi r1
dµi 32 bÝ
t
XOR
khèi l1
dµi 32 bÝ
t
khèi r1
dµi 32 bÝ
t
COMB
kho¸ k2
gi¶i m· dï ng k15
l2 = r1
r2 = COMB(r1, k2)
r2 = XOR(r2, l1)
khèi r2
dµi 32 bÝ
t
XOR
khèi l2
dµi 32 bÝ
t
khèi r2
dµi 32 bÝ
t
...
khèi l15
dµi 32 bÝ
t
khèi r15
dµi 32 bÝ
t
COMB
kho¸ k16
gi¶i m· dï ng k1
l16 = r15
r16 = COMB(r15, k16)
r16 = XOR(r16, l15)
khèi r16
dµi 32 bÝ
t
XOR
khèi l16
dµi 32 bÝ
t
khèi r16
dµi 32 bÝ
t
outg = SWAP_TR(t16)
phÐp ho¸ n vÞtr¸ i ph¶i
SWAP_TR
b¶n tin outf dµi 64 bÝ
t
phÐp ho¸ n vÞ
FINAL_TR
outf = FINAL_TR(outg)
b¶n tin outf dµi 64 bÝ
t
Hình 3 : Thuật toán mã hoá các khối 64 bit
Sơ đồ khối này có thể chuyển thành đoạn chương trình sau
void des64(block64_t inf, key16x48_t key, block64_t outf, int enc) {
block64_t t0, t1; int i, j; key_t ki;
block_t r0 = t0+32, l0 = t0, r1 = t1+32, l1 = t1;
for(i=0; i<64; i++) t0[i] = inf[ INITIAL_TR_M[i]-1 ]; //t0 = INITIAL_TR(inf);
for(i=0; i<16; i++) {
9
10. ki = (enc==0 ? key[i] : key[15-i]);
for(j=0; j<32; j++) l1[j] = r0[j]; //l1 = r0
combine32(r0, ki, r1); //r1 = combine(k0, r0)
for(j=0; j<32; j++) r1[j] = (r1[j]+l0[j])%2; //r1 = xor(r1, l0)
for(j=0; j<64; j++) t0[j] = t1[j]; //t0 = t1
}
for(i=0; i<64; i++) t1[i] = t0[ SWAP_TR_M[i]-1 ]; //t1 = SWAP_TR_M(t0);
for(i=0; i<64; i++) outf[i] = t1[ FINAL_TR_M[i]-1 ]; //outf = FINAL_TR_M(t1);
}
Bảng 7 : Thủ tục mã hoá với khối 64bit
Trong đó phép chuyển vị INITIAL_TR được thực hiện bằng vòng lặp và ma trận xác định
vị trí, tham khảo INITIAL_TR_M
static int INITIAL_TR_M [] = {
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7,
};
Bảng 8 : Ma trận hoán vị khởi đầu (dùng cho DES64)
Phép SWAP_TR chỉ đơn giản chuyển khối trái thành khối phải và ngược lại, nó cũng được
thực hiện bằng vòng lặp và ma trận vị trí SWAP_TR_M
static int SWAP_TR_M [] = {
33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56,
57, 58, 59, 60, 61, 62, 63, 64,
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, 27, 28, 29, 30, 31, 32,
};
Bảng 9 : Ma trận hoán vị chuyển đổi (dùng cho DES64)
Phép FINAL_TR được thực hiện bằng vòng lặp và ma trận xác định vị trí, tham khảo
FINAL_TR_M
static int FINAL_TR_M [] = {
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25,
};
10
11. Bảng 10 : Ma trận hoán vị cuối cùng (dùng cho DES64)
Phép XOR có thể được thực hiện đơn giản bằng một vòng lặp với toán tử xor các bít tương
ứng.
I.2.4. Thuật toán COMB
Chính trong phần này, các khoá được sử dụng. Các hộp thay thế S và các hộp hoán vị P
cũng được sử dụng nhằm làm tăng mức độ bảo mật của thuật toán. Thuật toán này kết hợp
khối r dài 32 bít với khối k
khèi r
dµi 32 bÝ
t
ho¸ n vÞmë réng
EXT_TR48
re = EXT_TR48(r)
kho¸ k
dµi 48 bÝ
t
khèi re
dµi 48 bÝ
t
tuyÓ lo¹ i ví i kho¸
n
XOR
khèi re
dµi 48 bÝ
t
re = XOR(rt, k)
rs = S_BOX(re)
thay thÕ qua c¸ c hép S
khèi rs
dµi 32 bÝ
t
ho¸ n vÞqua hép P
r' = P_BOX(rs)
khèi r’
dµi 32 bÝ
t
Hình 4 : Thuật toán kết hợp về phải & trái
Chúng ta sẽ phân tích các phép toán thay thế S sau khi nhìn vào đoạn chương trình tương
ứng với sơ đồ khối trên.
void combine32(block32_t inf, key48_t key, block32_t outf) {
int j, k; char cell; block64_t re, rs;
for(j=0; j<48; j++) re[j] = inf[ EXT_TR_M[j]-1 ]; //re = EXT_TR_M(inf);
for(j=0; j<48; j++) re[j] ^= key[j]; //re = xor48(re, key)
for(k=1; k<=8; k++) { //rs = S_BOX(re)
j = 32*re[6*k-5] + 16*re[6*k-0] + 8*re[6*k-4] + 4*re[6*k-3] + 2*re[6*k-2] + re[6*k-1];
cell = S_BOX[k-1][j];
rs[4*k-4] = (cell/8)%2;
rs[4*k-3] = (cell/4)%2;
rs[4*k-2] = (cell/2)%2;
rs[4*k-1] = (cell/1)%2;
}
for(j=0; j<32; j++) outf[j] = rs[ P_BOX[j]-1 ]; //outf = P_BOX(rs);
}
Bảng 11 : Thủ tục kết hợp vế trái và phải
11
12. Trong phép mở rộng EXT_TR thực chất là thêm một số bít bằng cách lấy lại các bít ở vị trí
khác nhau. Chúng ta có thể thấy điều này qua ma trận EXT_TR_M
static int EXT_TR_M [] = {
32, 1, 2, 3, 4, 5, 4, 5,
6, 7, 8, 9, 8, 9, 10, 11,
12, 13, 12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21, 20, 21,
22, 23, 24, 25, 24, 25, 26, 27,
28, 29, 28, 29, 30, 31, 32, 1,
};
Bảng 12 : Ma trận hoán vị mở rộng
Phép hoán vị P_BOX chỉ là phép hoán vị thông thường được thực hiện bằng ma trận
chuyển vị trí P_BOX
static int P_BOX[] = {
16, 7, 20, 21, 29, 12, 28, 17,
1, 15, 23, 26, 5, 18, 31, 10,
2, 8, 24, 14, 32, 27, 3, 9,
19, 13, 30, 6, 22, 11, 4, 25,
};
Bảng 13 : Hộp hoán vị (dùng cho thủ tục kết hợp vế trái và phải)
Phép thay thế qua các hộp S hơi phức tạp hơn. 48 bít sẽ được chia thành 8 nhóm, mỗi
nhóm dài 6 bít. 6 bít này sẽ được kết hợp thành một con số trong khoảng từ 0 đến 63 để dùng
làm chỉ số cột theo công thức
j = 32*re[6*k-5] + 16*re[6*k-0] + 8*re[6*k-4] + 4*re[6*k-3] + 2*re[6*k-2] + re[6*k-1]
Bảng 14 : Công thức tính cột của hộp hoán vị
Trong đó k là chỉ số của nhóm tính từ 1. Chỉ số nhóm k và chỉ số cột j sẽ được dùng làm
chỉ số để tra trong từ điển S ra một ký hiệu S[k][j] nằm trong khoảng từ 0 đến 15. Con số này
được điền vào nhóm đích tương ứng của nhóm k bằng công thức
rs[4*k-4] = (S[k][j]/8)%2;
rs[4*k-3] = (S[k][j]/4)%2;
rs[4*k-2] = (S[k][j]/2)%2;
rs[4*k-1] = (S[k][j]/1)%2;
Bảng 15 : Các công thức biến đổi ký hiệu trong hộp S
Hộp S cũng gọi là từ điển S là một mảng các con số nằm trong khoảng 0 đến 15. Các con
số này trùng lặp với nhau, và việc thiết kế mảng này được hãng IBM giữ bí mật nhằm chống
lại việc thám mã. Hộp S được định nghĩa như sau trong S_BOX
static int S_BOX[8][64] = {
{
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
}, {
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
12
13. 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
}, {
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
}, {
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
}, {
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
}, {
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
}, {
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
}, {
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11,
}
};
Bảng 16 : Các hộp S
I.2.5. Kiểm chứng triển khai DES
Các nhà thiết kế DES đã chứng minh bằng toán học tính đúng đắn của DES, nhưng chúng
ta không đảm bảo được thuật toán mà chúng ta triển khai đúng đắn với thiết kế của họ, đặc
biệt quá trình nhập liệu các bảng hoán vị và bảng thay thế có thể gây lỗi. Vì vậy chúng ta cần
có phương pháp kiểm chứng tính đúng đắn của triển khai mà chúng ta tạo ra.
Cách đơn giản nhất và mất thời gian nhất là vét cạn. Chúng ta sẽ tạo ra 2 64 hay 2568 bản rõ
khác nhau (mỗi bản dài 64 bít) và 127 8 khoá khác nhau. Với mỗi cặp bản rõ f và khoá k tạo
được, chúng ta sẽ so sánh Ek(f)≠f ∧ Dk(Ek(f)) = f thì triển khai đúng. Mặc dù chi phí kiểm
chứng rất cao, chúng ta phải thử 2568 x 1278 bộ giá trị, nhưng vì tính bảo mật và vì uy tính
của triển khai thì chúng ta vẫn phải làm.
I.2.6. Mã hoá các tập tin có độ dài bất kỳ
Bằng cách chia một tập tin bất kỳ thành các khối có độ dài 64 bít, chúng ta sẽ mã hoá được
toàn bộ tập tin. Nếu độ dài của tập tin tính ra bít không là bội của 64, chúng ta sẽ thêm các bít
độn (padding bits) sao cho độ dài của tập tin là bội của 64. Giả sử độ dài của tập tin tính ra bít
13
14. của tập tin là s và S là độ dài của tập tin tính ra byte, chúng ta có thể tính được số khối k cần
mã hoá, số bít p cần độn, và số byte P cần độn như sau
k = (s + 63) div 64 = (S + 7) div 8 = (S+7)>>3
p = k - s = ((s + 63) div 64) - s = ((s+63)>>4) - s
P = (k div 8) - S = ((S + 7) div 8) - S = ((S + 7)>>3) - S
Bảng 17 : Công thức tính số khối, số bít cần đệm
Để tăng độ an toàn, thậm chí người ta còn độn thêm các ký tự ngẫu nhiên tại những vị trí
nhất định của mỗi khối trong quá trình mã hoá. Và quá trình giải mã sẽ bao gồm việc bỏ đi
các ký tự của mỗi vị trí nhất định. Điều này chỉ làm thay đổi các chức năng đầu vào và đầu ra
của bộ mã hoá mà không làm thay đổi thủ tục mã hoá và giải mã.
Trong quá trình mã hoá, do có các bít độn và các bít ngẫu nhiên thêm vào nên chúng ta cần
có thêm thông tin tiêu đề (header) cho mỗi bản tin được mã hoá. Các thông tin này sẽ được sử
dụng và bỏ đi trong quá trình mã hoá. Thường định dạng bản tin của quá trình mã hoá như sau
Tên trường
Kích thước
Giải thích
sign
4
Bốn ký tự nhận biết ra tập tin mã hoá, dùng trong trường hợp
có trùng lặp về phân loại tập tin, giá trị TDES
pad
1
Số ký tự cần bỏ đi trong khối cuối, bao giờ cũng nhỏ hơn 8.
opt_len
4
Độ dài thông tin bổ xung tuỳ chọn theo tác giả, thường là
thông tin về các ký tự đệm
opt_len
Nội dung thông tin bổ xung tuỳ chọn theo tác giả, thường là
vị trí các bít đệm
opt
block_num
4
Số khối cần giải mã, mỗi khối dài 64 bít hay 8 byte
block1
8
Khối đầu tiên
block2
8
Khối tiếp theo
Bảng 18 : Định dạng của tập tin mã hoá
Tổng cộng kích thước tiêu đề là 13 trong trường hợp không có phần tuỳ chọn. Phần tuỳ
chọn (nếu có) nên được mã hoá bằng chính khoá để mã hoá tập tin để tăng tính bảo mật của
hệ thống.
Do quá trình mở rộng tập tin như vậy, giải mã và mã hoá không còn đối xứng nữa, vì mã
hoá thêm thông tin độn và thông tin tiêu đề trong khi giải mã bỏ thông tin đệm và thông tin
tiêu đề. Ta phải tách riêng hai chức năng mã hoá và giải mã. Chúng ta có thể xem sơ đồ mã
hoá với tập tin như sau
14
15. kho¸ k
dµi 8 ký tù
tËp tin f
d· y c¸ c gi¸ trÞ
MK8
t¹ o 16 kho¸ 48 bÝ
t
16 kho¸
mçi kho¸ dµi 48 bÝ
t
tËp tin f’
+ cã tiª u ®Ò
+ cã phÇn ®én
ENCF
m· ho¸ tËp tin
DECF
gi¶i m· tËp tin
tËp tin f’’
d· y c¸ c gi¸ trÞ
DES8
m· ho¸ c¸ c khèi 8 ký tù
Hình 5 : Mã hoá DES cho tập tin
Trong sơ đồ này, khối MK8 đóng vai trò chuyển đổi từ các khoá dài không quá 8 ký tự
(chính là chuỗi khoá do người dùng đưa vào) thành 16 khoá cùng độ dài 48 ký tự. Các khối
chức năng ENCF và DECF hoạt động cùng trên khoá này nhưng có đầu vào và đầu ra ngược
nhau. Chúng đều sử dụng tập tin có tiêu đề (headered file) đã được trình bày trong phần trên.
Việc triển khai của các khối ENCF và DECF rất phức tạp, bao gồm nhiều chi tiết làm tăng
tốc độ của thuật toán, nhưng ý tưởng chính của thuật toán có thể được trình bày như sau
1. Mở các tập tin đầu vào và đầu ra
2. Đọc / tính toán và ghi thông tin tiêu đề
3. Lặp lại việc sau
3.1. Đọc một khối từ tập tin đầu vào
3.2. Giải mã / mã hoá khối vừa đọc
3.3. Ghi khối xuống tập tin đầu ra
4. Đóng các tập tin đầu vào và đầu ra
Bảng 19 : Thủ tục mã hoá / giải mã với tập tin DES
Các khối MK8 và DES8 chỉ đơn giản biến đổi các dãy ký tự thành dãy bít, sau đó gọi lại
các thủ tục tương ứng MK48 và DES64. Đặc biệt DES8 có quá trình biến đổi dãy byte thành
dãy bit và ngược lại. Chúng ta cần thực hiện quá trình này trong một thủ tục để nhằm thống
nhất. Thuật toán DES8 như sau
void des8(des_block8_t inf, des_key16x48_t key, des_block8_t outf, int enc) {
des_block64_t inbuf, outbuf; longnat_t j;
for(j=0; j<64; j++) inbuf[j] = (inf[j/8] >> (j%8)) & 1;
des64(inbuf, key, outbuf, enc);
for(j=0; j<8; j++) outf[j] = 0;
for(j=0; j<64; j++) outf[j/8] |= (outbuf[j] << (j%8));
}
Bảng 20 : Thủ tục mã hoá chuỗi dài 8 ký tự
I.2.7. Mã hoá với khoá dài bất kỳ
Để mã hoá với độ dài bất kỳ, chúng ta phải mở rộng thuật toán một lần nữa. Chúng ta có
thể có nhiều cách giải quyết khác nhau để chuyển các khoá dài hơn tám ký tự về các khoá dài
tám ký tự, nhưng chúng ta cũng cần phải đảm bảo các yêu cầu trong lược đồ tổng quát.
15
16. Ví dụ giải pháp cắt các ký tự trong trường hợp khoá dài hơn 8 ký tự là giải pháp vi phạm
lược đồ tổng quát, vì khi đó hai khoá có 8 ký tự đầu tiên giống nhau sẽ trở thành giống nhau
do đó tạo ra hai bản mã giống nhau. Các nhà thám mã do đó không cần mất nhiều công, họ
chỉ cần thử 1278 = 67'675'234'241'018'881 khoá. Con số này có thể lớn đối với người nhưng
chỉ mất ít ngày đối với máy tính.
Chúng ta xem xét giải pháp chia nhỏ các khoá thành các chuỗi dài tám ký tự và mã hoá các
khối tin bằng các khoá đó. Trước tiên ta thấy giải pháp này mất thời gian, thời gian mã hoá sẽ
tỷ lệ với độ dài của khoá. Nhưng nói chung giải pháp này không hoàn toàn được đảm bảo do
các ký tự do phần trước là khoá mã hoá nhưng phần sau có thể lại là khoá giải mã. Tất nhiên
rất khó có trường hợp này xảy ra vì chúng ta cần phải tìm hai khoá k và k' sao cho MK48(k) =
inv(MK48(k')). Theo cách thiết kế DES của IBM thì không có hai khoá như vậy
I.3. Mã hoá với khoá công khai (public key encryption)
Các hệ mã hoá với khoá bí mật có một nhược điểm lớn là khoá cần giữ bí mật giữa người
gửi và người nhận. Do đó mỗi khi thiết lập một đường dây an toàn giữa hai người, hai người
cần phải trao đổi khoá qua một đường dây bí mật khác. Giữa hai lần thay đổi khoá bí mật,
khoá cũ cần phải được giữ kín giữa hai bên trao đổi. Điều này dẫn tới một loạt các phiền toái
đối với người dùng. Điều này dẫn đến nhu cầu phải có hệ mã hoá với khoá công khai, nghĩa là
khoá gửi và khoá nhận riêng. Chúng ta xem xét việc dùng hệ mã hoá công khai trước khi tìm
hiểu về thuật toán thực hiện.
Giả sử hai người A và B chưa bao giờ gặp nhau nhưng họ muốn thiết lập một đường dây
liên lạc bí mật, A sẽ gửi một khoá công khai E A trên đường truyền công cộng cho B, và ngược
lại B cũng gửi EB trên đường truyền cho A. Giả sử A cần gửi thông điệp P một cách bí mật
cho B, anh ta sẽ dùng khoá công khai EB để mã hoá thông điệp thành EB(P) và gửi tới cho B.
Khi nhận được thông điệp, B sẽ dùng khoá bí mật DB để giải mã thông điệp EB(P) nhận được
thành DB(EB(P)). Các khoá DB và EB phải được thiết kế sao cho DB(EB(P)) bằng chính P.
Tương tự như vậy, nếu A nhận được thông điệp E A(Q) gửi từ phía B, anh ta cũng dùng khoá
bí mật DA để giải mã thành DA(EA(Q)) hay chính là Q. Vì không có ai biết D A ngoài A, nên
chỉ có A đọc được thông điệp bí mật đó.
Từ những yêu cầu thực tế trên về hệ mã hoá công khai, chúng ta có lược đồ tổng quát cho
hệ mã hoá này như sau
-
Mỗi người tham gia truyền thông cần có một khoá E cung cấp công khai để người khác
mã hoá thông điệp và gửi cho anh ta, và một khoá D giữ bí mật để giải mã. Do đó với mỗi
cặp khoá mã E và giải mã D, chúng ta phải có ∀P D(E(P)) = P
-
E không thám mã được bằng cách sử dụng bản rõ. Yêu cầu này là cần thiết vì E cung cấp
công khai, nên ai cũng có thể dùng E để tạo ra cặp các bản rõ P và bản mã E(P), sau đó
tìm quy luật quan hệ giữa E(P) và P, cũng đồng nghĩa với việc tìm ra D.
-
Không thể dùng E để suy ra D. Điều này rất quan trọng vì E được cung cấp công khai. Và
nếu có mối liên hệ giữa E và D cũng đồng nghĩa với D được cung cấp công khai.
I.4. Thuật toán mã hoá với khoá công khai RSA
Có một số thuật toán đã được công bố thoả mãn lược đồ tổng quát của quá trình mã hoá
với khoá công khai, tuy nhiên thuật toán RSA do viện nghiên cứu MIT đưa ra được đánh giá
là thuật toán tốt. Cơ sở của thuật toán này là lý thuyết số (number theory) và phương pháp
tính toán số lớn (large number calculus).
16
17. I.4.1. Ví dụ về thuật toán RSA
Để hiểu rõ được cách thức hoạt động của thuật toán, chúng ta hãy xem ví dụ do chính tác
giả của thuật toán đưa ra. Để cho đơn giản trong tính toán, tác giả đã dùng các số nguyên tố
nhỏ.
Chọn p = 3 và q = 11
Do đó ta có n=3.11 = 33 và ϕ(n) = (p-1).(q-1) = 2.10 = 20
Ta chọn d = 7 để cho d và ϕ(n) nguyên tố cùng nhau
Ta chọn e=3 do đó 7e mod 20 = 1
Sử dụng hàm f(x) = xe mod n = x3 mod 33 trên bản rõ ta có bản mã
Sử dụng hàm f(x) = xd mod n = xd mod 33 trên bản mã ta có lại bản rõ
Bản rõ
19
21
26
1
14
14
5
Bản rõ3
6859
9261
17576
1
2744
2744
125
Bản mã
28
21
20
1
5
5
26
Bản mã7
13492928512
1801088541
1280000000
1
78125
78125
8031810176
Bản rõ
19
21
26
1
14
14
5
Bảng 21 : Ví dụ về thuật toán RSA
I.4.2. Thiết kế thuật toán
Dựa vào việc mã hoá xe mod n và việc giải mã xd mod n, chúng ta thấy cần phải có mối
liên hệ sao cho (xe mod n)d mod n = xe.d mod n = x. Điều này làm ta nhớ đến các định lý
Fermat và Euler trong lý thuyết số.
Định lý Fermat phát biểu rằng, với mọi số nguyên tố p và mọi số nguyên a bất kỳ không
chia hết cho p (a<p hoặc a≠kp), ta luôn có ( a p − a ) p hay (ap mod p) = (a mod p).
Định lý Euler phát biểu rằng, với mọi số nguyên n bất kỳ, và mọi số nguyên a nguyên tố
với n (nghĩa là bội số chung lớn nhất của a và n bằng 1), ta luôn có (a Φ( n ) −1) n hay (aΦ(n)
mod n) = (1 mod n) = 1 hoặc (aΦ(n)+1 mod n) = (a mod n).
Trong đó Φ(n) là số các số nguyên nhỏ hơn n mà không phải ước số của n. Theo quy ước
thì Φ(1) = 1. Tất nhiên, với số nguyên tố p thì Φ(p) = p-1. Với hợp số n có đúng hai ước
nguyên tố p và q thì Φ(n) = Φ(p.q) = (p-1).(q-1). Một cách tổng quát, ta có thể định nghĩa
(n
Φ(n) = card{ x | 1≤x<n ∧ ¬ x) }
Từ định lý Euler, ta có thể nhận thấy rằng mọi số bất kỳ tổ hợp từ Φ(n), nghĩa là các số có
dạng k.Φ(n) + 1, đều có tính chất (ak.Φ(n)+1 mod n) = (a mod n). Thật vậy, chúng ta có thể tham
khảo các biến đổi sau
ak.Φ(n)+1 mod n
17
18. = (ak.Φ(n).a) mod n
= ((ak.Φ(n) mod n).(a mod n)) mod n
//dùng (a.b) mod n = ((a mod n).(b mod n)) mod n
= ((aΦ(n))k mod n).(a mod n)) mod n
= ((aΦ(n) mod n)k mod n).(a mod n)) mod n
= ((1k mod n).(a mod n)) mod n
//dùng ak mod n = (a mod n)k mod n
//dùng Euler (aΦ(n) mod n) = (1 mod n) = 1
= (1.(a mod n)) mod n
= (a mod n) mod n
= a mod n
Bảng 22 : Chứng minh (ak.Φ(n)+1 mod n) = (a mod n)
Từ định lý này, chúng ta thấy nếu chọn cặp d.e bằng k.Φ(n)+1 hay chính xác hơn là (e.d)
mod Φ(n) = 1 thì đảm bảo ae.d = ak.Φ(n)+1 mod n = a mod n.
Chúng ta cũng thấy rằng do e.d = k.Φ(n)+1, nên ta cần phải chọn d trước nguyên tố với
Φ(n) do đó khi tìm e duy nhất bằng phương trình e.d mod Φ(n) = 1. Chúng ta cũng có thể
chọn e nguyên tối với Φ(n) trước và sau đó chọn d.
Tổng kết lại những kết quả trên, đối với mỗi một người dùng mã công khai, ta phải thiết
lập khoá công khai e và khoá bí mật d cho anh ta bằng các bước sau
-
Đầu tiên ta cần chọn hai số nguyên tố lớn p và q
-
Sau đó chọn n = p.q, do đó ϕ(n) = (p-1).(q-1)
-
Tiếp đó ta phải chọn d nguyên tố tương đối với ϕ(n)
-
Cuối cùng ta chọn d thoả mãn e.d mod ϕ(n) = 1 hay e.d = k.ϕ(n) + 1
Bảng 23 : Thủ tục xây dựng hệ mã RSA
I.4.3. Các tính chất sử dụng thiết kế thuật toán
Về cơ bản thuật toán này mã hoá và giải mã bằng hàm thành lập dựa trên phép lấy mũ và
phép lấy phần dư. Công thức của hàm f k,n(x) = xk mod n có một số tính chất đặc biệt được
dùng trong thiết kế. Trong đó n là một số nguyên dương lớn (large number). Các giá trị x phải
thoả mãn 0≤x<n. Và k cũng là một số nguyên dương lớn. Tất nhiên giá trị f(x) cũng thoả mãn
0≤f(x)<n do tính chất của phép mod. k và n là các số cố định như tham số của hàm. Chúng ta
tham khảo các tính chất này
Tính chất 1: Với hai số nguyên không âm a và b bất kỳ và với một số nguyên bất kỳ n>1,
ta luôn có (a.b) mod n = ( (a mod n).(b mod n) ) mod n.
Thật vậy, đặt a = ka.n + ra và b = kb.n + rb với ra = (a mod n) và rb = (b mod n)
18
19. chúng ta thấy (a.b) = ka.kb.n.n + ka.n.rb + kb.n.ra + ra.rb
rõ ràng (a.b) mod n = (ra.rb) mod n = ( (a mod n).(b mod n) ) mod n
Tính chất 2: Với mọi số nguyên không âm a, mọi số nguyên d>1, và mọi số nguyên n>1,
chúng ta luôn có (ad mod n) = ( (a mod n)d mod n).
Có thể chứng minh bằng cách sử dụng tính chất 1 trên nhưng trước hết cần phải chứng
minh tính kết hợp của các tích. Chúng tôi sẽ đưa ra cách chứng minh bằng sử dụng nhị thức
đặt a = ka.n + ra với ra = (a mod n)
d
d
d −1
0
1
d
ta có a d = ( k a .n + ra ) = C d .( k a .n ) + C d .( k a .n ) .ra + .. + C d .rad
d
chỉ có thành phần cuối cùng C d .rad không chứa n do đó không chia hết cho n
((
)
) (
) (
nên (a d mod n) = C dd .rad mod n = rad mod n = ( a mod n ) mod n
d
)
Tính chất 3: Với mọi số nguyên n>1, và mọi số a không chia hết cho n, chúng ta luôn có
(aϕ(n) mod n) = 1
Chúng tôi không chứng minh định lý này vì nó cần đến nhiều kiến thức của đại số đại
cương và lý thuyết số, hơn nữa đây công thức của định lý Euler có thể tìm thấy ở bất kỳ sách
lý thuyết số nào.
I.4.4. Tính toán trên số lớn (large number calculus)
Các số nguyên tố dùng trong thuật toán này thường rất lớn. Các tác giả khuyến cáo khoảng
trên 10100. Do đó chúng ta không thể dùng các phép toán số học thông thường để tính toán các
số như vậy mà chúng ta cần xây dựng lại phép toán cơ sở để tính toán trên số lớn.
Phép tính luỹ thừa (xd mod n) được coi là cơ sở cho hệ mã hoá RSA, do đó chúng ta xét
triển khai của phép toán này trước. Để hiểu được cách tiến hành của thuật toán, chúng ta hãy
quan sát ví dụ về tính toán trên số mũ
a15 = a1111b = a1000b.a100b.a10b.a = ((a2)2)2.(a2)2.a2.a = y3.y2.y1.y0
a10 = a1010b = a1000b.a10b = ((a2)2)2.a2 = y3.y1
Trong đó y0 = a, y1 = y02, y2 = y12, y3 = y22, ...
Bảng 24 : Ví dụ về cách tính nhanh hàm mũ
Điều này dẫn ta đến một thuật toán tính nhanh số mũ mà chỉ cần lặp log 2n lần so với thuật
toán lặp n lần thông thường, với n là số mũ cần tính
p = 1; y = a;
for(i=0; i<log2n; i++) {
if(ni == 1) p = p*y;
y = y*y;
}
Ban đầu p=1, y=a, giả sử n=1111b
i=0, p = a, y = a2
i=1, p = a.a2, y = a4
i=2, p = a.a2.a4, y = a8
i=3, p = a.a2.a4.a8, y = a16
Bảng 25 : Thủ tục tính nhanh hàm mũ
19
20. Trong trường hợp thuật toán của chúng ta bao gồm cả phép mod, ta chỉ cần cải tiến chút ít
do tính chất phân phối của phép mod đối với phép nhân và phép luỹ thừa.
p = 1; y = a%n; //y=a không cần y = a%n
for(i=0; i<log2n; i++) {
if(ni == 1) p = (p*y)%n;
y = (y*y)%n;
}
Ban đầu p=1, y=(a%n), giả sử n=1111b
i=0, p = (a % n), y = a2 % n
i=1, p = (a3 % n), y = (a4 % n)
i=2, p = (a7 % n), y = (a8 % n)
i=3, p = (a15 % n), y = (a16 % n)
Bảng 26 : Thủ tục tính nhanh hàm (xd mod n)
Ký hiệu phần trăm trong đoạn chương trình dùng thay cho phép mod. Chúng ta thấy trong
ứng dụng của chúng ta, các giá trị y và p luôn nhỏ hơn n do a cũng nhỏ hơn n. Chúng chỉ lớn
hơn khi có phép nhân, do đó chúng ta chỉ dùng phép mod với phép nhân.
Ngoài các phép toán trên, chúng ta cần phải triển khai các phép gán số lớn, so sánh hai số
lớn, lấy log cơ số hai của một số lớn, tăng một số lớn, nhân hai số lớn, mod hai số lớn. Tuy
nhiên các phép toán này rất dễ dàng triển khai.
I.5. Kết hợp giữa DES và RSA
Để trao đổi nhanh chóng các bản tin giữa hai điểm truyền tin, người ta thường phải dùng
các hệ thống mã bí mật như DES. Nhưng vì DES có một nhược điểm là phải trao đổi khoá bí
mật trước khi thực hiện truyền thông bí mật. Do đó chúng ta cần phải chuyển khoá bằng một
hệ mã công khai như RSA. Vì vậy một hệ trao đổi kết hợp như vậy phải có những hoạt động
sau
-
Đối tượng cần truyền tin A gửi tín hiệu yêu cầu nhận tin tới đối tượng B
-
Đối tượng B chấp nhận và gửi khoá công khai EB cho đối tượng A
-
Đối tượng A sinh ra khoá bí mật K, mã hoá thành EB(K), rồi gửi cho B
-
Đối tượng B nhận EB(K), giải mã lại thành K, và gửi sẵn sàng nhận tin cho A
-
Đối tượng A chuẩn bị gói tin P, mã hoá thành K(P), rồi gửi cho B
-
Đối tượng B nhận gói K(P), giải mã thành P, và lưu lại cho mình
20
21. II – Mã hoá hàm băm
II.1. Giới thiệu
Việc sử dụng các hệ mật mã và các sơ đồ chữ ký số, thường là mã hóa và ký số trên từng
bit của thông tin, sẽ tỷ lệ với thời gian để mã hóa và dung lượng của thông tin. Thêm vào đó
có thể xảy ra trường hợp: Với nhiều bức thông điệp đầu vào khác nhau, sử dụng hệ mật mã,
sơ đồ ký số giống nhau (có thể khác nhau) thì cho ra kết quả bản mã, bản ký số giống nhau
(ánh xạ N-1: nhiều – một), như Hình 6. Điều này sẽ dẫn đến một số rắc rối về sau cho việc
xác thực thông tin.
Hình 6: Nhiều thông điệp nguồn cho cùng một kết quả đích sau mã hóa hay ký số.
Với các sơ đồ ký số, chỉ cho phép ký các bức thông điệp (thông tin) có kích thước nhỏ và
sau khi ký, bản ký số có kích thước gấp đôi bản thông điệp gốc – ví dụ với sơ đồ chữ ký
chuẩn DSS chỉ ký trên các bức thông điệp có kích thước 160 bit, bản ký số sẽ có kích thước
320 bit. Trong khi đó trên thực tế, ta cần phải ký các thông điệp có kích thước lớn hơn nhiều,
chẳng hạn vài chục MegaByte. Hơn nữa, dữ liệu truyền qua mạng không chỉ là bản thông điệp
gốc, mà còn bao gồm cả bản ký số (có dung lượng gấp đôi dung lượng bản thông điệp gốc),
để đáp ứng việc xác thực sau khi thông tin đến người nhận.
Một cách đơn giản để giải bài toán (với thông điệp có kích thước vài chục MB) này là chặt
thông điệp thành nhiều đoạn 160 bit, sau đó ký lên các đoạn đó độc lập nhau. Nhưng biện
pháp này có một số vấn đề trong việc tạo ra các chữ ký số:
•
Thứ nhất: với một thông điệp có kích thước a, thì sau khi ký kích thước của chữ ký
sẽ là 2a (trong trường hợp sử dụng DSS).
•
Thứ hai: với các chữ ký “an toàn” thì tốc độ chậm vì chúng dùng nhiều phép tính
số học phức tạp như số mũ modulo.
•
Thứ ba : vấn đề nghiêm trọng hơn đó là kết quả sau khi ký, nội dung của thông
điệp có thể bị xáo trộn các đoạn với nhau, hoặc một số đoạn trong chúng có thể bị
mất mát, trong khi người nhận cần phải xác minh lại thông điệp. Ta cần phải bảo vệ
tính toàn vẹn của thông điệp.
21
22. Giải pháp cho các vấn đề vướng mắc đến chữ ký số là dùng hàm băm để trợ giúp cho việc
ký số. Các thuật toán băm với đầu vào là các bức thông điệp có dung lượng, kích thước tùy ý
(vài KB đến vài chục MB thậm chí hơn nữa) – các bức thông điệp có thể là dạng văn bản,
hình ảnh, âm thanh, file ứng dụng v.v… - và với các thuật toán băm: MD2, MD4, MD5, SHA
cho các bản băm đầu ra có kích thước cố định: 128 bit với dòng MD, 160 bit với SHA.
Như vậy, bức thông điệp kích thước tùy ý sau khi băm sẽ được thu gọn thành những bản
băm – được gọi là các văn bản đại diện – có kích thước cố định (128 bit hoặc 160 bit). Với
mỗi thông điệp đầu vào chỉ có thể tính ra được một văn bản đại diện – giá trị băm tương ứng–
duy nhất. Giá trị băm được coi là đặc thù của thông điệp, giống như dấu vân tay của mỗi
người. Hai thông điệp khác nhau chắc chắn có hai văn bản đại diện khác nhau. Khi đã có văn
bản đại diện duy nhất cho bức thông điệp, áp dụng các sơ đồ chữ ký số ký trên văn bản đại
diện đó.
Cơ chế gửi thông tin sử dụng hàm băm trợ giúp cho chữ ký số được mô tả theo thứ tự các
Hình 7a, 7b, 7c.
Hình 7a: Băm thông điệp.
Hình 7b: Ký trên bản băm.
22
23. Hình 7c: Truyền dữ liệu thông tin cần gửi.
Hình 7 : Sơ đồ mô tả các công đoạn người gửi A làm trước khi gửi thông điệp cho người B
(sử dụng hàm băm rồi ký số).
Giả sử A muốn gửi cho B thông điệp x. A thực hiện các bước sau:
1.
A băm thông điệp x (Hình 7a), thu được bản đại diện z = h(x) – có kích thước cố
định 128 bit hoặc 160 bit.
2.
A ký số trên bản đại diện z (Hình 7b), bằng khóa bí mật của mình, thu được bản ký
số y = sig K1 (z).
3.
A gửi (x, y) cho B (Hình 7c).
Khi B nhận được (x, y). B thực hiện các bước sau:
1.
B kiểm tra chữ ký số để xác minh xem thông điệp mà mình nhận được có phải
được gửi từ A hay ko bằng cách giải mã chữ ký số y, bằng khóa công khai của A,
được z. (Hình 8a)
2.
B dùng một thuật toán băm – tương ứng với thuật toán băm mà A dùng – để băm
thông điệp x đi kèm, nhận được h(x). (Hình 8b)
3.
B so sánh 2 giá trị băm z và h(x), nếu giống nhau thì chắc chắn rằng thông điệp x –
mà A muốn gửi cho B – còn nguyên vẹn, bên cạnh đó cũng xác thực được người
gửi thông tin là ai. (Hình 8c)
Hình 8a: Xác minh chữ ký.
23
24. Hình 8b: Tiến hành băm thông điệp x đi kèm.
Hình 8c: Kiểm tra tính toàn vẹn của thông điệp.
Hình 8 : Sơ đồ mô tả các công đoạn sau khi người B nhận được thông điệp.
Hàm băm đã trợ giúp cho các sơ đồ ký số nhằm giảm dung lượng của dữ liệu cần thiết để
truyền qua mạng (lúc này chỉ còn bao gồm dung lượng của bức thông điệp gốc và 256 bit (sử
dụng MD) hay 320 bit (sử dụng SHA) của bức ký số được ký trên bản đại diện của thông điệp
gốc), tương đương với việc giảm thời gian truyền tin qua mạng.
Hàm băm thường kết hợp với chữ ký số để tạo ra một loại chữ ký điện tử vừa an toàn hơn
(không thể cắt/dán) vừa có thể dùng để kiểm tra tính toàn vẹn của thông điệp.
Hàm băm được ứng dụng rất mạnh trong vấn đề an toàn thông tin trên đường truyền. Các
ứng dụng có sử dụng hàm băm không chỉ đảm bảo về mặt an toàn thông tin, mà còn tạo được
lòng tin của người dùng vì họ có thể dễ dàng phát hiện được thông tin của mình có còn toàn
vẹn hay không, họ biết rằng thông tin của mình chắc chắn được bí mật với phía các nhà cung
cấp.
II.2. Hàm băm
II.2.1. Định nghĩa
Hàm băm là các thuật toán không sử dụng khóa để mã hóa (ở đây ta dùng thuật ngữ “băm”
thay cho “mã hóa”), nó có nhiệm vụ “lọc” (băm) thông điệp được đưa vào theo một thuật toán
h một chiều nào đó, rồi đưa ra một bản băm – văn bản đại diện – có kích thước cố định. Do
đó người nhận không biết được nội dung hay độ dài ban đầu của thông điệp đã được băm
bằng hàm băm.
Giá trị của hàm băm là duy nhất, và không thể suy ngược lại được nội dung thông điệp từ
giá trị băm này.
II.2.2. Đặc trưng
Hàm băm h là hàm băm một chiều (one-way hash) với các đặc tính sau:
24
25. •
Với thông điệp đầu vào x thu được bản băm z = h(x) là duy nhất.
•
Nếu dữ liệu trong thông điệp x thay đổi hay bị xóa để thành thông điệp x’ thì h(x’)
≠ h(x). Cho dù chỉ là một sự thay đổi nhỏ hay chỉ là xóa đi 1 bit dữ liệu của thông
điệp thì giá trị băm cũng vẫn thay đổi. Điều này có nghĩa là: hai thông điệp hoàn
toàn khác nhau thì giá trị hàm băm cũng khác nhau.
•
Nội dung của thông điệp gốc không thể bị suy ra từ giá trị hàm băm. Nghĩa là: với
thông điệp x thì dễ dàng tính được z = h(x), nhưng lại không thể (thực chất là khó)
suy ngược lại được x nếu chỉ biết giá trị hàm băm h(x).
II.2.3. Tính chất
Việc đưa hàm băm h vào dùng trong sơ đồ chữ ký số không làm giảm sự an toàn của sơ đồ
chữ ký số vì nó là bản tóm lược thông báo – bản đại diện cho thông điệp – được ký chứ không
phải là thông điệp gốc. Điều cần thiết đối với h là cần thỏa mãn một số tính chất sau để tránh
bị giả mạo:
Tính chất 1: Hàm băm h là không va chạm yếu
Xét một kiểu tấn công như sau:
Đáng lẽ: thông tin phải được truyền đúng từ A đến B (Hình 9a)
Hình 9a: Cách đi đúng của thông tin
Nhưng: trên đường truyền, thông tin bị lấy trộm và bị thay đổi (Hình 9b)
Hình 9b: Thông tin bị lấy trộm và bị thay đổi trên đường truyền
Hình 9 : Sơ đồ mô tả cho kiểu tấn công của tính chất 1
Người A gửi cho B (x, y) với y = sigK(h(x)). Nhưng trên đường truyền, tin bị lấy trộm. Tên
trộm, bằng cách nào đó tìm được một bản thông điệp x’ có h(x’) = h(x) mà x’ ≠ x. Sau đó,
hắn đưa x’ thay thế x rồi truyền tiếp cho người B. Người B nhận được và vẫn xác thực được
thông tin đúng đắn.
25
26. Do đó, để tránh kiểu tấn công như Hình 9b, hàm h phải thỏa mãn tính không va chạm yếu:
Hàm băm h là không va chạm yếu nếu khi cho trước một bức điện x, không thể tiến hành về
mặt tính toán để tìm ra một bức điện x’ ≠ x mà h(x’) = h(x).
Tính chất 2: Hàm băm h là không va chạm mạnh:
Xét một kiểu tấn công như sau: Đầu tiên, tên giả mạo tìm ra được hai bức thông điệp x’ và
x (x’ ≠ x) mà có h(x’) = h(x) (ta coi bức thông điệp x là hợp lệ, còn x’ là giả mạo). Tiếp theo,
hắn đưa cho ông A và thuyết phục ông này kí vào bản tóm lược h(x) để nhận được y. Khi đó
(x’, y) là bức điện giả mạo nhưng hợp lệ.
Để tránh kiểu tấn công này, hàm h phải thỏa mãn tính không va chạm mạnh: Hàm băm h là
không va chạm mạnh nếu không có khả năng tính toán để tìm ra hai bức thông điệp x và x’
mà x ≠ x’ và h(x) = h(x’).
Tính chất 3: Hàm băm h là hàm một chiều:
Xét một kiểu tấn công như sau: Việc giả mạo các chữ ký trên bản tóm lược z thường xảy ta
với các sơ đồ chữ ký số. Giả sử tên giả mạo tính chữ ký trên bản tóm lược z, sau đó hắn tìm
một bản thông điệp x’ được tính ngược từ bản đại diện z, z = h(x’). Tên trộm thay thế bản
thông điệp x hợp lệ bằng bản thông điệp x’ giả mạo, nhưng lại có z = h(x’). Và hắn ký số trên
bản đại diện cho x’ bằng đúng chữ ký hợp lệ. Nếu làm được như vậy thì (x’, y) là bức điện giả
mạo nhưng hợp lệ.
Để tránh được kiểu tấn công này, h cần thỏa mãn tính chất một chiều: Hàm băm h là một
chiều nếu khi cho trước một bản tóm lược thông báo z thì không thể thực hiện về mặt tính
toán để tìm ra thông điệp ban đầu x sao cho h(x) = z .
II.2.4. Các thuật toán băm
Các hàm băm dòng MD: MD2, MD4, MD5 được Rivest đưa ra thu được kết quả đầu ra với
độ dài là 128 bit. Hàm băm MD4 đưa ra vào năm 1990. Một năm sau phiên bản mạnh MD5
cũng được đưa ra. Chuẩn hàm băm an toàn: SHA, phức tạp hơn nhiều cũng dựa trên các
phương pháp tương tự, được công bố trong Hồ sơ Liên bang năm 1992 và được chấp nhận
làm tiêu chuẩn vào năm 1993 do Viện Tiêu Chuẩn và Công Nghệ Quốc Gia (NIST), kết quả
đầu ra có độ dài 160 bit.
Như đã nêu trong chương mở đầu, thông điệp đầu vào cho các hàm băm có thể là: dạng
văn bản, dạng hình ảnh, dạng .exe ….
II.2.4.1. Khái niệm “Thông điệp đệm”
“Thông điệp đệm” – messege padding - là một xâu bit có độ dài chia hết cho 512.
“Thông điệp đệm” được lưu trong mảng
M = M[0] M[1] … M[N-1].
Trong đó M[i] là xâu bit có độ dài 32 bit, gọi là word; N mod 16 = 0.
M được xây dựng từ thông điệp a bằng thuật toán:
26
27. 1. d = 447 – (|a| mod 512); (+ 512, trường hợp |a| mod 512 > 447).
2. Giả sử l là kí hiệu biểu diễn nhị phân của |a| mod 264, tl: |l| = 64.
3. M = a || 1 || 0d || l
Bảng 27 : Xây dựng thông điệp đệm M từ a
Độ dài của xâu a || 1 || 0d
Độ dài của “Thông điệp đệm” M là
là
|a| + 1 + d = 448 mod 512 .
448 mod 512 + 64 = 512 mod 512.
Ví dụ : Có xâu đầu vào a = “ABC”, ta có kết quả xây dựng M như sau:
a = “ABC” = "01000001 01000010 01000011"
Độ dài tính theo bit của xâu a:
|a| = 24 bit
=> d = 447 – (|a| mod 512) = 423.
|a| + 1 + d = 24 + 1 + 423 =
448 mod 512.
Biểu diễn nhị phân của độ dài xâu a là l:
00
l = |a| mod 264 = 24 mod 264 = 24 = 16 + 8 = ( 00..... 11000 )2
59 so
00
=> Độ dài của l là |l| = | 00..... 11000| = 59 + 5 = 64.
59 so
M = a || 1 || 0d || l
00 00
=> M = 01000001 01000010 01000011 || 1 || 00..... || 00..... 11000
423 so
M = M[0] M[1] … M[N-1], N
≡
59 so
0 mod 16
M[0] = 01000001 01000010 01000011 10000000
00
M[1] = M[2] = ….. = M[13] = M[14] = 00.....
32 so
M[15] = 00000000 00000000 00000000 00011000
Trong việc xây dựng M, ta gắn số 1 đơn lẻ vào sau a, sau đó thêm tiếp các số 0 vào đủ để
độ dài của M đồng dư với 448 modulo 512. Cuối cùng nối thêm 64 bit (chính là |l|) chứa biểu
diễn nhị phân về độ dài ban đầu của x (được rút gọn theo modulo 264 nếu cần).
Xâu kết quả M có độ dài chia hết cho 512. Vì thế khi chặt M thành các word 32 bit, số
word nhận được là N sẽ chia hết cho 16.
Mục đích việc tạo ra mảng M – “thông điệp đệm” – là để các hàm băm xử lý trên từng
khối (block) 512 bit, tức là 16 word, cùng một lúc.
27
28. II.2.4.2. Hàm băm MD4
Input
: Thông điệp có độ dài tùy ý.
Ouput
: Bản băm, đại diện cho thông điệp gốc, độ dài cố định 128 bit.
Mô tả thuật toán
Giả sử đầu vào là một xâu a có độ dài b bit (b có thể bằng 0)
Bước 1: Khởi tạo các thanh ghi
Có 4 thanh ghi được sử dụng để tính toán nhằm đưa ra các đoạn mã: A, B, C, D. Bản tóm
lược của thông điệp được xây dựng như sự kết nối của các thanh ghi. Mỗi thanh ghi có độ dài
32 bit. Các thanh ghi này được khởi tạo giá trị hecxa.
word
word
word
word
A := 67 45 23 01
B := EF CD AB 89
C := 98 BA DC FE
D := 10 32 54 76
Bước 2:
Xử lý thông điệp a trong 16 khối word, có nghĩa là xử lý cùng một lúc 16 word = 512 bit
(chia mảng M thành các khối 512 bit, đưa từng khối 512 bit đó vào mảng T[j]). Mỗi lần xử lý
một khối 512 bit. Lặp lại N/16 lần.
1.
A = 67
B = ef
C = 98
D = 10
2.
for i := 0 to n/16 - 1 do {
3.
45
cd
ba
32
23
ab
dc
54
01
89
fe
76
for j := 0 to 15 do T[j] = M[16i + j];
//Mỗi lần xử lý 16 từ, mỗi từ 32 bit, tl: 512 bit.
4.
AA := A;
BB := B;
CC := C;
DD := D;
5.
6.
7.
round_1();
round_2();
round_3();
8.
A = A + AA
B = B + BB
C = C + CC
D = D + DD
}
Bảng 28 : Thuật toán MD4
28
29. a
T = getFromM(i*16, 16)
AA = A
BB = B
CC = C
DD = D
round_1()
round_2()
round_3()
A = A + AA
B = B + BB
C = C + CC
D = D + DD
i=i+1
M = getBufferMsg(a)
A = 67 45 23
B = ef cd ab
C = 98 ba dc
D = 10 32 54
n = length(M)
i=0
01
89
fe
76
F
T
i > n div 16
-1
DCBA
Hình 10 : Lược đồ thuật toán MD4
Gán giá trị cho bốn biến AA, BB, CC, DD lần lượt bằng giá trị của 4 thanh ghi A, B, C, D.
Ba vòng “băm”.
Một số phép toán logic được sử dụng trong ba vòng này.
X
∧
Y là phép toán AND theo bit giữa X và Y
X
∨
Y là phép toán OR theo bit giữa X và Y
X ⊕ Y là phép toán XOR theo bit giữa X và Y
¬
X chỉ phép bù của X
X + Y là phép cộng theo modulo 232
X <<< s là phép dịch vòng trái X đi s vị trí (0 ≤ s ≤ 31)
Các vòng 1, 2 và 3 dùng tương ứng ba hàm F, G và H.
Mỗi hàm này là một hàm boolean tính theo bit.
F(X, Y, Z) = (X ∧ Y) ∨ (( ¬ X) ∧ Z)
G(X, Y, Z) = (X ∧ Y) ∨ (X ∧ Z) ∨ (Y ∧ Z)
29
30. H(X, Y, Z) = X ⊕Y ⊕Z
Ba vòng trong MD4 là hoàn toàn khác nhau. Mỗi vòng (3.1, 3.2, 3.3) gồm một trong 16
word trong T được xử lý. Các phép toán được thực hiện trong ba vòng tạo ra các giá trị mới
trong bốn thanh ghi. Cuối cùng, bốn thanh ghi được cập nhật ở 3.4 bằng cách cộng ngược các
giá trị lưu trước đó ở 2.3. Phép cộng này được xác định là cộng các số nguyên dương, được
rút gọn theo modulo 232.
Vòng 1 (round_1())
STT
Phép toán
STT
Phép toán
1
2
3
4
5
6
7
8
A = (A + F(B, C, D) + T[0]) <<< 3
D = (D + F(A, B, C) + T[1]) <<< 7
C = (C + F(D, A, B) + T[2]) <<< 11
B = (B + F(C, D, A) + T[3]) <<< 19
A = (A + F(B, C, D) + T[4]) <<< 3
D = (D + F(A, B, C) + T[5]) <<< 7
C = (C + F(D, A, B) + T[6]) <<< 11
B = (B + F(C, D, A) + T[7]) <<< 19
9
10
11
12
13
14
15
16
A = (A + F(B, C, D) + T[8]) <<< 3
D = (D + F(A, B, C) + T[9]) <<< 7
C = (C + F(D, A, B) + T[10]) <<< 11
B = (B + F(C, D, A) + T[11]) <<< 19
A = (A + F(B, C, D) + T[12]) <<< 3
D = (D + F(A, B, C) + T[13]) <<< 7
C = (C + F(D, A, B) + T[14]) <<< 11
B = (B + F(C, D, A) + T[15]) <<< 19
Bảng 29: Phép toán trong Vòng 1
Kết quả của VD a sau khi được xử lý qua vòng 1.
1. 64B3DA82
5. 3D5E5934
9. 59798D5E
13. 7551AAC6
2. 34D8EB03
6. 489D5140
10. D206302D
14. 789B984F
3. B7BCB118
7. CCD14D6C
11. 753D6134
15. F55A1F31
4. 6D91B115
8. 454D0E92
12. F52AED08
16. ABA71E22
Bảng 30 : Kết quả sau Vòng 1
Vòng 2 (round_2())
1. A = (A + G(B, C, D) + T[0] + 5A827999) <<< 3
2. D = (D + G(A, B, C) + T[4] + 5A827999) <<< 5
3. C = (C + G(D, A, B) + T[8] + 5A827999) <<< 9
4. B = (B + G(C, D, A) + T[12] + 5A827999) <<< 13
5. A = (A + G(B, C, D) + T[1] + 5A827999) <<< 3
6. D = (D + G(A, B, C) + T[5] + 5A827999) <<< 5
7. C = (C + G(D, A, B) + T[9] + 5A827999) <<< 9
8. B = (B + G(C, D, A) + T[13] + 5A827999) <<< 13
9. A = (A + G(B, C, D) + T[2] + 5A827999) <<< 3
10. D = (D + G(A, B, C) + T[6] + 5A827999) <<< 5
30
31. 11. C = (C + G(D, A, B) + T[10] + 5A827999) <<< 9
12. B = (B + G(C, D, A) + T[14] + 5A827999) <<< 13
13. A = (A + G(B, C, D) + T[3] + 5A827999) <<< 3
14. D = (D + G(A, B, C) + T[7] + 5A827999) <<< 5
15. C = (C + G(D, A, B) + T[11] + 5A827999) <<< 9
16. B = (B + G(C, D, A) + T[15] + 5A827999) <<< 13
Bảng 31 : Phép toán trong Vòng 2
Giá trị 5A827999 là một hằng số ở dạng hecxa có độ dài 32 bit
Kết quả của VD a sau khi được xử lý qua vòng 2.
1. 558C2E28
5. 558C2E28
9. 31E9FE4A
13. B60A11E6
2. 5A0E08F9
6. 5A0E08F9
10. 6F68E462
14. 2DED6D8E
3. F6A9B390
7. F6A9B390
11. D745F88A
15. A2870B31
4. 7876BC8F
8. 7876BC8F
12. 7050BC10
16. 4384D178
Bảng 32 : Kết quả sau Vòng 2
Vòng 3 (round_3())
1. A = (A + H(B, C, D) + T[0] + 6ED9EBA1) <<< 3
2. D = (D + H(A, B, C) + T[8] + 6ED9EBA1) <<< 9
3. C = (C + H(D, A, B) + T[4] + 6ED9EBA1) <<< 11
4. B = (B + H(C, D, A) + T[12] + 6ED9EBA1) <<< 15
5. A = (A + H(B, C, D) + T[2] + 6ED9EBA1) <<< 3
6. D = (D + H(A, B, C) + T[10] + 6ED9EBA1) <<< 9
7. C = (C + H(D, A, B) + T[6] + 6ED9EBA1) <<< 11
8. B = (B + H(C, D, A) + T[14] + 6ED9EBA1) <<< 15
9. A = (A + H(B, C, D) + T[1] + 6ED9EBA1) <<< 3
10. D = (D + H(A, B, C) + T[9] + 6ED9EBA1) <<< 9
11. C = (C + H(D, A, B) + T[5] + 6ED9EBA1) <<< 11
12. B = (B + H(C, D, A) + T[13] + 6ED9EBA1) <<< 15
13. A = (A + H(B, C, D) + T[3] + 6ED9EBA1) <<< 3
14. D = (D + H(A, B, C) + T[11] + 6ED9EBA1) <<< 9
15. C = (C + H(D, A, B) + T[7] + 6ED9EBA1) <<< 11
16. B = (B + H(C, D, A) + T[15] + 6ED9EBA1) <<< 15
31
32. Bảng 33 : Các phép toán trong Vòng 3
Giá trị 6ED9EBA1 là một hằng số ở dạng hecxa có độ dài 32 bit
Kết quả của VD a sau khi được xử lý qua vòng 3.
1. 98A7C489
5. F3031C80
9. C02E826B
13. 03477E5E
2. E70B031C
6. 7D7A371B
10. F38DC78B
14. 77509F0A
3. A96B2FFA
7. 1C2487DE
11. E3C7F63B
15. FB3D792D
4. 58BE9F94
8. F7767709
12. 812AB00F
16. 23D73C06
Bảng 34: Kết quả sau Vòng 3
Kết quả ra là đoạn mã có độ dài 128 bit, được thu gọn từ thông điệp a có độ dài b bit. Đoạn
mã này thu được từ 4 thanh ghi A, B, C, D: bắt đầu từ byte thấp của thanh ghi A cho đến byte
cao của thanh ghi D.
Với VD a = “ABC”, kết quả cuối cùng là Đại diện văn bản:
D
3409907C
C
93F85626
B
671E4A93
A
6A8CA15F
II.2.4.3. Hàm băm MD5
Mặc dù MD4 vẫn chưa bị phá, song các phiên bản yếu cho phép bỏ qua hoặc vòng thứ nhất
hay thứ ba đều có thể bị phá không khó khăn gì. Nghĩa là dễ dàng tìm thấy các va chạm đối
với các phiên bản chỉ có hai vòng. Phiên bản mạnh của dòng MD là MD5 được công bố năm
1991. MD5 dùng bốn vòng thay cho ba và chậm hơn 30% so với MD4 (khoảng 0,9 MB/giây
trên cùng một máy).
Input : Thông điệp (văn bản) có độ dài tùy ý.
Output
: Bản băm, đại diện cho thông điệp gốc, đồ dài cố định 128 bit.
Mô tả thuật toán
♦ Các bước 1, 2, 3 của MD5 tương tự như của MD4.
♦ Bước 4: Thực hiện bốn vòng băm
Các vòng 1, 2, 3 và 4 dùng tương ứng ba hàm F, G, H và I. Mỗi hàm này là một hàm
boolean tính theo bit. Chúng được xác định như sau:
F(X, Y, Z) = (X ∧ Y) ∨ (( ¬ X) ∧ Z)
G(X, Y, Z) = (X ∧ Z) ∨ (Y ∧ (
¬
Z))
H(X, Y, Z) = X ⊕ ⊕
Y Z
I(X, Y, Z) = Y ⊕(X ∨ (
¬
Z))
32
33. : Quá trình tạo bản băm của MD5.
Hình 10
1.
A := 67
B := ef
C := 98
D := 10
45
cd
ba
32
23
ab
dc
54
01
89
fe
76
2.
for i := 0 to n/16 - 1 do {
3.
for j := 0 to 15 do T[j] = M[16i + j];
4.
AA := A; Mỗi lần xử lý 16 từ, mỗi từ 32 bit, tl: 512 bit.
BB := B;
CC := C;
DD := D;
5.
6.
7.
8.
round_1();
round_2();
round_3();
round_4();
9.
A = A + AA
B = B + BB
C = C + CC
D = D + DD
}
Bảng 35 : Thuật toán MD5
33
34. a
M = getBufferMsg(a)
A = 67 45 23
B = ef cd ab
C = 98 ba dc
D = 10 32 54
n = length(M)
i=0
DCBA
T = getFromM(i*16, 16)
AA = A
BB = B
CC = C
DD = D
round_1()
round_2()
round_3()
round_4()
A = A + AA
B = B + BB
C = C + CC
D = D + DD
i=i+1
01
89
fe
76
F
i > n div 16
-1
T
Hình 12 : Lược đồ thuật toán MD5
Bốn vòng trong MD5 là hoàn toàn khác nhau. Mỗi vòng (5, 6, 7, 8) gồm một trong 16
word trong T.
MD5 sử dụng thêm một mảng S[1 … 64] được xây dựng từ hàm sin. Với S[i], giá trị của
phần tử thứ i trong mảng S, tương đương với phần nguyên của 4294967296 × abs(sin(i)), với
i tính theo radian.
Vòng 1 sử dụng giá trị trong mảng S[1 … 16]
Vòng 2 sử dụng giá trị trong mảng S[17 … 32]
Vòng 3 sử dụng giá trị trong mảng S[33 … 48]
Vòng 4 sử dụng giá trị trong mảng S[49 … 64]
Ta có mảng S[1 … 64] như sau (tất cả đều để ở hệ cơ số 16):
1. D76AA478
17. F61E2562
33. FFFA3942
49. F4292244
2. E8C7B756
18. D040B340
34. 8771F681
50. 432AFF97
3. 242070DB
19. 265E5A51
35. 6D9D6122
51. AB9423A7
34
35. 4. C1BDCEEE
20. E9B6C7AA
36. FDE5390C
52. FC93A039
5. F57C0FAF
21. D62F105D
37. A4BEEA44
53. 655B59C3
6. 4787C62A
22. 02441453
38. 4BDECFA9
54. 8F0CCC92
7. A8304613
23. D8A1E681
39. F6BB4B60
55. FFEFF47D
8. FD469501
24. E7D3FBC
40. BEBFBC70
56. 85845DD1
9. 698098D8
25. 21E1CDE6
41. 289B7EC6
57. 6FA87E4F
10. 8B44F7AF
26. C33707D6
42. EAA127FA
58. FE2CE6E0
11. FFFF5BB1
27. F4D50D87
43. D4EF3085
59. A3014314
12. 895CD7BE
28. 455A14ED
44. 04881D05
60. 4E0811A1
13. 6B901122
29. A9E3E905
45. D9D4D039
61. F7537E82
14. FD987193
30. FCEFA3F8
46. E6DB99E5
62. BD3AF235
15. A679438E
31. 676F02D9
47. 1FA27CF8
63. 2AD7D2BB
16. 49B40821
32. 8D2A4C8A
48. D4AC5665
64. EB86D391
Bảng 36 : Giá trị hằng số của mảng S có 64 phần tử.
Các phép toán được thực hiện trong bốn vòng tạo ra các giá trị mới trong bốn thanh ghi.
Cuối cùng, bốn thanh ghi được cập nhật ở 3.5 bằng cách cộng ngược các giá trị lưu trước đó ở
2.3. Phép cộng này được xác định là cộng các số nguyên dương, được rút gọn theo modulo
232.
Vòng 1 (round_1())
1. A = (A + F(B, C, D) + T0] + S[1] <<< 7
2. D = (D + F(A, B, C) + T[1] + S[2]) <<< 12
3. C = (C + F(D, A, B) + T[2] + S[3]) <<< 17
4. B = (B + F(C, D, A) + T[3] + S[4]) <<< 22
5. A = (A + F(B, C, D) + T[4] + S[5]) <<< 7
6. D = (D + F(A, B, C) + T[5] + S[6]) <<< 12
7. C = (C + F(D, A, B) + T[6] + S[7]) <<< 17
8. B = (B + F(C, D, A) + T[7] + S[8]) <<< 22
9.
A = (A + F(B, C, D) + T[8] + S[9]) <<< 7
10. D = (D + F(A, B, C) + T[9] + S[10]) <<< 12
11. C = (C + F(D, A, B) + T[10] + S[11]) <<< 17
12. B = (B + F(C, D, A) + T[11] + S[12]) <<< 22
13. A = (A + F(B, C, D) + T[12] + S[13]) <<< 7
14. D = (D + F(A, B, C) + T[13] + S[14]) <<< 12
35
36. 15. C = (C + F(D, A, B) + T[14] + S[15]) <<< 17
16. B = (B + F(C, D, A) + T[15] + S[16]) <<< 22
Bảng 37 : Các phép toán trong Vòng 1
Vòng 2 (round_2())
1. A = (A + G(B, C, D) + T[1] + S[17] <<< 5
2. D = (D + G(A, B, C) + T[6] + S[18]) <<< 9
3. C = (C + G(D, A, B) + T[21] + S[19]) <<< 14
4. B = (B + G(C, D, A) + T[0] + S[20]) <<< 20
5.
A = (A + G(B, C, D) + T[5] + S[21]) <<< 5
6.
D = (D + G(A, B, C) + T[10] + S[22]) <<< 9
7.
C = (C + G(D, A, B) + T[15] + S[23]) <<< 14
8.
B = (B + G(C, D, A) + T[4] + S[24]) <<< 20
9.
A = (A + G(B, C, D) + T[9] + S[25]) <<< 5
10. D = (D + G(A, B, C) + T[14] + S[26]) <<< 9
11. C = (C + G(D, A, B) + T[3] + S[27]) <<< 14
12. B = (B + G(C, D, A) + T[8] + S[28]) <<< 20
13. A = (A + G(B, C, D) + T[13] + S[29]) <<< 5
14. D = (D + G(A, B, C) + T[2] + S[30]) <<< 9
15. C = (C + G(D, A, B) + T[7] + S[31]) <<< 14
16. B = (B + G(C, D, A) + T[12] + S[32]) <<< 20
Bảng 38 : Các phép toán Vòng 2
Vòng 3 (round_1())
1. A = (A + H(B, C, D) + T[5] + S[33]) <<< 4
2. D = (D + H(A, B, C) + T[8] + S[34]) <<< 11
3. C = (C + H(D, A, B) + T[11] + S[35]) <<< 16
4. B = (B + H(C, D, A) + T[14] + S[36]) <<< 23
5. A = (A + H(B, C, D) + T[1] + S[37]) <<< 4
6. D = (D + H(A, B, C) + T[4] + S[38]) <<< 11
7. C = (C + H(D, A, B) + T[7] + S[39]) <<< 16
8. B = (B + H(C, D, A) + T[10] + S[40]) <<< 23
36
37. 9. A = (A + H(B, C, D) + T[13] + S[41]) <<< 4
10. D = (D + H(A, B, C) + T[0] + S[42]) <<< 11
11. C = (C + H(D, A, B) + T[3] + S[43]) <<<16
12. B = (B + H(C, D, A) + T[6] + S[44]) <<< 23
13. A = (A + H(B, C, D) + T[9] + S[45]) <<< 4
14. D = (D + H(A, B, C) + T[12] + S[46]) <<< 11
15. C = (C + H(D, A, B) + T[15] + S[47]) <<< 16
16. B = (B + H(C, D, A) + T[2] + S[48]) <<< 23
Bảng 39 : Các phép toán Vòng 3
Vòng 4 (round_4())
1. A = (A + I(B, C, D) + T[0] + S[49]) <<< 6
2. D = (D + I(A, B, C) + T[7] + S[50]) <<< 10
3. C = (C + I(D, A, B) + T[14] + S[51]) <<< 15
4. B = (B + I(C, D, A) + T[5] + S[52]) <<< 21
5. A = (A + I(B, C, D) + T[12] + S[53]) <<< 6
6. D = (D + I(A, B, C) + T[3] + S[54]) <<< 10
7. C = (C + I(D, A, B) + T[10] + S[55]) <<< 15
8. B = (B + I(C, D, A) + T[1] + S[56]) <<< 21
9. A = (A + I(B, C, D) + T[8] + S[57]) <<< 6
10. D = (D + I(A, B, C) + T[15] + S[58]) <<< 10
11. C = (C + I(D, A, B) + T[6] + S[59]) <<< 15
12. B = (B + I(C, D, A) + T[13] + S[60]) <<< 21
13. A = (A + I(B, C, D) + T[4] + S[61]) <<< 6
14. D = (D + I(A, B, C) + T[11] + S[62]) <<< 10
15. C = (C + I(D, A, B) + T[2] + S[63]) <<< 15
16. B = (B + I(C, D, A) + T[9] + S[64]) <<< 21
Bảng 40 : Các phép toán Vòng 4
♦ Bước 5: Output
Kết quả ra là đoạn mã có độ dài 128 bit, được thu gọn từ thông điệp a có độ dài b bit. Đoạn
mã này thu được từ 4 thanh ghi A, B, C, D: bắt đầu từ byte thấp của thanh ghi A cho đến byte
cao của thanh ghi D.
37
38. II.2.4.4. Hàm băm chuẩn SHA
Chuẩn hàm băm SHA phức tạp và chậm hơn dòng MD. SHA được thiết kế để chạy trên
máy kiến trúc endian lớn hơn là trên máy endian nhỏ. SHA tạo ra bản tóm lược thông điệp có
kích thước 160 bit, sử dụng 5 thanh ghi 32 bit.
Input
: Thông điệp (văn bản) có độ dài tùy ý
Output
: Bản băm, đại diện cho thông điệp gốc, độ dài cố định 160 bit.
Mô tả thuật toán:
Giả sử đầu vào là một xâu a có độ dài b bit (b có thể bằng 0). SHA sử dụng các hàm
boolean sau để tính toán:
F(X, Y, Z) = (X
∧
Y)
∨
((
¬
X)
∧
Z) với 0 ≤ t ≤ 19
với 20 ≤ t ≤ 39
G(X, Y, Z) = X ⊕ Y ⊕ Z
H(X, Y, Z) = (X ∧ Y) ∨ (Y ∧ Z) ∨ (Z ∧ X) với 40 ≤ t ≤ 59
với 60 ≤ t ≤ 79
I(X, Y, Z) = X ⊕ Y ⊕ Z
Sử dụng bốn hằng 32 bit:
K1 = 5A827999
với 0 ≤ t ≤ 19
K2 = 6ED9EBA1
với 20 ≤ t ≤ 39
K3 = 8F1BBCDC
với 40 ≤ t ≤ 59
K4 = CA62C1D6
với 60 ≤ t ≤ 79
♦ Bước 1: Khởi tạo các thanh ghi.
Có 5 thanh ghi được khởi tạo: A, B, C, D, E. Bản tóm lược của thông điệp được xây dựng
như sự kết nối của các thanh ghi. Mỗi thanh ghi có độ dài 32 bit. Các thanh ghi này được khởi
tạo giá trị hecxa.
word A = 67 45 23 01
word B = EF CD AB 89
word C = 98 BA DC FE
word D = 10 32 54 76
word E = C3 D2 E1 F0
♦ Bước 2: Xử lý thông điệp a.
Xử lý từng khối, 512 bit, bao gồm 16 word, Mỗi khối được xử lý khoảng 80 bước thông
qua mảng W[t], với 0 ≤ t ≤ 79.
2.1
2.2
2.3
for i = 0 to n/16 - 1 do {
for t = 0 to 15 do W[t] = M[16i + t]
for t = 16 to 79 do
38
39. W[t] = (W[t-3] ⊕ W[t-8] ⊕ W[t-14] ⊕ W[t-16]) <<< 1
AA = A;
BB = B;
CC = C;
DD = D;
EE = E;
for t = 0 to 19 do {
Temp = (A<<<5) + F(B, C, D) + E + W[t] + K1;
EE = DD;
DD = CC;
CC = BB<<<30;
BB = AA;
AA = Temp;
}
2.4
2.5
2.6
for t = 20 to 39 do {
Temp = (A<<<5) + G(B, C, D) + E + W[t] + K2;
EE = DD;
DD = CC;
CC = BB<<<30;
BB = AA;
AA = Temp;
}
2.7
2.8
2.9
}
.
for t = 40 to 59 do {
Temp = (A<<<5) + H(B, C, D) + E + W[t] + K3;
EE = DD;
DD = CC;
CC = BB<<<30;
a
BB = AA;
AA = Temp;
}
M = getBufferMsg(a)
W = getFromM(i*16, 16)
fillUp(W, 16, 80)
for t = 60 to 79 do {
AA = A
Temp = (A<<<5) + I(B, C, D) BB = B
+ E + W[t] + K4;
K1 = 5A827999DD;
EE =
CC = C
DD = CC;
DD = D
K2 = 6ED9EBA1
CC = BB<<<30;
EE = E
K3 = 8F1BBCDC
BB = AA;
process(0,19, F, K1)
K4 = CA62C1D6
AA = Temp;
process(20,39, G, K2)
A } 67 45 23 01
=
process(40,59, H, K3)
B A ef Acd AA 89
= = + ab
process(60,79, I, K4)
C B 98Bba BB fe
= = + dc
D C 10C32 CC 76
= = + 54
A = A + AA
D = d2 e1
E = c3 D + DD f0
B = B + BB
E
i = 0= E + EE
C = C + CC
n = length(M)
D = D + DD
E=E+
Bảng 41 : Thuật toán SHA EE
i=i+1
EDCBA
F
T
39
i > n div 16
-1
Hình 13 : Lược đồ thuật toán SHA
40. ♦ Bước 3: Output
Kết quả ra là đoạn mã có độ dài 160 bit, được thu gọn từ thông điệp a có độ dài b bit. Đoạn
mã này thu được từ 5 thanh ghi A, B, C, D, E; bắt đầu từ byte thấp của thanh ghi A cho đến
byte cao của thanh ghi E.
Ví dụ: với thông điệp đầu vào a = “abc”, ta có mảng M như sau:
|a| = |01100001 01100010 01100011|
=> |a| = 24 bit
=> d = 447 – (24 mod 512) = 423
00
|a| mod 264 = 24 mod 264 = 24 => |l| = | 00..... 11000|
59 so
00 00
=> M = 01100001 01100010 01100011 || 1 || 00..... || 00..... 11000
423 so
M = M[0] M[1] … M[N-1], N
≡
59 so
0 mod 16
M[0] = (1100001 01100010 01100011 10000000)2 = (61 62 63 80)16
40
41. 00
M[1] = M[2] = ….. = M[13] = M[14] = ( 00..... )2 = (00 00 00 00)16
32 so
M[15] = (00000000 00000000 00000000 00011000)2 = (00000018)16
Trong trường hợp này, mảng M vừa tròn 1 khối 512 bit, gồm 16 word từ M[0] đến M[15].
Đưa từng khối 512 bit vào mảng W[t], với 0 ≤ t ≤ 79
for i = 0 to N/16 - 1 do
for t = 0 to 15 do W[t] = M[16i + t]
W[0] = M[0] = 61626368
W[1] = … = W[14] = M[1] = … M[14] = 00000000
W[15] = M[15] = 00000018
Tính các W[t], với 16 ≤ t ≤ 79
for t = 16 to 79 do
W[t] = (W[t-3] ⊕ W[t-8] ⊕ W[t-14] ⊕ W[t-16]) <<< 1
Gán giá trị cho các biến
AA = A = 67 45 23 01
BB = B = ef cd ab 89
CC = C = 98 ab cd fe
DD = D = 10 32 54 76
EE = E = c3 d2 e1 f0
W[16] = 2C4C700C
W[37] = 626F8061
W[58] = 15799C23
W[17] = 00000000
W[38] = 38066261
W[59] = B0B59051
W[18] = 00000300
W[39] = 000C1800
W[60] = 65222C20
W[19] = 898E0185
W[40] = 4C7619A8
W[61] = 13FC754E
W[20] = 00000000
W[41] = 185610C0
W[62] = DF340994
W[21] = 00006000
W[42] = 19DB9820
W[63] = 83211988
W[22] = 31C030B1
W[43] = BE01E58F
W[64] = B430014C
W[23] = 00000300
W[44] = 2849B457
W[65] = 7CAB2F7F
W[24] = 89820185
W[45] = 7C1C142C
W[66] = 4F3A95A6
W[25] = 38061626
W[46] = C0342C95
W[67] = DB37710F
41
46. xảy ra trong thuật toán này: sự khác nhau về các hằng số được sử dụng và vấn đề xử lý song
song. Sau mỗi lần xử lý một khối 512 bit, kết quả của cả hai trường hợp này được cộng thêm
vào thành biến trong các thanh ghi. Điều này dường như làm cho thuật toán an toàn hơn, bảo
mật hơn.
2. HAVAL
Haval là một biến đổi của MD5. Nhưng điểm khác của nó với MD5, đó là nó xử lý các
khối 1024 bit, thay vì 512 bit như MD5, và sử dụng tới 8 thanh ghi 32 bit. Số vòng xử lý của
nó cũng dao động từ 3 đến 5 vòng, chứ không cố định vòng như MD4 hay MD5, mỗi vòng 16
bước. Văn bản đại diện mà nó đưa ra cũng không cố định ở một kích thước, có thể là 128 bit,
160 bit, 192 bit, 224 bit hoặc 256 bit.
Haval thay thế các hàm logic đơn giản của MD5 bằng 7 hàm logic. Mỗi vòng sử dụng một
hàm, nhưng mỗi bước lại là một phép hóan vị khác nhau được đưa ra lúc đầu vào. Đầu vào là
các thông điệp mới, mỗi bước (ngoại trừ bước đầu tiên) sử dụng một hằng số mới. Thuật toán
cũng có hai sự thay đổi luân phiên.
TEMP = (f(j,A,B,C,D,E,F,G) <<< 7) + (H <<< 11) + M[i](r(j)) + K[j]
H = G; G = F; F = E; E = D; D = C; C = B; B = A; A = TEMP
46
47. KẾT LUẬN
Mã hoá thông tin là phần không thể thiếu trong trao đổi thông tin bí mật và bảo vệ hệ
thống. Trong tài liệu này, chúng tôi đã trình bày các vấn đề chung cũng như các thuật toán cụ
thể về một số hình thức mã hoá khác nhau.
Các thuật toán toán mã hoá nói chung rất phức tạp và trong đó có những phần không được
chính các tác giả của thuật toán không công bố. Do đó việc hiểu và triển khai các thuật toán
mã hoá rất phức tạp. Tuy nhiên chúng tôi đã trình bày các thuật toán ở mức cụ thể để có thể
triển khai. Chúng tôi cũng đã triển khai một số thuật toán và có chương trình đi kèm với tài
liệu này.
Trong tài liệu, chúng tôi muốn trình bày với người đọc một cách đơn giản và dễ hiểu nhất
các thuật toán mã hoá. Do đó chúng tôi bỏ đi những phần triển khai phức tạp như trong các hệ
thống thực. Mặc dù các thuật toán được sử dụng trong mạng Internet rất phức tạp và thường
có nhiều chi tiết bổ xung từ thuật toán nguyên bản của tác giả, nhưng chúng đều dựa trên các
thuật toán như DES, RSA, MD5, SHA mà chúng tôi đã chọn để trình bày trong tài liệu này.
Chúng tôi rất hy vọng tài liệu này có ích cho người đọc.
Có rất nhiều vấn đề liên quan với các thuật toán mã hoá mà chúng tôi đã trình bày ở trên.
Ví dụ như các thuật toán DES, RSA, SHA được cải tiến thế nào để tăng tốc độ và độ an toàn?
Làm thế nào để sử dụng các hệ thống mã hoá bí mật và mã hoá công khai để xác thực một
cách an toàn? Việc xác thực trong các hệ thống Windows với hệ thống mã như thế nào?
Chúng tôi rất hy vọng có cơ hội để trình bày các vấn đề này trong các tài liệu tiếp theo.
47
48. TÀI LIỆU THAM KHẢO
[1]. Nguyễn Bính, “Mật mã, Lý thuyết và Thực hành”.
[2]. Nguyễn Thúc Hải, “Mạng máy tính và các hệ thống mở”.
[3]. Nguyễn Quốc Cường, “Internetworking với TCP/IP”.
[4]. Nguyễn Hữu Việt Hưng, “Đại số đại cương”, Nhà xuất bản Giáo dục.
[5]. Phạm Văn Ất, “Kĩ thuật lập trình C cơ sở và nâng cao”, Nhà xuất bản Khoa học kĩ
thuật.
[6]. Phạm Văn Ất, “C++ và lập trình hướng đối tượng”, Nhà xuất bản Khoa học kĩ thuật.
[7]. Bruce Schneier, “Applied Cryptography”.
[8]. R.Rivest, B.Schneier, “Introduction to history and development of Hash Functions”.
[9] R.Anderson and E.Biham, “A Fast New Hash Function”, Third International Workshop
Proceedings, Springer – Verlag, 1996.
[10]. Hans Debfs, Helmut Knebl, “Introduction to cryptography”.
[11]. Douglas, “Cryptography, Theory and Practice”, CRT Press.
[12]. M.Bellare, R.Canetti, and H.Karwwczyk, “Keying Hash Functions for Message
Authentication”,.
[13]. M.Blaze, W.Di_e, R.Rivest, B.Schneier, T.Shimomura, E.Thompson, and M.Weiner,
“Key Lengths for Symmetric Ciphers to Provide Adequate Commercial Security”, Jan 1996.
[14]. William Stallings, “Cryptography and Network Security”.
[15]. Jennifer Sebery and Josef Pieprzyk, “Cryptography: an Introduction to Computer
Security”, New York, Prentice Hall.
[16]. Art Salomaa, Springz – Verlaz, Turku, “Puclic – Key Cryptography”.
[17]. Carlisle Adams, Steve Lloyd, “Understanding PKI: Concepts, Standard and
Development Considerations”.
[18]. H.X.Mel, Deris M.Baker, “Cryptography Decrypte”.
[19]. Jonh E. Herskey, “Cryptography Denystifield”.
[20]. Nick Gallbreath, Nicholas Gallbreath, “Cryptography for Internet & Database
Applications”.
[21]. Stinson, “Library of Congress Cataloging in Publication Data”.
48