12/08/2018, 14:11

Thuật toán mã hóa DES

Thuật toán DES có những giai đoạn sau: quá trình sinh khóa, quá trình mã hóa, quá trình giải mã 1. Quá trình sinh khóa Là quá trình từ 1 khóa 64 bit, sinh ra 16 khóa con 48 bit như sơ đồ dưới đây: Từ khóa chính 64 bit qua bảng hoán vị PC-1 còn 56 bit. Rồi tách thành C0 (28 bit) với D0 ...

Thuật toán DES có những giai đoạn sau: quá trình sinh khóa, quá trình mã hóa, quá trình giải mã

1. Quá trình sinh khóa

Là quá trình từ 1 khóa 64 bit, sinh ra 16 khóa con 48 bit như sơ đồ dưới đây:

Screen Shot 2016-11-19 at 10.41.04 AM.png

Từ khóa chính 64 bit qua bảng hoán vị PC-1 còn 56 bit. Rồi tách thành C0 (28 bit) với D0 (28 bit)

Rồi dịch n bit trái C0, D0 (trong hình ký hiệu LS là dịch trái) ta được C1, D1. Rồi cộng C1 với D1 với nhau qua bảng hoán vị PC-2 ta được K1.

Tương tự vậy thêm 15 vòng nữa ta được K2, K3,..., K16.

Ở các lần 1, 2, 9, 16 dịch bit trái là 1 bit. Còn lại ta dịch bit trái là 2 bit.

$key_string = "thieumao";
$key_hex = convertKeyToHex($key_string);
$key_bin = convert::hexToBin($key_hex);
$key_pc1 = convert::hoanVi($key_bin, destable::$pc1);
$catkey = convert::cat2($key_pc1);
$C[0] = $catkey[0];
$D[0] = $catkey[1];
for ($i=1; $i<=16; $i++){
	$bit = 2;
	if (($i==1) || ($i==2) || ($i==9) || ($i==16) ){
		$bit = 1;
	}
	$C[$i] = convert::dichTrai($C[$i-1], $bit);
	$D[$i] = convert::dichTrai($D[$i-1], $bit);
	$CD[$i] = $C[$i] . $D[$i];
	$K[$i] = convert::hoanVi($CD[$i], destable::$pc2);
	$K_hex[$i] = convert::binToHex($K[$i]);
}

2. Quá trình mã hóa

Yêu cầu của thuật toán DES là khóa đầu vào 64 bit và bản rõ đầu vào cũng là 64 bit. Để xử lý bản rõ đầu vào không phải là 64 bit, ta tách ra thành các khối bit nhỏ là 64 bit. Còn khối cuối cùng ta thêm padding (ở code example mình, mình cộng thêm những padding là số 0 để cho đủ 64 bit) vào cho đủ 64 bit. Rồi ta mã hóa từng khối nhỏ 64 bit đó.

Screen Shot 2016-11-19 at 11.11.59 AM.png

Từng khối nhỏ 64 bit đó, ta qua bản hoán vị IP (Initial Permutation) ta được 1 khối cũng 64 bit. Ta tách ra làm 2 khối nhỏ 32bit (Left 32 bit và Right 32 bit) L0, R0.

Qua hàm F ta biết đổi L0, R0 thành L1, R1.(Gọi là 1 vòng)

Screen Shot 2016-11-19 at 12.28.05 PM.png

Tương tự quay thêm 15 vòng nữa đủ 16 vòng ta được L16, R16. Cộng chuỗi L16 với R16 với nhau, rồi qua bảng hoán vị IP-1 (Ivert Initial Permutation) ta được bản mã. (Ciphertext output)

$banMa = "";
for ($j=0; $j<$soKhoi; $j++){
	echo "<br>>>>>> Khoi " . ($j+1) . " : " . $cacKhoi[$j];
	$x = $cacKhoi[$j];//"AABA39284B27C849";
	$x_bin = convert::hexToBin($x);
	$x_ip = convert::hoanVi($x_bin, destable::$ip);
	$catx = convert::cat2($x_ip);
	$L[0] = $catx[0];
	$R[0] = $catx[1];
	for ($i=1; $i<=16; $i++){
		$L[$i] = $R[$i-1];
		$F = hamF($R[$i-1], $K[$i]);
		$R[$i] = convert::phepXOR($L[$i-1], $F);
	}
	$R16L16 = $R[16].$L[16];
	$y = convert::hoanVi($R16L16, destable::$ip_1);
	$y_hex = convert::binToHex($y);
	echo "<br>Ban ro: " . $x;
	echo "<br>Ban ma: " . $y_hex;
	$banMa = $banMa . $y_hex;
}
echo "<br> Ban ma tong: " . $banMa;

3. Quá trình giải mã

Quá trình giải mã chính là quá trình mã hóa. Nhưng dùng khóa con theo chiều ngược lại. Tức là khối đầu vào là bản mã hóa, dùng khóa con theo thứ tự ngược lại: K16, K15, ..., K1

Để hiểu hơn về thuật toán bạn xem source code example của mình dưới đây:

  • PHP: https://github.com/QuizSystem/DES-PHP
  • Swift 3: https://github.com/QuizSystem/DES-iOS
0