Я реализую алгоритм шифрования 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