thức, thì chúng ta sẽ hình dung trong đầu chúng ta như sau: x_{i+1}. Tương tự , chúng ta dùng ^ cho chỉ số trên (superscripts) (số mũ) , x^i là “x mũ i” (x lũy thừa i). Dấu “+” là phép cộng các words . X<<<s là giá trị 32-bit được thực hiện như lệnh xoay (rotating) X về trái s bit.(dời (shift) X về trái s-bit) Not(X) là tóan hạng “bù” của X X v Y là tóan hạng OR của X và Y X xor Y là tóan hạng XOR XY là tóan hạng AND 3. Mô tả thuật tóan MD5 Chúng ta bắt đầu bằng cách giả sử chúng ta có một tín hiệu input có chiều dài b- bit, và chúng ta muốn tìm tín hiệu md của nó . Ở đây b là một số nguyên ko dấu bất kỳ ; b có thể bằng zero, không cần thiết b là một bội số của 8, và nó có thể lớn tùy ý. Chúng ta hình dung các bits của tín hiệu input được viết như dưới đây: m_0 m_1 … m_{b-1} Sau đây có 5 bước để tính tóan một tín hiệu md từ một string input 3.1 Bước 1: Thêm vào các Padding Bits (các bit đệm): Sau đây được gọi là quá trình Padding : -Một tín hiệu được mở rộng sao cho chiều dài của nó có dạng ( p*512+448) bits ; p trong biểu thức trên là số nguyên > hoặc =0). -Sau khi thêm các bit padding vào tín hiệu cho nó có dạng như trên , set bit đầu tiên bằng 1 và các bits sau đó = 0 Sau đây là một số ghi chú tui tính sẳn để các bạn tham khảo: 512-bit = 64-byte = 64-char 448-bit = 56-byte = 112-charHex 128-bit = 16-byte = 32-charHex (32 ký tự hexa) 64-bit = 8-byte 32-bit = 4-byte (giá trị một thanh ghi) = 8-charHex 8-bit = 1-byte 1-char( 1 ký tự nhập vào ANSI) = 1-byte 1-charHex (Một ký tự hexa 0-9 và a-f) = ½ byte = 4-bit 1-byte = 2-charHex = 1-char 1-word = 4-byte (Bảng 1) Ví dụ : Giả sử tín hiệu input là chuổi string : hello Chúng được biểu thị bằng số hexa như sau: hello = 68 65 6c 6c 6f ( 10 charHex = 10*4-bit=40-bit) -Với biểu thức p*512+488 ; do tín hiệu chỉ có 40-bit nên p=0 trong trường hợp này. ( thường thì p=0 do chuổi nhấp vào ko quá 64 ký tự char); do đó để để mở rộng chuối ta cần padding thêm 488-40=448-bit nữa. -Bước kế tiếp là set các bit padding: bit đầu tiên thêm vào có giá trị = 1 và các bit sau nó có giá trị = ko Bây giờ tui viết lại chuổi padded dưới dạng số hex như sau: Chú ý số hex đầu tiên được padding có dạng bit như sau : 1000 (dạng bit)(1- charHex=4bit, bit đầu =1, 3 bit sau =0). Vậy 1000=1*2^3+0*2^2+0*2^1+0*2^0=0x80 (hay 80h) Các số hex sau có dạng : 00 Ta viết lại chuổi đã padded như sau: 68 65 6c 6c 6f 80 00 00 00 … 00 00 (tổng cộng 488-bit=56byte=112-charHex) 448-bit padded Ghi chú : ở đây bạn chú ý đến số 80h thêm vào đầu tiên, vì trong lập trình chúng ta dùng số hex chứ ko thao tác trên bit. 3.2 Bước 2: Thêm vào giá trị chiều dài của chuổi nhập input sau chuổi tạo ra ở bước trên Như trên tui đã nói, b là chiều dài của chuổi đã nhập. Đổi b ra dạng 64 – bit. Và 64-bit này được sử dụng thêm vào sau cùng chuổi đã padding ở bước 1. Trong trường hợp b lớn hơn 2^64 thì chỉ lấy 64-bit low-order thêm vào. Tại thời điểm này , chuổi đã padding có dạng (p*512+488+64) bit =(p*512+512) bit = 512*(p+1) bits Vậy chiều dài bit của chuổi là một bội số của 512 bits ( thường p=0 như trên tui đã nói) Cũng có thể nói, tín hiệu này là có chiều dài là bội số của 16-word (32-bit) Ta có thể dùng mãng : M[0…N-1] biểu thị cho các words của kết quả padding 2 bước trên (N là bội số của 16). Ghi chú: p trong biểu thức 512*(p+1) bits còn gọi là số blocks của khối “16-word Bolcks” (16-word=512bit) Ví dụ: Tiếp tục với ví dụ chuổi hello, ta có chiều dài chuổi hello là b=5. Chiều dài bit của chuổi hello là : b=5*8=40; đổi ra số hexa là 28. Viết lại theo dạng 2-word (64-bit) là : 00 00 00 28. Vậy ta thêm 2 words trên vào cuối chuổi đã padding ở bước 1 . Ta có theo số hex 68 65 6c 6c 6f 80 00 00 00 … 00 00 00 00 00 28 40bit 448-bit 64-bit = 512 bits Trong ASM: Tôi chọn ASM làm ngôn ngữ mô tả cho thuật tóan này, vì thiết nghĩ chúng ta vận dụng MD5 để cracking. Nên sử dụng ngôn ngữ ASM gần gủi với các cracker hơn. Đầu tiên chúng ta định nghĩa hàm như sau: MD5hash proc uses eax ebx ecx edx edi esi,ptBuffer:dword,dtBufferLength:dword,ptMD5Resul t:dword local dta:dword,dtb:dword,dtc:dword,dtd:dword Trong đó ptBuffer là addr chứa địa chỉ string input chúng ta cần hash dtBufferLength : dword : chứa chiều dài b của chuổi string input Thực hiện bước 1 và bước 2 chúng ta có đọan code sau: ; phase I · padding mov edi,ptBuffer <<<edi=addr string input mov eax,dtBufferLength <<<eax=chiều dài string input= b trong mô tả inc eax <<< eax=eax+1 add edi,eax <<< edi=edi+eax mov byte ptr [edi-1],080h <<<padding vào byte đầu tiên = 80h xor edx,edx <<< edx=0 mov ebx,64 <<< ebx=64 (64byte=512bit) , ở đây tính tóan hệ số p trong biểu thức ( p*512+448) bits div ebx <<< chia eax/ebx=eax/64 : thương số chứa trong eax, số dư chứa trong edx neg edx <<< edx=-edx add edx,64 <<<edx=64+edx=64+(-edx ở bước trên) cmp edx,8 <<< so sánh edx với 8 jae @f <<< Nếu >= thì nhảy đến @@ ;Đến đây các bạn hảy chú ý rằng : nếu phần dư khi chia cho 64 chứa trong edx phải từ khỏang 0->56byte(488bit) thì ok và p=eax ,còn nếu trong khỏang 56->64 (64- 56=8byte) thì p=eax+1 tức là edx+64 add edx,64 @@: mov ecx,edx <<<ecx=edx : khởi tạo biến đếm để padding set các bit = 0 xor al,al <<< al=0 rep stosb <<< set al=0 vào các bit padding trong ES:DI, luu từ trái qua phải và tăng DI (EDI) mov eax,dtBufferLength <<<eax= dtBufferLength inc edx <<< edx=edx+1 add dtBufferLength,edx <<< dtBufferLength= dtBufferLength + edx xor edx,edx <<< edx=0 mov ebx,8 <<< ebx=8 : để chuyển chiều dài sang dạng hex (b*8) mul ebx <<< eax=eax*ebx=eax*8 mov dword ptr [edi-8],eax <<< padding 1word=Chiều dài b đã đổi sang dạng số hex vào mov dword ptr [edi-4],edx <<< padding 1word = 0 vào mov edx,dtBufferLength <<<edx= dtBufferLength mov edi,ptBuffer <<<edi= ptBuffer 3.3 Bước 3: Khởi tạo giá trị đầu tiên cho MD Buffer : Bộ đệm buffer của tín hiệu MD có 4-word (A,B,C,D). Chúng được sử dụng để tính tóan tín hiệu MD. Ở đây mỗi A,B,C,D được gọi là register 32-bit. Các registers này được khởi tạo giá trị đầu tiên với giá trị là số hexa như sau: Word A: 01 23 45 67 Word B: 89 ab cd ef Word C: fe dc ba 98 Word D: 76 54 32 10 Trong ASM: ; phase II · chaining variables initialization mov esi,ptMD5Result assume esi:ptr MD5RESULT mov [esi].dtA,067452301h mov [esi].dtB,0efcdab89h mov [esi].dtC,098badcfeh mov [esi].dtD,010325476h 3.4 Bước 4: Qui trình tính tóan tín hiệu trong khối 16-words Blocks Như trên chúng ta biết p là số blocks của khối 16-words Blocks. Vậy bước này là tiến trình tính tóan “ xáo trộn” các khối 16-word Blocks.Thường thì p=0 các bạn nên nhớ điều đó. Đầu tiên chúng ta định nghĩa các hàm bổ trợ mà mỗi một lần chúng lấy 3 word 32- bit và sinh ra một word 32-bit F(X,Y,Z)=XY v not(X) Z G(X,Y,Z)=XZ v Y not(Z) H(X,Y,Z)=X xor Y xor Z I(X,Y,Z)=Y xor (X v not (Z)) Đọan này các bạn tham khảo thêm về mặt tóan học của MD5 , sau đây tui chỉ dịch theo tài liệu để các bạn tiện tham khảo: Trong mỗi một lần tính tóan , hàm F họat động như một điều kiện : Nếu X thỏa thì là Y, khác thì là Z (if x then Y else Z). Hàm F có thể được định nghĩa bằng cách dùng “+” thay vì “v” từ XY và not(X)Z thì sẽ không bao giờ có 1’s trong vị trí bit giống như thế. Chú ý quan tâm rằng nếu các bits của X,Y và Z là imdependent và