Запрос примеров явно не по теме, но я покажу, как вы можете создать алгоритм в целом , используя шифры DES CBC и DES ECB.
Все операции включеныбайты или байтовые массивы.
- разделить 16-байтовый ключ на ключ A и ключ B
- init DES CBC-шифрование с ключом A и нулевым IV в 8 байтов
- перебирать все полные блоки в сообщении и для каждого блока выполнять шифрование CBC, отбрасывая результат (используя тот же экземпляр шифра, вам нужно сохранить состояние в конце концов)
- создать последний блок ископируйте оставшиеся байты сообщения в него
- в следующей позиции, добавьте начальный байт индикатора заполнения
- , завершите шифрование CBC, зашифровав последний блок, и сохраните результат
- выполнить дешифрование DES ECB по результату с помощью ключа B, заменив результат
- , выполнить шифрование DES ECB по результату с помощью ключа A, заменив результат
Изатем, конечно, верните результат.
... счастливое программирование
Ну, так как ответ был принят, я воздержусь от предупреждения не публиковать пример кода и публиковать свой собственныйпросто для того, чтобы продемонстрировать хорошие методы программирования (насколько я могу создавать те, у кого есть моё понимание Python):
import sys
from Crypto.Cipher import DES
from Crypto.Cipher import DES3
from Crypto.Util.strxor import strxor
import binascii
def macIso9797_m1_alg3(key, msg):
return macIso9797_alg3(key, msg, b"\x00")
def macIso9797_m2_alg3(key, msg):
return macIso9797_alg3(key, msg, b"\x80")
def macIso9797_alg3(key, msg, pad_start):
if (len(key) != 16):
raise ValueError("Key length should be 16 bytes")
keya = key[:8]
keyb = key[8:]
full_blocks = len(msg) / 8
# b"\x00" * 8 might be slightly faster
desa = DES.new(keya, DES.MODE_CBC, bytes(bytearray(8)))
for i in range(0, full_blocks):
off = i * 8
block = msg[off:off + 8]
# don't need the ciphertext, just the internal state
desa.encrypt(block)
# create padded final block
final_block = bytearray(8)
left = len(msg) % 8
final_block[0:left] = msg[-left:]
final_block[left] = pad_start
res = desa.encrypt(bytes(final_block))
# cipher may not *just* return the final block (but does)
if (len(res) > 8):
res = res[-8:]
desb = DES.new(keyb, DES.MODE_ECB)
res = desb.decrypt(res)
desc = DES.new(keya, DES.MODE_ECB)
res = desc.encrypt(res)
return res
macKey="EA1302AFBCCF791CB0065BFAD948B092"
message="test message"
res = macIso9797_m1_alg3(binascii.unhexlify(macKey), message)
print("MAC key: " + binascii.hexlify(res))
Обратите внимание, что документация API объектов DES / cipher в приведенном выше коде неясно, какие данные возвращаются и когда. Поэтому я вставил оператор if
для извлечения последнего блока зашифрованного текста, который явно не нужен при реализации current . Это, вероятно, слишком осторожно (но это относится к криптодомену).
Также обратите внимание, что я создал последний блок для заполнения за пределами самого сообщения. Заполнение самого сообщения опасно (вы можете использовать это сообщение для других целей) и / или ресурсоемко, поскольку копирование большого сообщения - плохая идея.