Рейтинг@Mail.ru

Python: генерация группы ключей.


Опять делюсь универскими наработками. Задача в общем то примитивная (или по крайней мере её реализация). Надо сгенерировать N равнозначных ключей для шифрования/дешифрования сообщения. Т.е., генерируем 10 ключей, шифруем сообщение любым из этих 10, расшифровываем так же любым из этих 10. Например, зашифровали пятым ключом, расшифровали третьим, или десятым.

Для реализации поставленной задачи опять прибегнем к ксору aka XOR, исключающее или, почти шифр Вернама. Почти — потому что длина ключа у нас по сути не равна длине сообщения. Алгоритм будет таков:

  1. Дано начальное значение ikey. В общем то это и будет на самом деле ключ, который используется в шифровании и расшифровке, просто он будет «спрятан» в сгенерированных ключах.
  2. Генерируем 10 случайных строк по длине равных ключу ikey.
  3. Для каждой строки из предыдущего пункта выполняем: xor(A, ikey) + A. Полученные строки и будут нашими ключами.

Теперь для шифрования нам необходимо предварительно обработать введёный ключ и извлечь из него ikey. Это можно сделать поксорив первую половину ключа со второй. И с помощью ikey уже шифровать или расшифровывать сообщение.

Реализацию ксора в python нашёл на просторах инета (выглядит довольно красиво, я пока так не умею :-)), остальное писал сам. Вот исходник:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import random, itertools, struct

def generate_strings(ikey, q=10):
keys = {}
for i in range(q):
#print "%d." % i,
keys[i] = ""
for j in range(len(ikey)):
#keys[i] += hex(random.randint(0, 15))[2 : ]
keys[i] += chr(random.randint(0, 255))
#print keys[i]
return keys

def xor (s, key):
key = itertools.cycle(key)
return ».join(chr(ord(x) ^ ord(y)) for (x,y) in itertools.izip(s, key))

def generate_keys(ikey):
keys = generate_strings(ikey)
for i in range(len(keys)):
keys[i] = xor(keys[i], ikey) + keys[i] #xor(keys[i], b) + b
return keys

def bs2s(bs):
ss = ""
for i in bs:
s = hex(ord(i))[2 : ]
if len(s) == 1:
ss += "0"
ss += s
return ss

def s2bs(ss):
bs = ""
for i in range(0, len(ss), 2):
bs += chr(int(ss[i : i +2], 16))
return bs

def restore_key(key):
c = len(key) / 2
return xor(key[ : c], key[c : ])

if __name__ == "__main__":
action = ""
print "Select action:\ng — generate keys\nc — encrypt or decrypt file\nq — quit"
while action != "q":
action = raw_input("> ")
if action == "g":
ikey = raw_input("Enter initial key value: ")
keys = generate_keys(ikey)
print "Generated keys:"
for i in range(len(keys)):
print "%d. %s" % (i, bs2s(keys[i]))
elif action == "c":
f_in_name = raw_input("Enter input file name: ")
f_out_name = raw_input("Enter output file name: ")
key = raw_input("Enter key: ")
try:
key = restore_key(s2bs(key))
f = open(f_in_name, "rb")
c = xor(f.read(), key)
f.close()
f = open(f_out_name, "wb")
f.write(c)
f.close()
except:
print "Errors :-(."
elif action != "q":
print "Invalid action."

Единственная поправка к алгоритму, который я описал — ключи перед выводом я перевожу в шестнадцатиричное число, чтобы не хранить ключи в бинарном виде, ну и после ввода так же перевожу обратно. На этом всё.

Ссылки к статье:
http://code.activestate.com/recipes/496970/ — «Recipe 496970: xor for strings».

криптография, Программирование

Пожалуйста, оцените полезность и качество данной статьи. Одна звезда - плохо, 5 - хорошо.
1 звезда2 звезды3 звезды4 звезды5 звёзд (2 голосов, средний: 5,00 из 5)
Loading ... Loading ...

  1. Пока что нет комментариев.
  1. Пока что нет уведомлений.
*