End to End

Lesson 35: Simple End to End encryption

Hybrid sender:

# rsa-aes eax sender

import sys
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import get_random_bytes

from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA

if len(sys.argv) != 4:
    print(f'usage: python3 {sys.argv[0]} pubkey fileToEncrypt fileToSend')
    sys.exit()

#create random aes symmetric key
aeskey = get_random_bytes(16) #16 bytes = 128bit encryption
#get recipients public rsa key
with open(sys.argv[1], 'rb') as f:
    pubkey= f.read()
rsakey = RSA.importKey(pubkey)
rsacipher = PKCS1_OAEP.new(rsakey)
e_aeskey = rsacipher.encrypt(aeskey)

#use aes key to encrypt file (AES symmetric)
with open(sys.argv[2], 'rb') as f:
    data = f.read()

aescipher = AES.new(aeskey, AES.MODE_EAX)
e_data, tag = aescipher.encrypt_and_digest(data)


#write both encrypted aes key and encrypted file to one bundled file
with open(sys.argv[3], 'wb') as f:
    f.write(e_aeskey) #256 bytes
    f.write(aescipher.nonce) #16 bytes
    f.write(tag) #16 bytes
    f.write(e_data)

Hybrid reciever:

# rsa-aes eax mode recipient
import sys
from Crypto.Cipher import AES

from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA

if len(sys.argv) != 4:
    print(f'usage: python3 {sys.argv[0]} privkey file2Decypt createFile')
    sys.exit()

with open(sys.argv[2], 'rb') as f:
    e_aeskey = f.read(256)
    #16 byte aes key becomes 256 bytes after rsa encryption
    nonce = f.read(16)
    tag = f.read(16)
    e_data = f.read()

with open(sys.argv[1]) as f:
    key = f.read()

privkey = RSA.importKey(key)
rsacipher = PKCS1_OAEP.new(privkey)

aeskey = rsacipher.decrypt(e_aeskey)
try:
    aescipher = AES.new(aeskey, AES.MODE_EAX, nonce)
    data = aescipher.decrypt_and_verify(e_data, tag)
except:
    print('Decryption or Authenticity failure')

with open(sys.argv[3], 'wb') as f:
    f.write(data)

Get file (or use netcat)

#tcp server-receive

#usage: python3 get_file.py host port filename

import socket, sys

if len(sys.argv) != 4:
    print(f'usage: python3 {sys.argv[0]} host port filename')
    sys.exit()

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
host = sys.argv[1]
port = int(sys.argv[2])
s.bind( (host, port) )
s.listen()

conn, addr = s.accept()
data=True
with open(sys.argv[3], 'wb') as f:
    while data:
        data = conn.recv(4096)
        f.write(data)
conn.close()

Send file (or use netcat)

#CLIENT-send tcp

#usage: python3 send_file.py host port filename

import socket, sys

if len(sys.argv) != 4:
    print(f'usage: python3 {sys.argv[0]} host port filename')
    sys.exit()

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = sys.argv[1]
port = int(sys.argv[2])
s.connect( (host, port) )

data = True
with open(sys.argv[3], 'rb') as f:
    while data:
        data = f.read(4096)
        s.sendall(data)

s.close()