23 de agosto de 2012

One-time Pads

Seguridad de la Información y Criptografía
Homework 1

This is the first homework for the cryptography class, and the topic is One-Time Pads. We make a program where we create two files with the same list of keys and a function to encrypt and decrypt a message or text with a size less or equal than the key.

At the end of this post I embed my complete code, but in the next part I try to explain how my code works.

What is an One-time pad?


"In cryptography, the one-time pad is a type of encryption which has been proven to be impossible to crack if used correctly. Each bit or character from the plaintext is encrypted by a modular addition with a bit or character from a secret random key of the same length as the plaintext, resulting in a ciphertext."

If the key is truly random, as large as or greater than the plaintext, never reused in whole or part, and kept secret, the ciphertext will be impossible to decrypt or break without knowing the key. So, the only bad thing about this method is if we don't be careful how the list of keys are saved or where, it can be insecure, but is better that the last time when we only encrypt a text rotating the alphabet or changing the position of the alphabet.

My code


First of all, I create a function where the program open two different files, "keys1" and "keys2", then choose a random number between 32 and 126, for convert that number into a ASCII char character, and write a line of characters with a length defined in the beginning of the code (KEY_SIZE).

def create_files_with_keys(n):
  file1 = open('keys1', 'w')
  file2 = open('keys2', 'w')

  for i in range(n):
    key = ''
    for j in range(KEY_SIZE):
      key = key + chr(int(random.uniform(32,126)))
    key = key + '\n'
    file1.write(key)
    file2.write(key)

  file1.close()
  file2.close()
In this image I show what happens when I run my program. In the main function I call to "create_files_with_keys(n)", and the files were created.


And in this case I only create 4 keys, that I defined in the beginning of the code with a global variable. Check that the same keys were written in the two files.


Now for encrypt a message I read line by line in the file with the keys and save it in an array, then write again the keys in the file less the first that we need to use for the encryption.

I use the module for encrypt the message. And for debug print the message, the current key, and the ciphertext.

def encrypt(message):
  keys_file = open('keys1', 'r')
  ciphertext = ''
  residue = []

  for line in keys_file:
    residue.append(line.strip('\n'))
  keys_file.close()

  keys_file = open('keys1', 'w')
  for i in range(len(residue)-1):
    line = residue[i+1] + '\n'
    keys_file.writelines(line)

  message = message.zfill(KEY_SIZE)
  alphabet = map(chr, range(32,126))

  for i in range(KEY_SIZE):
    suma = alphabet.index(message[i]) + alphabet.index(residue[0][i])
    mod = suma%94
    ciphertext = ciphertext + alphabet[mod]

  print 'Message to encrypt: ' + message
  print 'Key used to encrypt: ' + residue[0]
  print 'Message encrypted: ' + ciphertext
  return ciphertext
For this time I use the file "keys2" to get the first key and can decrypt the message.

For debug I print the ciphertext, the key used (it must be the same for encrypt), and the message decrypted.

def decrypt(ciphertext):
  keys_file = open('keys2', 'r')
  message = ''
  residue = []

  for line in keys_file:
    residue.append(line.strip('\n'))
  keys_file.close()

  keys_file = open('keys2', 'w')
  for i in range(len(residue)-1):
    line = residue[i+1] + '\n'
    keys_file.writelines(line)

  alphabet = map(chr, range(32,126))

  for i in range(KEY_SIZE):
    suma = alphabet.index(ciphertext[i]) - alphabet.index(residue[0][i])
    mod = suma%94
    message = message + alphabet[mod]

  print 'Message to decrypt: ' + ciphertext
  print 'Key used to decrypt: ' + residue[0]
  print 'Message decrypted: ' + message.lstrip('0')
  return message.lstrip('0')
And finally the main function, where I used the number of keys created in the files for receive the same quantity of messages to encrypt and decrypt.

def main():
  create_files_with_keys(N_KEYS)
  print '\n'
  for i in range(N_KEYS):
    message = raw_input('Write a message: ')
    print '\n'
    ciphertext = encrypt(message)
    print '\n'
    message = decrypt(ciphertext)
    print '\n'
  print '\n'
Here's an example of how I write a message, the message is encrypted, the key in one files is deleted, then send the message to the function for decrypt, use the first key in the other file, delete the key and decrypt the message.


Complete code



References
One-Time Pad - Definition

1 comentario:

  1. random.randint(a, b)
    diff archivo.1 archivo.2
    Nice work; 5 pts.

    ResponderEliminar

Nota: solo los miembros de este blog pueden publicar comentarios.