Security and Cryptography in Python - Stream Ciphers(1)
The practical implementations of One Time Pads
Real-life One Time Pad?
- 1Gb message requires 1Gb key streams
- No resus of key stream
- Key distribution is difficult
Stream Cipher
A stream cipher is like a One Time Pad
- No requirements on key stream
- Hence, not TRUE randomness
- Also, can re-use key stream
Examples:
- A5/1(G2 encryption) - 54 bits
- A5/2(export version) - 17 bits
- RC4(WEP, SSL) - 40-2048 bits
All algorithms kept secret
Challenges
- Authenticity - MAC
- Re-use key
- Low entropy
Implementation of our Stream Cipher
Refer to :https://en.wikipedia.org/wiki/Linear_congruential_generator
class KeyStream:
def __init__(self, key=1):
self.next = key
def rand(self):
self.next = (1103515245*self.next + 12345) % 2**31
return self.next
def get_key_byte(self):
return self.rand() % 256
key = KeyStream()
for i in range(10):
print(key.get_key_byte())
Running Result:
class KeyStream:
def __init__(self, key=1):
self.next = key
def rand(self):
self.next = (1103515245*self.next + 12345) % 2**31
return self.next
def get_key_byte(self):
return self.rand() % 256
def encrypt(key, message):
return bytes([message[i]^ key.get_key_byte() for i in range(len(message))])
key = KeyStream(10)
message = "Hello, World".encode()
cipher = encrypt(key, message)
print(cipher)
key =KeyStream(10)
message = encrypt(key, cipher)
print(message)
Running Result:
Benefit of Stream Cipher
import random
class KeyStream:
def __init__(self, key=1):
self.next = key
def rand(self):
self.next = (1103515245*self.next + 12345) % 2**31
return self.next
def get_key_byte(self):
return self.rand() % 256
def encrypt(key, message):
return bytes([message[i]^ key.get_key_byte() for i in range(len(message))])
def transmit(cipher, likely):
b = []
for c in cipher:
if random.randrange(0, likely) == 0:
c = c ^ 2**random.randrange(0, 8)
b.append(c)
return bytes(b)
key = KeyStream(10)
message = "Hello, World! I am here to declare that I will take over the universe and become the supreme emperor.".encode()
print(message)
cipher = encrypt(key, message)
print(cipher)
cipher = transmit(cipher, 5)
key = KeyStream(10)
message = encrypt(key, cipher)
print(message)
Running Result: