Ключ алгоритма IDEA делает неверный текст дешифрования - PullRequest
0 голосов
/ 17 июня 2020

Я реализую алгоритм шифрования IDEA, и мне нужно зашифровать некоторый текст из файла, расшифровать и записать его в выходной файл.
Но давайте рассмотрим запуск образца шифрования следующим образом:

Я шифрование каждые 8 ​​байтов (символов) [всего 64 бита], и проблема явно связана с ключом. Я генерирую 128-битный ключ, используя следующий метод

key=random.getrandbits(128)

Пример выполнения алгоритма:

plain_text = 'HiStackO'
# IDEA Example
cryptor = IDEA()  # Initialize cryptor with 128bit key
cipher_text = cryptor.encrypt(plain_text)
deciphered_text = cryptor.decrypt(cipher_text)
print(
    "Original text = {0}\nEncryption key = {3}\nCiphered text = {1}\nDeciphered text = {2}".format(plain_text, cipher_text, deciphered_text, cryptor.key))

Вывод:

Original text = HiStackO
Encryption key = 190198366819106713251143891094816949033
Ciphered text = 21ad870e1a262894
Deciphered text = HiStackO

Другой прогон с другим случайно сгенерированным ключом:

Original text = HiStackO
Encryption key = 139562249838113732045629763230225557471
Ciphered text = 6b547bde7d2b852
Deciphered text = „uƹç 

Для приведенного выше примера примерно каждые 5/6 прогонов дает вам этот неверный результат, он может варьироваться в зависимости от разных простых текстов ...
Что я отсутствует? Я не смог найти каких-либо конкретных c ограничений для генерации ключей для алгоритма
Одна странность заключается в том, что почти в каждой статье / книге в Интернете говорится о замене шагов 12-13 (здесь 11,12) для каждого раунда, кроме последний раунд
Но метод никогда не работал, только этот (замена только в последней половине раунда)

Шифрование / дешифрование + вычисление шифр-кода:

ROUNDS = 9
def calculate_cipher(self, sub_keys, text):
    X = text
    K = sub_keys # 9 lists one for each round 8*6subkeys + 4 for the last half round

    step = ['0'] * 14
    for i in range(0, ROUNDS - 1):
        # Input print
        # print("Round [" + str(i + 1) + "] BIN input " + str(X))
        # print("Round [" + str(i + 1) + "] DEC input " + str([int(x, 2) for x in X]))
        # print("Round [" + str(i + 1) + "] HEX input " + ' '.join([str(hex(int(x, 2)))[2:] for x in X]))
        # Sub Key print
        # print("Round [" + str(i + 1) + "] BIN sub-key " + str(K[i]))
        # print("Round [" + str(i + 1) + "] DEC sub-key " + str([int(k, 2) for k in K[i]]))
        # print("Round [" + str(i + 1) + "] HEX sub-key " + ' '.join([str(hex(int(k, 2)))[2:] for k in K[i]]))
        step[0] = (self.mul(X[0], int(K[i][0], 2)))
        step[1] = (self.add(X[1], int(K[i][1], 2)))
        step[2] = (self.add(X[2], int(K[i][2], 2)))
        step[3] = (self.mul(X[3], int(K[i][3], 2)))
        step[4] = (self.xor(step[0], step[2]))
        step[5] = (self.xor(step[1], step[3]))
        step[6] = (self.mul(step[4], int(K[i][4], 2)))
        step[7] = (self.add(step[5], step[6]))
        step[8] = (self.mul(step[7], int(K[i][5], 2)))
        step[9] = (self.add(step[6], step[8]))
        step[10] = (self.xor(step[0], step[8]))
        step[11] = (self.xor(step[2], step[8]))
        step[12] = (self.xor(step[1], step[9]))
        step[13] = (self.xor(step[3], step[9]))

        X = [step[10], step[11], step[12], step[13]] 

    """X1 * K1
       X2 + K2
       X3 + K3
       X4 * K4"""
    X = [step[10], step[12], step[11], step[13]]
    result = []
    result.append(self.mul(X[0], int(K[ROUNDS - 1][0], 2)))
    result.append(self.add(X[1], int(K[ROUNDS - 1][1], 2)))
    result.append(self.add(X[2], int(K[ROUNDS - 1][2], 2)))
    result.append(self.mul(X[3], int(K[ROUNDS - 1][3], 2)))

    cipher = ''.join([str(hex(int(x)))[2:] for x in result])
    #print("Final Cipher/Decipher: " + cipher + "\n---------------")
    cipher = '0' * (16 - len(cipher)) + cipher
    return cipher  # Encrypted/decrypted Hex string

def encrypt(self, plain_text=''):
    plain_text = get_pt_bin_block_list(plain_text)#Converts every byte to 
binary (8 bytes) and then combines each 2 making list divided to 4 cells 16 bit each(each cell contains the int value of the combination of both chars binaries)
        print(plain_text)
        return self.calculate_cipher(self.enc_sub_keys, plain_text)

def decrypt(self, cipher_text=''):
    cipher_text = get_cipher_block(cipher_text)
    res = self.calculate_cipher(self.dec_sub_keys, cipher_text)
    res = ''.join('0' * (16 - len(res))) + res
    print("Decrypted cipher: " + res)
    return ''.join([chr(int(''.join(c), 16)) for c in zip(res[0::2],res[1::2])])    

**Operations**
    self.mul = lambda x, y: (x*y) % (2**BLOCK_SIZE+1)#int(np.mod(x * y, 2 ** BLOCK_SIZE + 1))
            self.add = lambda x, y: (x+y) % (2**BLOCK_SIZE)#int(np.mod(x + y, 2 ** BLOCK_SIZE))
            self.xor = lambda x, y: x ^ y
...