Giới thiệu về DES
Định nghĩa
Thuật toán DES (Data Encryption Standard) là một phương pháp mã hóa khối, xử lý thông tin theo từng khối 64 bit và biến đổi chúng qua các quy trình phức tạp để tạo ra bản mã có độ dài không thay đổi Là một giải thuật đối xứng, DES sử dụng cùng một mã khóa cho cả hai quá trình mã hóa và giải mã, với tổng độ dài khóa là 64 bit Tuy nhiên, chỉ 56 bit trong số đó được sử dụng thực sự, trong khi 8 bit còn lại chỉ phục vụ cho việc kiểm tra, dẫn đến độ dài thực tế của khóa chỉ là 56 bit.
DES được thiết kế dựa trên hai khái niệm chính: mã hóa tổng (product cipher) và mã Feistel (Feistel cipher) Mã hóa tổng kết hợp nhiều phương pháp mã hóa đơn giản như thay thế và hoán vị, mang lại độ an toàn cao hơn so với các mã hóa riêng lẻ Mã Feistel, một dạng mã khối lặp, kết hợp các phép thay thế và hoán vị, trong đó bản rõ được biến đổi qua nhiều vòng để tạo ra bản mã cuối cùng.
Mô hình mã Feistel
Mã Feistel là một loại mã khối lặp, bao gồm 16 chu trình xử lý giống nhau Quy trình này còn có hai lần hoán vị ở đầu và cuối, được gọi là hoán vị ban đầu và hoán vị cuối cùng.
Trong quá trình mã hóa, hai bước IP và FP diễn ra theo thứ tự, với IP trước FP, trong khi giải mã thì thứ tự này bị đảo ngược Bản rõ P và các bản mã C i được chia thành hai phần: nửa trái và nửa phải, được biểu diễn dưới dạng p = (L 0 , R 0 ).
C i = (L i , R i ) i=1,2, ,n Quy tắc biến đổi các nửa trái phải này qua các vòng được thực hiện như sau:
Ki là một khóa con cho vòng thứ i Khóa con này được sinh ra từ khóa K ban đầu theo một thuật toán sinh khóa con (key schedule):
Hàm F là một hàm mã hóa chung cho tất cả các vòng, đóng vai trò quan trọng trong việc thay thế, trong khi việc hoán đổi các nửa trái phải thực hiện chức năng hoán vị Bản mã c được tính từ kết quả của vòng cuối cùng.
Hình 1: Sơ đồ tính toán của hệ mã Feistel Để giải mã quá trình được thực hiện qua các vòng theo thứ tự ngược lại:
Và cuối cùng bản rõ là: P = ( L 0 , R 0 )
Thuật toán sinh khoá con
Khóa DES là một khối 64-bit, trong đó 8 bit ít quan trọng nhất của mỗi byte bị loại bỏ để kiểm tra tính chẵn lẻ, đảm bảo khóa không có lỗi Quá trình này được thực hiện qua permuted choice 1 (PC), dẫn đến 56 bit được chia thành hai phần bằng nhau và xử lý độc lập Trong mỗi chu trình, một trong hai phần sẽ được dịch đi 1 hoặc 2 bit, tùy thuộc vào chu trình (1, 2, 9, 16 là dịch 1 bit, còn lại là dịch 2 bit) Các khóa con 48 bit được tạo ra thông qua thuật toán lựa chọn 2 (PC-2), với 24 bit từ mỗi phần Quá trình dịch bit ("16x}".format(plaintext) plaintext = bytearray.fromhex(plaintext) if difference == None: return plaintext plaintext = ( plaintext, bytearray(p ^ d for p, d in zip(plaintext, difference))
) return plaintext class Sbox: def init (self, pattern): self.pattern = pattern def call (self, row, column): return self.pattern[row][column]
@property def pattern(self): return self._pattern
The `LinearTransformation` class is initialized with a pattern, which is set using a property setter The class includes a callable method that requires the input to be of type `bytearray`, raising an exception if the input does not meet this requirement.
# if ((len(bytes) * 8) < len(self.pattern)) or ((len(bytes) * 8) < max(self.pattern)):
The provided code defines a function that raises an exception if the input data length does not match the expected pattern length It includes helper functions to get and set specific bits within a byte The `get_bit` function retrieves a bit from a byte based on its position, while the `set_bit` function modifies a bit's value within a byte The main logic processes a pattern, transforming it into a byte array by iterating through segments of the pattern, adjusting values as needed, and returning the final transformed bytearray.
@property def pattern(self): return self._pattern
The `pattern` setter method requires the input to be either a list or tuple It raises an exception if the length of the pattern is not a multiple of 8 Additionally, each value in the pattern must be a positive integer; otherwise, an exception will be triggered.
# raise Exception("Values in pattern cannot be greater than pattern length") if value < 0: raise Exception("Values in pattern cannot be smaller than 0") self._pattern = pattern def function_e(data): e = LinearTransformation((32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12,
The provided code outlines several functions for processing data using bitwise operations, including a key-based transformation and an initial permutation The `function_k` applies an XOR operation between the data and a key, while `function_s` combines bits from the input data to derive specific values The code also includes methods to extract rows and columns from bytes, leveraging s-boxes for substitution during transformation The process starts with initializing a byte and incrementally processes bits, ultimately returning a modified byte array The initial permutation function is defined but not fully detailed in the excerpt.
31, 23, 15, 7)) return ip(data) def initial_permutation_inverted(data): ip_inv = LinearTransformation((40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55,
1, 41, 9, 49, 17, 57, 25)) return ip_inv(data) def pc1(key): c = (57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
37, 29, 21, 13, 5, 28, 20, 12, 4) pc1 = LinearTransformation(c + d) return pc1(key) def pc2(key): pc2 = LinearTransformation((14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19,
29, 32)) return pc2(key) def permutation(data): p = LinearTransformation((16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18,
19, 13, 30, 6, 22, 11, 4, 25)) return p(data) def permutation_inverted(data): p_inv = LinearTransformation((9, 17, 23, 31, 13, 28, 2, 18, 24, 16, 30, 6, 26,
The function `round_key(no, key)` generates a round key by applying a series of rotations to a given key It utilizes a helper function `rotate(array, rotation)` to perform bitwise operations on the array, ensuring that the resulting values adhere to a specific format The key undergoes initial permutation via `pc1(key)`, followed by defined rotations that manipulate its halfbytes These halfbytes are split into two parts, `c` and `d`, which are rotated according to a predetermined sequence After the rotations, the halfbytes are combined and transformed back into the final key format using `pc2(key)` Additionally, the function `get_sboxes()` is designed to retrieve specific patterns for further processing.
The Cipher class is designed to perform encryption and decryption using a specified key, supporting 16 rounds of processing The `encrypt` method applies an initial permutation to the plaintext, divides it into left and right blocks, and processes these blocks through multiple rounds of transformation Each round involves a key derived from the main key and a function that expands, keys, substitutes, and permutes the data The `decrypt` method reverses this process, applying the initial permutation to the ciphertext and executing rounds in reverse order Additionally, utility functions are provided to generate random keys and plaintext messages, enhancing the flexibility of the encryption system.
#!/usr/bin/env python3 from import cast_8_bit_to_6_bit, Cipher as DES, differential_attack_6_rounds, KeyRandomGenerator, \
Here is a rewritten version of the article in paragraph form, complying with SEO rules:The PlaintextRandomGenerator and KeyRandomGenerator are used to generate a random plaintext and key, respectively The encryption and decryption process is demonstrated using the DES algorithm, with the plaintext and key being printed out in hexadecimal format The difference between the original plaintext and the decrypted plaintext is also calculated and printed out Additionally, a 6-round attack is performed on the DES algorithm using the differential attack method, with the goal of recovering the round 6 key The attack is repeated with different differences and subkeys, and the resulting key candidates are printed out The main function calls the encryption/decryption and 6-round attack functions, demonstrating the effectiveness of the differential attack method in recovering the round 6 key.
File test_des.py from des import Cipher, function_s, KeyRandomGenerator, LinearTransformation, permutation, permutation_inverted, \
The article outlines a series of tests for cryptographic functions, specifically focusing on a cipher, linear transformations, and random key/plaintext generation It begins with a `test_cipher` function that verifies the encryption and decryption processes using predefined tuples of keys, plaintexts, and ciphertexts Following that, the `test_function_s` function checks the output of a specific transformation against expected results The `test_linear_transformation` function evaluates multiple linear transformation patterns to ensure accurate data processing Additionally, the `test_key_random_generator` function confirms that the generated keys are of the correct type and length, with an odd parity for each byte The `test_plaintext_random_generator` function assesses the generation of plaintexts, ensuring they are correctly formed and meet specified criteria Lastly, the `test_permutation_inverted` function is introduced to validate the integrity of data permutations This comprehensive testing framework ensures the reliability and security of the cryptographic implementations.
In the testing of the Sbox function, various patterns are utilized to ensure its accuracy The initial dataset is processed into a bytearray, and it is validated against a permutation inversion function The Sbox class is instantiated with different patterns, such as [[1, 2], [0, 3]], and its functionality is verified through assertions that check the output for specific input values For example, when using the pattern [[0, 1], [3, 2]], the Sbox correctly returns 0 for the input (0, 0) and 2 for (1, 1) Further testing with the pattern [[1, 2, 0], [3, 0, 1]] confirms the expected outputs for various inputs, demonstrating the reliability and correctness of the Sbox implementation.
#!/usr/bin/env python3 from setuptools import find_packages, setup setup( name="des", version="0.0.0", packages=find_packages(),
# Simple DES implementation in Python
Install by executing `python setup.py install` or `pip install `.
The provided Python code demonstrates the use of the DES (Data Encryption Standard) algorithm for encryption and decryption It begins by importing the necessary DES class and generating a random key and message The code then encrypts the random message, producing a ciphertext, which is subsequently decrypted back to plaintext Finally, it verifies that the decrypted plaintext matches the original message, ensuring the integrity of the encryption process, with the output confirming that the two are equal.
Implemented 6-rounds differential attack allow to break 6 rounds of DES using differential cryptoanalisys.
Example code has been placed in `des/main.py` file under `break_6_rounds` function.
The difference between encryption and decryption can be illustrated through the example of plaintext values, where the original plaintext is EB47DCC8CF3D1DD7 and the modified plaintext is AB4FDCC8CB3D1DD7 Using the key DC89256D162916DF, the difference between the two plaintexts is calculated as 0367457805008282, which is consistent in 12% of the data The resulting ciphertexts are FC9CE112286E9A23 for the original and FFFBA46A2D6E18A1 for the modified plaintext, with a final ciphertext of 0D6A0F43B0481DAA Upon decryption, the original plaintext EB47DCC8CF3D1DD7 is successfully retrieved, confirming the validity of the process.
Valid key: [57, 32, 42, 3, 38, 6, 15, 49] # key used by DES in 6th round
Key candidate: [-1, 32, -1, -1, 0, 6, 15, 49] # potential key (-1 inform that we cannot predict value)
Key candidate: [16, 0, -1, 3, 38, 6, -1, -1] # potential key (-1 inform that we cannot predict value)
Use `pytest` to run prepared unit tests.
=================================================================================================== platform linux Python 3.9.0+, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
/home/user/des-attack/venv/bin/python cachedir: pytest_cache rootdir: /home/user/des-attack collected 7 items