some major changes
parent
e22f41c86f
commit
f8828a0c6f
File diff suppressed because it is too large
Load Diff
@ -1,295 +0,0 @@
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
from cryptography.hazmat.primitives.asymmetric import padding
|
||||
from cryptography.exceptions import InvalidSignature
|
||||
import os
|
||||
try:
|
||||
from .syfr import * #import syfr
|
||||
except ImportError:
|
||||
from syfr import *
|
||||
|
||||
key_dir = os.path.join(os.path.expanduser('~'),'.keys','komrade')
|
||||
if not os.path.exists(key_dir): os.makedirs(key_dir)
|
||||
PATH_PRIVATE_KEY=os.path.join(key_dir,'private_key.pem')
|
||||
PATH_PUBLIC_KEY=os.path.join(key_dir,'public_key.pem')
|
||||
|
||||
|
||||
### CREATING KEYS
|
||||
|
||||
def new_keys(save=True,password=None):
|
||||
private_key = rsa.generate_private_key(
|
||||
public_exponent=65537,
|
||||
key_size=2048,
|
||||
backend=default_backend()
|
||||
)
|
||||
public_key = private_key.public_key()
|
||||
|
||||
if save:
|
||||
save_private_key(private_key,password=password)
|
||||
save_public_key(public_key)
|
||||
|
||||
return private_key,public_key
|
||||
|
||||
|
||||
|
||||
def save_private_key(private_key,fn=PATH_PRIVATE_KEY,password=None, return_instead=False):
|
||||
pem = private_key.private_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PrivateFormat.PKCS8,
|
||||
encryption_algorithm=serialization.NoEncryption() if not password else serialization.BestAvailableEncryption(password.encode())
|
||||
)
|
||||
if return_instead: return pem
|
||||
with open(fn,'wb') as f: f.write(pem)
|
||||
|
||||
def save_public_key(public_key,fn=PATH_PUBLIC_KEY,return_instead=False):
|
||||
pem = public_key.public_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
||||
)
|
||||
if return_instead: return pem
|
||||
with open(fn,'wb') as f: f.write(pem)
|
||||
|
||||
|
||||
|
||||
### LOADING KEYS
|
||||
def load_keys():
|
||||
return (load_private_key_from_file(), load_public_key_from_file())
|
||||
|
||||
def load_private_key(pem,password=None):
|
||||
return serialization.load_pem_private_key(
|
||||
pem,
|
||||
password=password.encode() if password else None,
|
||||
backend=default_backend()
|
||||
)
|
||||
|
||||
def load_private_key_from_file(fn=PATH_PRIVATE_KEY,password=None):
|
||||
with open(fn, "rb") as key_file:
|
||||
return load_private_key(key_file.read(), password)
|
||||
|
||||
def load_public_key(pem):
|
||||
return serialization.load_pem_public_key(
|
||||
pem,
|
||||
backend=default_backend()
|
||||
)
|
||||
|
||||
def load_public_key_from_file(fn=PATH_PUBLIC_KEY):
|
||||
with open(fn, "rb") as key_file:
|
||||
return load_public_key(key_file.read())
|
||||
|
||||
### DE/ENCRYPTING
|
||||
def encrypt_msg(message, public_key):
|
||||
return public_key.encrypt(
|
||||
message,
|
||||
padding.OAEP(
|
||||
mgf=padding.MGF1(algorithm=hashes.SHA256()),
|
||||
algorithm=hashes.SHA256(),
|
||||
label=None
|
||||
)
|
||||
)
|
||||
|
||||
def encrypt_msg_symmetric(message):
|
||||
import os
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
backend = default_backend()
|
||||
key = os.urandom(32)
|
||||
iv = os.urandom(16)
|
||||
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend)
|
||||
encryptor = cipher.encryptor()
|
||||
|
||||
ct = encryptor.update(message) + encryptor.finalize()
|
||||
return ct
|
||||
|
||||
def decrypt_msg_symmetric():
|
||||
import os
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
backend = default_backend()
|
||||
key = os.urandom(32)
|
||||
iv = os.urandom(16)
|
||||
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend)
|
||||
|
||||
return ct
|
||||
decryptor = cipher.decryptor()
|
||||
decryptor.update(ct) + decryptor.finalize()
|
||||
b'a secret message'
|
||||
|
||||
def decrypt_msg(encrypted, private_key):
|
||||
return private_key.decrypt(
|
||||
encrypted,
|
||||
padding.OAEP(
|
||||
mgf=padding.MGF1(algorithm=hashes.SHA256()),
|
||||
algorithm=hashes.SHA256(),
|
||||
label=None
|
||||
)
|
||||
)
|
||||
|
||||
### SIGNING/VERIFYING
|
||||
def sign_msg(message, private_key):
|
||||
return private_key.sign(
|
||||
message,
|
||||
padding.PSS(
|
||||
mgf=padding.MGF1(hashes.SHA256()),
|
||||
salt_length=padding.PSS.MAX_LENGTH
|
||||
),
|
||||
hashes.SHA256()
|
||||
)
|
||||
|
||||
def verify_msg(message, signature, public_key):
|
||||
try:
|
||||
verified = public_key.verify(
|
||||
signature,
|
||||
message,
|
||||
padding.PSS(
|
||||
mgf=padding.MGF1(hashes.SHA256()),
|
||||
salt_length=padding.PSS.MAX_LENGTH
|
||||
),
|
||||
hashes.SHA256()
|
||||
)
|
||||
return True
|
||||
except InvalidSignature:
|
||||
return False
|
||||
return None
|
||||
|
||||
|
||||
|
||||
|
||||
# #private_key,public_key = new_keys()
|
||||
# private_key,public_key = load_keys()
|
||||
|
||||
# #print(private_key)
|
||||
# #print(public_key)
|
||||
|
||||
|
||||
# #enc = encrypt_msg('Drive your plow over the bones of the dead', public_key)
|
||||
# #print(enc)
|
||||
|
||||
# dec = decrypt_msg(enc,private_key)
|
||||
# #print(dec)
|
||||
|
||||
# msg = b'hello'
|
||||
# signature = sign_msg(msg,private_key)
|
||||
|
||||
# #print(encrypt_msg(b'hello',public_key))
|
||||
|
||||
# print(verify_msg(msg+b'!!',signature,public_key))
|
||||
|
||||
|
||||
|
||||
## ONLY NEEDS RUN ONCE!
|
||||
def gen_global_keys1(fn='.keys.global.json'):
|
||||
from kivy.storage.jsonstore import JsonStore
|
||||
|
||||
private_key,public_key=new_keys(save=False,password=None)
|
||||
pem_private_key = save_private_key(private_key,password=None,return_instead=True)
|
||||
pem_public_key = save_public_key(public_key,return_instead=True)
|
||||
|
||||
store = JsonStore('./.keys.global.json')
|
||||
|
||||
store.put('_keys',private=str(pem_private_key.decode()),public=str(pem_public_key.decode())) #(private_key,password=passkey)
|
||||
|
||||
def gen_global_keys(fn='.keys.global.json'):
|
||||
from kivy.storage.jsonstore import JsonStore
|
||||
|
||||
store = JsonStore('./.keys.global.json')
|
||||
|
||||
#store.put('_keys',private=str(pem_private_key.decode()),public=str(pem_public_key.decode())) #(private_key,password=passkey)
|
||||
|
||||
private_key = generate_rsa_key()
|
||||
pem_private_key = serialize_privkey(private_key, password=None)# save_private_key(private_key,password=passkey,return_instead=True)
|
||||
pem_public_key = serialize_pubkey(private_key.public_key())
|
||||
store.put('_keys',private=pem_private_key.decode(),public=pem_public_key.decode()) #(private_key,password=passkey)
|
||||
|
||||
"""
|
||||
import os
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
backend = default_backend()
|
||||
key = os.urandom(32)
|
||||
iv = os.urandom(16)
|
||||
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend)
|
||||
encryptor = cipher.encryptor()
|
||||
ct = encryptor.update(b"a secret message") + encryptor.finalize()
|
||||
decryptor = cipher.decryptor()
|
||||
decryptor.update(ct) + decryptor.finalize()
|
||||
b'a secret message'"""
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def aes_rsa_encrypt(message, recipient_rsa_pub):
|
||||
aes_key = create_aes_key()
|
||||
aes_ciphertext, iv = aes_encrypt(message, aes_key)
|
||||
encry_aes_key = rsa_encrypt(aes_key, recipient_rsa_pub)
|
||||
return aes_ciphertext, encry_aes_key, iv #, sign
|
||||
|
||||
|
||||
def aes_rsa_decrypt(aes_ciphertext, rsa_priv, encry_aes_key, iv): #, hmac, hmac_signature, rsa_priv, iv, metadata):
|
||||
aes_key = rsa_decrypt(encry_aes_key, rsa_priv)
|
||||
plaintext = aes_decrypt(aes_ciphertext, aes_key, iv)
|
||||
return plaintext
|
||||
|
||||
|
||||
|
||||
|
||||
# def _decrypt_rsa(x,privkey=CORRECT_PRIV_KEY):
|
||||
# x_decr = rsa_decrypt(x,privkey)
|
||||
# return x_decr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# encrypt sender
|
||||
#def _enc_sender(x):
|
||||
# recv=receiver_pubkey
|
||||
|
||||
# encrypt recipient too?
|
||||
|
||||
|
||||
|
||||
# sender_pubkey_b_encr = sep2.join(
|
||||
# aes_rsa_encrypt(
|
||||
# serialize_pubkey(self.public_key), receiver_pubkey
|
||||
# )
|
||||
# )
|
||||
|
||||
# receiver_pubkey_b_encr = sep2.join(
|
||||
# aes_rsa_encrypt(
|
||||
# serialize_pubkey(receiver_pubkey_b, receiver_pubkey
|
||||
# )
|
||||
# )
|
||||
|
||||
|
||||
|
||||
# msg_encr = sep2.join([val_encr,val_encr_key,iv])
|
||||
# sender_encr = sep2.join(
|
||||
# aes_rsa_encrypt(
|
||||
# serialize_pubkey(self.public_key), receiver_pubkey
|
||||
# )
|
||||
# )
|
||||
# signature_encr = sep2.join(
|
||||
# rsa_encrypt(
|
||||
# signature,
|
||||
# receiver_pubkey
|
||||
# )
|
||||
# )
|
||||
|
||||
|
||||
|
||||
# sender = sep2.join(sender_pubkey_b, signature)
|
||||
|
||||
# WDV = sep.join([
|
||||
# time_b,
|
||||
# receiver_encr,
|
||||
# msg_encr,
|
||||
# sender_encr,
|
||||
# signature_encr
|
||||
# ])
|
||||
|
||||
def simple_lock_test(privkey,pubkey):
|
||||
return privkey.public_key().public_numbers() == pubkey.public_numbers()
|
@ -1,255 +0,0 @@
|
||||
# ###
|
||||
# # Kademlia patches
|
||||
# ###
|
||||
|
||||
# from kademlia.storage import *
|
||||
# from kademlia.network import *
|
||||
# from kademlia.routing import RoutingTable
|
||||
# from rpcudp.protocol import RPCProtocol
|
||||
# import os
|
||||
|
||||
# handler = logging.StreamHandler()
|
||||
# formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||
# handler.setFormatter(formatter)
|
||||
# log = logging.getLogger('kademlia')
|
||||
# log.addHandler(handler)
|
||||
# log.setLevel(logging.DEBUG)
|
||||
|
||||
|
||||
# PROXY_ADDR = ('0.0.0.0',8368)
|
||||
|
||||
|
||||
# """UDP proxy server."""
|
||||
|
||||
# import asyncio
|
||||
|
||||
|
||||
# class ProxyDatagramProtocol(asyncio.DatagramProtocol):
|
||||
|
||||
# def __init__(self, remote_address=PROXY_ADDR):
|
||||
# self.remote_address = remote_address
|
||||
# self.remotes_d = {}
|
||||
# super().__init__()
|
||||
|
||||
# def connection_made(self, transport):
|
||||
# self.transport = transport
|
||||
|
||||
# def datagram_received(self, data, addr):
|
||||
# if addr in self.remotes_d:
|
||||
# self.remotes_d[addr].transport.sendto(data)
|
||||
# return
|
||||
# loop = asyncio.get_event_loop()
|
||||
# self.remotes_d[addr] = RemoteDatagramProtocol(self, addr, data)
|
||||
# coro = loop.create_datagram_endpoint(
|
||||
# lambda: self.remotes_d[addr], remote_addr=self.remote_address)
|
||||
# asyncio.ensure_future(coro)
|
||||
|
||||
|
||||
# class RemoteDatagramProtocol(asyncio.DatagramProtocol):
|
||||
|
||||
# def __init__(self, proxy, addr, data):
|
||||
# print('RemoteDP got:',proxy,addr,data)
|
||||
# self.proxy = proxy
|
||||
# self.addr = addr
|
||||
# self.data = data
|
||||
# super().__init__()
|
||||
|
||||
# def connection_made(self, transport):
|
||||
# self.transport = transport
|
||||
# self.transport.sendto(self.data)
|
||||
|
||||
# def datagram_received(self, data, _):
|
||||
# self.proxy.transport.sendto(data, self.addr)
|
||||
|
||||
# def connection_lost(self, exc):
|
||||
# self.proxy.remotes.pop(self.attr)
|
||||
|
||||
|
||||
# async def start_datagram_proxy(protocol_class, bind, port, remote_host, remote_port):
|
||||
# loop = asyncio.get_event_loop()
|
||||
# protocol = protocol_class((remote_host, remote_port))
|
||||
# return await loop.create_datagram_endpoint(
|
||||
# lambda: protocol, local_addr=(bind, port))
|
||||
|
||||
|
||||
# def main(bind='0.0.0.0', port=8888,
|
||||
# remote_host='0.0.0.0', remote_port=9999):
|
||||
# loop = asyncio.get_event_loop()
|
||||
# print("Starting datagram proxy...")
|
||||
# coro = start_datagram_proxy(bind, port, remote_host, remote_port)
|
||||
# transport, _ = loop.run_until_complete(coro)
|
||||
# print("Datagram proxy is running...")
|
||||
# try:
|
||||
# loop.run_forever()
|
||||
# except KeyboardInterrupt:
|
||||
# pass
|
||||
# print("Closing transport...")
|
||||
# transport.close()
|
||||
# loop.close()
|
||||
|
||||
|
||||
|
||||
# log = logging.getLogger('kademlia') # pylint: disable=invalid-name
|
||||
|
||||
|
||||
|
||||
# class KadProtocol(KademliaProtocol):
|
||||
# # remote_address = PROXY_ADDR
|
||||
# # REMOTES_D={}
|
||||
|
||||
# # def __init__(self, source_node, storage, ksize):
|
||||
# # RPCProtocol.__init__(self,wait_timeout=5)
|
||||
# # self.router = RoutingTable(self, ksize, source_node)
|
||||
# # self.storage = storage
|
||||
# # self.source_node = source_node
|
||||
|
||||
# # def datagram_received(self, data, addr):
|
||||
# # #if not hasattr(self,'remotes_d'): self.remotes_d={}
|
||||
# # # print('\n\n!?!?!?',self.REMOTES_D, type(self.REMOTES_D))
|
||||
# # # if addr in self.REMOTES_D:
|
||||
# # # self.REMOTES_D[addr].transport.sendto(data)
|
||||
# # # return
|
||||
# # loop = asyncio.get_event_loop()
|
||||
# # # self.REMOTES_D[addr] = RemoteDatagramProtocol(self, addr, data)
|
||||
# # RDP = RemoteDatagramProtocol(self, addr, data)
|
||||
# # coro = loop.create_datagram_endpoint(lambda: RDP, remote_addr=self.remote_address)
|
||||
# # asyncio.ensure_future(coro)
|
||||
|
||||
# def handle_call_response(self, result, node):
|
||||
# """
|
||||
# If we get a response, add the node to the routing table. If
|
||||
# we get no response, make sure it's removed from the routing table.
|
||||
# """
|
||||
# if not result[0]:
|
||||
# log.warning("no response from %s, ?removing from router", node)
|
||||
# self.router.remove_contact(node)
|
||||
# return result
|
||||
|
||||
# log.info("got successful response from %s", node)
|
||||
# self.welcome_if_new(node)
|
||||
# return result
|
||||
|
||||
|
||||
|
||||
# class KadServer(Server):
|
||||
# protocol_class = KademliaProtocol # KadProtocol #KademliaProtocol
|
||||
|
||||
# # def __init__(self, *x, **y):
|
||||
# # self.storage = y['storage']
|
||||
# # # raise Exception(str(self.storage))
|
||||
# # super().__init__(*x,**y)
|
||||
# # log.info(f'Storage has {len(self.storage.data)} keys')
|
||||
|
||||
# def __repr__(self):
|
||||
# repr = f"""
|
||||
# KadServer()
|
||||
# ksize = {self.ksize}
|
||||
# alpha = {self.alpha}
|
||||
# storage = {len(self.storage.data)} keys
|
||||
# node = {self.node}
|
||||
# transport = {self.transport}
|
||||
# protocol = {self.protocol}
|
||||
# refresh_loop = {self.refresh_loop}
|
||||
# save_state_loop = {self.save_state_loop}
|
||||
# bootstrappable_neighbors = {self.bootstrappable_neighbors()}
|
||||
# """
|
||||
# return repr
|
||||
|
||||
|
||||
|
||||
# # async def get(self, key):
|
||||
# # """
|
||||
# # Get a key if the network has it.
|
||||
|
||||
# # Returns:
|
||||
# # :class:`None` if not found, the value otherwise.
|
||||
# # """
|
||||
# # log.info("Looking up key %s", key)
|
||||
# # dkey = digest(key)
|
||||
# # # if this node has it, return it
|
||||
# # if self.storage.get(dkey) is not None:
|
||||
# # log.info('I already have this')
|
||||
# # return self.storage.get(dkey)
|
||||
# # node = Node(dkey)
|
||||
# # nearest = self.protocol.router.find_neighbors(node)
|
||||
# # log.info(f'My nearest nodes are: {nearest}')
|
||||
# # if not nearest:
|
||||
# # log.warning("There are no known neighbors to get key %s", key)
|
||||
# # return None
|
||||
# # spider = ValueSpiderCrawl(self.protocol, node, nearest,
|
||||
# # self.ksize, self.alpha)
|
||||
# # found = await spider.find()
|
||||
|
||||
# # log.info(f'spider done crawling: {spider}')
|
||||
# # log.info(f'spider found value: {found}')
|
||||
|
||||
# # self.storage[dkey]=found
|
||||
# # return found
|
||||
|
||||
# # async def set(self, key, value):
|
||||
# # """
|
||||
# # Set the given string key to the given value in the network.
|
||||
# # """
|
||||
# # if not check_dht_value_type(value):
|
||||
# # raise TypeError(
|
||||
# # "Value must be of type int, float, bool, str, or bytes"
|
||||
# # )
|
||||
# # log.info("setting '%s' = '%s' on network", key, value)
|
||||
# # dkey = digest(key)
|
||||
|
||||
# # print('STORE??',type(self.storage),self.storage)
|
||||
# # self.storage.set(dkey,value)
|
||||
# # return await self.set_digest(dkey, value)
|
||||
|
||||
# # async def set_digest(self, dkey, value):
|
||||
# # """
|
||||
# # Set the given SHA1 digest key (bytes) to the given value in the
|
||||
# # network.
|
||||
# # """
|
||||
# # node = Node(dkey)
|
||||
|
||||
# # nearest = self.protocol.router.find_neighbors(node)
|
||||
# # if not nearest:
|
||||
# # log.warning("There are no known neighbors to set key %s",
|
||||
# # dkey.hex())
|
||||
# # #return False
|
||||
|
||||
# # spider = NodeSpiderCrawl(self.protocol, node, nearest,
|
||||
# # self.ksize, self.alpha)
|
||||
# # nodes = await spider.find()
|
||||
# # log.info("setting '%s' on %s", dkey.hex(), list(map(str, nodes)))
|
||||
|
||||
# # # if this node is close too, then store here as well
|
||||
# # neighbs=[n.distance_to(node) for n in nodes]
|
||||
# # log.info('setting on %s neighbors', neighbs)
|
||||
# # biggest = max(neighbs) if neighbs else 0
|
||||
# # log.info('my distance to node is %s, biggest distance is %s',
|
||||
# # self.node.distance_to(node),biggest)
|
||||
# # if self.node.distance_to(node) < biggest:
|
||||
# # self.storage.set(dkey,value)
|
||||
|
||||
# # log.info('here are the nodes %s' % nodes)
|
||||
# # results = [self.protocol.call_store(n, dkey, value) for n in nodes]
|
||||
# # log.info('here are the results')
|
||||
|
||||
# # # return true only if at least one store call succeeded
|
||||
# # return any(await asyncio.gather(*results))
|
||||
|
||||
|
||||
|
||||
# #### NEVERMIND
|
||||
# # KadServer = Server
|
||||
|
||||
# import time
|
||||
# if __name__=='__main__':
|
||||
# # test
|
||||
# hfs = HalfForgetfulStorage(fn='test.db')
|
||||
|
||||
# #hfs['a']=1
|
||||
# # time.sleep(2)
|
||||
# hfs['a']=1000
|
||||
|
||||
# print(hfs['a'])
|
||||
|
||||
|
||||
# print(hfs['a'])
|
@ -0,0 +1,187 @@
|
||||
import os
|
||||
from pythemis.skeygen import KEY_PAIR_TYPE, GenerateKeyPair
|
||||
from pythemis.smessage import SMessage, ssign, sverify
|
||||
from pythemis.exception import ThemisError
|
||||
from base64 import b64decode,b64encode
|
||||
|
||||
KEY_PATH = os.path.join(os.path.expanduser('~'),'.komrade')
|
||||
|
||||
class Person(object):
|
||||
|
||||
def __init__(self,name,api):
|
||||
self.name=name
|
||||
self.api=api
|
||||
|
||||
self.privkey=None
|
||||
self.pubkey=None
|
||||
|
||||
# self.load_or_gen()
|
||||
|
||||
@property
|
||||
def key_path_pub(self):
|
||||
return os.path.join(KEY_PATH,'.komrade.'+self.name+'.addr')
|
||||
|
||||
@property
|
||||
def key_path_priv(self):
|
||||
return os.path.join(KEY_PATH,'.komrade.'+self.name+'.key')
|
||||
|
||||
@property
|
||||
def privkey_b64(self):
|
||||
return b64encode(self.privkey)
|
||||
|
||||
@property
|
||||
def pubkey_b64(self):
|
||||
return b64encode(self.pubkey)
|
||||
## genearating keys
|
||||
|
||||
def gen_key(self):
|
||||
keypair = GenerateKeyPair(KEY_PAIR_TYPE.EC)
|
||||
self.privkey = keypair.export_private_key()
|
||||
self.pubkey = keypair.export_public_key()
|
||||
|
||||
with open(self.key_path_priv, "wb") as private_key_file:
|
||||
private_key_file.write(self.privkey_b64)
|
||||
|
||||
with open(self.key_path_pub, "wb") as public_key_file:
|
||||
public_key_file.write(self.pubkey_b64)
|
||||
|
||||
|
||||
## loading keys from disk
|
||||
|
||||
def load_key(self):
|
||||
if os.path.exists(self.key_path_pub):
|
||||
with open(self.key_path_pub) as pub_f:
|
||||
self.pubkey=b64decode(pub_f.read())
|
||||
|
||||
if os.path.exists(self.key_path_priv):
|
||||
with open(self.key_path_priv) as priv_f:
|
||||
self.privkey=b64decode(priv_f.read())
|
||||
|
||||
def load_or_gen(self):
|
||||
self.load_key()
|
||||
if not self.pubkey:
|
||||
self.gen_key(passphrase)
|
||||
|
||||
def encrypt(self,msg,for_pubkey_b64):
|
||||
# handle verification failure
|
||||
for_pubkey = b64decode(for_pubkey_b64)
|
||||
encrypted_msg = SMessage(self.privkey, for_pubkey).wrap(msg)
|
||||
return encrypted_msg
|
||||
|
||||
def decrypt(self,encrypted_msg,from_pubkey_b64):
|
||||
# handle verification failure
|
||||
from_pubkey = b64decode(from_pubkey_b64)
|
||||
decrypted_msg = SMessage(self.privkey, from_pubkey).unwrap(encrypted_msg)
|
||||
|
||||
def sign(self,msg):
|
||||
signed_msg = b64encode(ssign(self.privkey, msg))
|
||||
return signed_msg
|
||||
|
||||
def verify(self,signed_msg_b64,pubkey_b64):
|
||||
signed_msg = b64decode(signed_msg_b64)
|
||||
public_key = b64decode(pubkey_b64)
|
||||
try:
|
||||
verified_msg = sverify(public_key, signed_msg)
|
||||
return verified_msg
|
||||
except ThemisError as e:
|
||||
print('!!',e)
|
||||
return None
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## PERSONS
|
||||
async def find_pubkey(self,username):
|
||||
return await self.api.get('/pubkey/'+username,decode_data=False)
|
||||
|
||||
async def set_pubkey(self): #,username),pem_public_key):
|
||||
|
||||
await self.set('/pubkey/'+self.name,self.public_key,encode_data=False)
|
||||
# keystr=pem_public_key
|
||||
# await self.set(b'/name/'+keystr,username,encode_data=False)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Register
|
||||
async def register(self,name,passkey=None,just_return_keys=False):
|
||||
# if not (name and passkey): return {'error':'Name and password needed'}
|
||||
import kademlia
|
||||
try:
|
||||
person = await self.get_person(name)
|
||||
except kademlia.network.CannotReachNetworkError:
|
||||
return {'error':'Network disconnected'}
|
||||
except NetworkStillConnectingError:
|
||||
return {'error':'Network still connecting...'}
|
||||
|
||||
keys = self.get_keys()
|
||||
if person is not None:
|
||||
self.log('register() person <-',person)
|
||||
# try to log in
|
||||
|
||||
self.log('my keys',keys)
|
||||
if not name in keys:
|
||||
self.log('!! person already exists')
|
||||
return {'error':'Person already exists'}
|
||||
|
||||
# test 3 conditions
|
||||
privkey=keys[name]
|
||||
pubkey=load_pubkey(person)
|
||||
|
||||
if simple_lock_test(privkey,pubkey):
|
||||
self.username=name
|
||||
self.log('!! logging into',name)
|
||||
return {'success':'Logging back in...'}
|
||||
|
||||
private_key = generate_rsa_key()
|
||||
public_key = private_key.public_key()
|
||||
pem_private_key = serialize_privkey(private_key, password=passkey)# save_private_key(private_key,password=passkey,return_instead=True)
|
||||
pem_public_key = serialize_pubkey(public_key)
|
||||
|
||||
if just_return_keys:
|
||||
return (pem_private_key,pem_public_key)
|
||||
|
||||
# save pub key in db
|
||||
await self.set_person(name,pem_public_key)
|
||||
# save priv key on hardware
|
||||
fn_privkey = os.path.join(KEYDIR,f'.{name}.key')
|
||||
|
||||
self.log('priv key =',pem_private_key)
|
||||
write_key_b(pem_private_key, fn_privkey)
|
||||
|
||||
# good
|
||||
return {'success':'Person created ...', 'username':name}
|
||||
|
||||
|
||||
def load_private_key(self,password):
|
||||
#if not self.app_storage.exists('_keys'): return {'error':'No login keys present on this device'}
|
||||
pem_private_key=self.app_storage.get('_keys').get('private')
|
||||
# self.log('my private key ====',pem_private_key)
|
||||
try:
|
||||
return {'success':load_privkey(pem_private_key,password)}
|
||||
except ValueError as e:
|
||||
self.log('!!',e)
|
||||
return {'error':'Incorrect password'}
|
||||
|
||||
if __name__=='__main__':
|
||||
from p2p import Api
|
||||
api = Api()
|
||||
marx = Person('marx',api=api) #,'marx@marxzuckerburg.com',passphrase='twig')
|
||||
|
||||
marx.gen_key()
|
||||
|
||||
elon = Person('elon',api=api) #,'elon@marxzuckerburg.com',passphrase='twig')
|
||||
elon.gen_key()
|
||||
|
||||
|
||||
msg = b'My public key is '+marx.pubkey_b64
|
||||
signed_msg = marx.sign(msg)
|
||||
|
||||
print(msg)
|
||||
print(signed_msg)
|
||||
|
||||
verified_msg = elon.verify(signed_msg, marx.pubkey_b64)
|
||||
print('verified?',verified_msg)
|
@ -1,2 +0,0 @@
|
||||
from .syfr import *
|
||||
from .loader import *
|
@ -1,222 +0,0 @@
|
||||
import copy
|
||||
import hashlib
|
||||
import os
|
||||
import requests
|
||||
|
||||
from .syfr import *
|
||||
|
||||
DATA_BLOCK_SIZE = 65536
|
||||
|
||||
|
||||
def encrypt_file(file_path, rsa_priv, receiver_pubkey):
|
||||
contents = open(file_path).read()
|
||||
|
||||
return blocks
|
||||
|
||||
|
||||
def masters_from_children(children, rsa_priv, receiver_pubkey):
|
||||
contents = []
|
||||
masters_content = []
|
||||
last_master_content = "MASTER:"
|
||||
|
||||
for child in children:
|
||||
if len(last_master_content) + len(child['id']) > DATA_BLOCK_SIZE - bitsize_marker_length - 32:
|
||||
masters_content.append(last_master_content)
|
||||
last_master_content = "MASTER:"
|
||||
|
||||
last_master_content += "\n{0}".format(child['id'])
|
||||
|
||||
if len(last_master_content) > 8:
|
||||
masters_content.append(last_master_content)
|
||||
|
||||
masters = [encrypt_block(long_pad(master_c), rsa_priv, receiver_pubkey) for master_c in masters_content]
|
||||
return masters
|
||||
|
||||
|
||||
def fetch_block(id):
|
||||
url = "https://syfr.io/data/v0/{0}".format(id)
|
||||
print("Fetching block {0} from {1}.".format(id, url))
|
||||
return requests.get(url).content
|
||||
|
||||
|
||||
def tree_decrypt_block(block, priv):
|
||||
"""
|
||||
In parsing a tree, determine if the block is a master block.
|
||||
If so, return TRUE and a list of ids.
|
||||
Else it is a leaf-content block, return FALSE and whole contents.
|
||||
Whole block dict assumed to be passed in. If ID passed in, try to fetch.
|
||||
"""
|
||||
|
||||
if isinstance(block, str):
|
||||
block = fetch_block(id)
|
||||
|
||||
contents = long_unpad(full_decrypt_block(block, priv))
|
||||
if contents[0:7] == "MASTER:":
|
||||
return True, contents[7:].split('\n')[1:]
|
||||
else:
|
||||
return False, contents
|
||||
|
||||
|
||||
def tree_decrypt(block, priv, cached_blocks=None):
|
||||
"""
|
||||
Decrypts and assembles an entire block tree.
|
||||
If blocks are provided, checks here for cached blocks, otherwise it fetches
|
||||
on Internet.
|
||||
"""
|
||||
content = ""
|
||||
cont = True
|
||||
blocks = [block]
|
||||
|
||||
if isinstance(cached_blocks, list):
|
||||
cb = dict([(b['id'], b) for b in cached_blocks])
|
||||
cached_blocks = cb
|
||||
level = 0
|
||||
|
||||
while cont:
|
||||
new_contents = []
|
||||
print("Decrypting {0} blocks at level {1}.".format(len(blocks), level))
|
||||
level += 1
|
||||
for b in blocks:
|
||||
if cached_blocks and isinstance(b, str) and b in cached_blocks:
|
||||
new_contents.append(tree_decrypt_block(cached_blocks[b], priv))
|
||||
else:
|
||||
new_contents.append(tree_decrypt_block(b, priv))
|
||||
|
||||
blocks = []
|
||||
for is_master, con in new_contents:
|
||||
if not is_master:
|
||||
content += con
|
||||
else:
|
||||
blocks += con
|
||||
cont = len(blocks) > 0
|
||||
|
||||
return content
|
||||
|
||||
|
||||
def assemble_block_tree(contents, rsa_priv, receiver_pubkey):
|
||||
content_pieces = divide_contents(contents)
|
||||
print("Encrypting {0} Leaf Blocks.".format(len(content_pieces)))
|
||||
leaf_blocks = [encrypt_block(c, rsa_priv, receiver_pubkey) for c in content_pieces]
|
||||
blocks = copy.copy(leaf_blocks)
|
||||
n = len(blocks)
|
||||
new_blocks = blocks
|
||||
|
||||
while n > 1:
|
||||
new_blocks = masters_from_children(new_blocks, rsa_priv, receiver_pubkey)
|
||||
print("APPENDING {0} Masters".format(len(new_blocks)))
|
||||
blocks += new_blocks
|
||||
n = len(new_blocks)
|
||||
|
||||
return blocks
|
||||
|
||||
|
||||
def divide_contents(contents):
|
||||
subcontents = []
|
||||
n = 0
|
||||
while n < len(contents):
|
||||
m = min(len(contents), n + DATA_BLOCK_SIZE - bitsize_marker_length)
|
||||
subcontent = contents[n:m]
|
||||
subcontent = long_pad(subcontent, DATA_BLOCK_SIZE)
|
||||
subcontents.append(subcontent)
|
||||
n += DATA_BLOCK_SIZE - bitsize_marker_length
|
||||
return subcontents
|
||||
|
||||
|
||||
def unite_contents(content_blocks):
|
||||
content = ""
|
||||
for n, x in enumerate(content_blocks):
|
||||
content += long_unpad(x)
|
||||
|
||||
return content
|
||||
|
||||
|
||||
def compute_block_hash(block_dict):
|
||||
s = ""
|
||||
for k in sorted(block_dict.keys()):
|
||||
if k in ['id']:
|
||||
continue
|
||||
s += "&{0}:{1}".format(k, block_dict[k])
|
||||
return hashlib.sha256(s).hexdigest()
|
||||
|
||||
|
||||
def decompose_metadata(metadata):
|
||||
sender, receiver = [x.split(':')[-1] for x in metadata.split(';')]
|
||||
return sender, receiver
|
||||
|
||||
|
||||
def recompose_metadata(sender, receiver):
|
||||
# TODO remove this
|
||||
return "sender_pubkey:{0};receiver_pubkey:{1}".format(sender, receiver)
|
||||
|
||||
|
||||
def encrypt_block(content, rsa_priv, receiver_pubkey):
|
||||
assert len(content) == DATA_BLOCK_SIZE
|
||||
aes_ciphertext, encry_aes_key, hmac, hmac_signature, iv, metadata = \
|
||||
encrypt(content, rsa_priv, receiver_pubkey)
|
||||
sender, receiver = decompose_metadata(metadata)
|
||||
response = {
|
||||
'aes_ciphertext': aes_ciphertext,
|
||||
'encry_aes_key': encry_aes_key,
|
||||
'hmac': hmac,
|
||||
'hmac_signature': hmac_signature,
|
||||
'iv': iv,
|
||||
'sender_public_key': sender,
|
||||
'receiver_public_key': receiver
|
||||
}
|
||||
response['id'] = compute_block_hash(response)
|
||||
return response
|
||||
|
||||
|
||||
def full_decrypt_block(response, receiver_privkey):
|
||||
assert compute_block_hash(response) == response['id']
|
||||
|
||||
|
||||
return decrypt(
|
||||
response['aes_ciphertext'],
|
||||
response['encry_aes_key'],
|
||||
response['hmac'],
|
||||
response['hmac_signature'],
|
||||
receiver_privkey,
|
||||
response['iv'],
|
||||
recompose_metadata(
|
||||
response['sender_public_key'], response['receiver_public_key'])
|
||||
)
|
||||
|
||||
|
||||
def aes_decrypt_block(response, aes_key):
|
||||
return
|
||||
|
||||
# def aes_rsa_encrypt(message, recipient_rsa_pub):
|
||||
# aes_key = create_aes_key()
|
||||
# aes_ciphertext, iv = aes_encrypt(message, aes_key)
|
||||
# # hmac_key = hashlib.sha256(aes_key).hexdigest()
|
||||
|
||||
# #sender_pubkey = serialize_pubkey(rsa_priv.public_key())
|
||||
# # recipient_rsa_pub = load_pubkey(receiver_pubkey)
|
||||
# #recipient_rsa_pub = receiver_pubkey
|
||||
# # metadata = loader.recompose_metadata(sender_pubkey, receiver_pubkey)
|
||||
|
||||
# encry_aes_key = rsa_encrypt(aes_key, recipient_rsa_pub)
|
||||
|
||||
# # hmac_list = [metadata, iv, aes_ciphertext, encry_aes_key]
|
||||
# # hmac = create_hmac(hmac_key, hmac_list)
|
||||
# # hmac_signature = sign(hmac, rsa_priv)
|
||||
|
||||
# # return aes_ciphertext, encry_aes_key, hmac, hmac_signature, iv, metadata
|
||||
# return aes_ciphertext, encry_aes_key, iv #, sign
|
||||
|
||||
|
||||
# def aes_rsa_decrypt(aes_ciphertext, encry_aes_key, iv, rsa_priv): #, hmac, hmac_signature, rsa_priv, iv, metadata):
|
||||
# aes_key = rsa_decrypt(encry_aes_key, rsa_priv)
|
||||
|
||||
# # hmac_key = hashlib.sha256(aes_key).hexdigest()
|
||||
# # hmac_list = [metadata, iv, aes_ciphertext, encry_aes_key]
|
||||
# # independent_hmac = create_hmac(hmac_key, hmac_list)
|
||||
# # assert hmac == independent_hmac
|
||||
|
||||
# # sender_pub, receiver_pub = [x.split(':')[-1] for x in metadata.split(';')]
|
||||
# # sender_pub = load_pubkey(sender_pub)
|
||||
# #assert verify_signature(hmac_signature, hmac, sender_pub)
|
||||
|
||||
# plaintext = aes_decrypt(aes_ciphertext, aes_key, iv)
|
||||
# return plaintext
|
@ -1,233 +0,0 @@
|
||||
import base64
|
||||
import hashlib
|
||||
import os
|
||||
|
||||
import cryptography
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.hazmat.primitives import hashes, hmac
|
||||
from cryptography.hazmat.primitives.asymmetric import padding
|
||||
from cryptography.hazmat.primitives.padding import PKCS7
|
||||
|
||||
from . import loader
|
||||
|
||||
bitsize_marker_length = 10
|
||||
|
||||
|
||||
def generate_rsa_key(complexity=4096):
|
||||
private_key = rsa.generate_private_key(
|
||||
public_exponent=65537,
|
||||
key_size=complexity,
|
||||
backend=default_backend()
|
||||
)
|
||||
return private_key
|
||||
|
||||
|
||||
def serialize_privkey(key, password=False):
|
||||
return base64.b64encode(key.private_bytes(
|
||||
encoding=serialization.Encoding.DER,
|
||||
format=serialization.PrivateFormat.PKCS8,
|
||||
encryption_algorithm=serialization.NoEncryption() if not password else serialization.BestAvailableEncryption(password.encode())
|
||||
))
|
||||
|
||||
|
||||
def serialize_pubkey(pubkey):
|
||||
return base64.b64encode(pubkey.public_bytes(
|
||||
encoding=serialization.Encoding.DER,
|
||||
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
||||
))
|
||||
|
||||
|
||||
def load_pubkey(pubkey_text):
|
||||
return serialization.load_der_public_key(
|
||||
base64.b64decode(pubkey_text),
|
||||
backend=default_backend())
|
||||
|
||||
|
||||
def load_privkey(privkey_text,password=None):
|
||||
return serialization.load_der_private_key(
|
||||
base64.b64decode(privkey_text),
|
||||
password=password.encode() if password else None,
|
||||
backend=default_backend()
|
||||
)
|
||||
|
||||
def load_privkey_fn(fn_privkey,password=None):
|
||||
with open(fn_privkey,'rb') as f:
|
||||
privkey=load_privkey(f.read(),password=password)
|
||||
return privkey
|
||||
|
||||
def load_pubkey_fn(fn_pubkey):
|
||||
with open(fn_pubkey,'rb') as f:
|
||||
privkey=load_pubkey(f.read())
|
||||
|
||||
def write_key(key, file_path='mykey.pem'):
|
||||
with open(file_path, 'w+') as fh:
|
||||
fh.write(key)
|
||||
|
||||
def write_key_b(key, file_path='mykey.pem'):
|
||||
with open(file_path, 'wb') as fh:
|
||||
fh.write(key)
|
||||
|
||||
|
||||
def sign(message, private_key):
|
||||
signature = private_key.sign(
|
||||
message,
|
||||
padding.PSS(
|
||||
mgf=padding.MGF1(hashes.SHA256()),
|
||||
salt_length=padding.PSS.MAX_LENGTH),
|
||||
hashes.SHA256()
|
||||
)
|
||||
# signer.update(message)
|
||||
return base64.b64encode(signature) #signer.finalize())
|
||||
|
||||
|
||||
def verify_signature(signature, message, pubkey):
|
||||
try:
|
||||
verified = pubkey.verify(
|
||||
base64.b64decode(signature),
|
||||
message,
|
||||
padding.PSS(
|
||||
mgf=padding.MGF1(hashes.SHA256()),
|
||||
salt_length=padding.PSS.MAX_LENGTH
|
||||
),
|
||||
hashes.SHA256()
|
||||
)
|
||||
return True
|
||||
except cryptography.exceptions.InvalidSignature as e:
|
||||
print('!?',e)
|
||||
return False
|
||||
return None
|
||||
# verifier.update(message)
|
||||
# try:
|
||||
# verifier.verify()
|
||||
# return True
|
||||
# except cryptography.exceptions.InvalidSignature:
|
||||
# print("Invalid Signature")
|
||||
# return False
|
||||
|
||||
|
||||
def rsa_encrypt(message, pubkey):
|
||||
ciphertext = pubkey.encrypt(
|
||||
message,
|
||||
padding.OAEP(
|
||||
mgf=padding.MGF1(algorithm=hashes.SHA1()), # SHA1 is suspect
|
||||
algorithm=hashes.SHA1(),
|
||||
label=None
|
||||
)
|
||||
)
|
||||
return base64.b64encode(ciphertext)
|
||||
|
||||
|
||||
def rsa_decrypt(ciphertext, key):
|
||||
plaintext = key.decrypt(
|
||||
base64.b64decode(ciphertext),
|
||||
padding.OAEP(
|
||||
mgf=padding.MGF1(algorithm=hashes.SHA1()),
|
||||
algorithm=hashes.SHA1(),
|
||||
label=None
|
||||
)
|
||||
)
|
||||
return plaintext
|
||||
|
||||
|
||||
def create_aes_key(complexity=32):
|
||||
return base64.b64encode(os.urandom(complexity))
|
||||
|
||||
|
||||
def create_hmac(key, message_list):
|
||||
h = hmac.HMAC(key, hashes.SHA256(), backend=default_backend())
|
||||
message = "?".join([str(x) for x in message_list])
|
||||
h.update(message)
|
||||
return base64.b64encode(h.finalize())
|
||||
|
||||
|
||||
def pad(message, blocksize=128):
|
||||
padder = PKCS7(blocksize).padder()
|
||||
padded_data = padder.update(message)
|
||||
padded_data += padder.finalize()
|
||||
return padded_data
|
||||
|
||||
|
||||
def long_pad(message, goal_length=loader.DATA_BLOCK_SIZE):
|
||||
assert len(message) + bitsize_marker_length <= goal_length
|
||||
c = 0
|
||||
for _ in range(goal_length - len(message) - bitsize_marker_length):
|
||||
message += "0"
|
||||
c += 1
|
||||
d = str(c).zfill(bitsize_marker_length)
|
||||
message += d
|
||||
return message
|
||||
|
||||
|
||||
def unpad(padded_data, blocksize=128):
|
||||
unpadder = PKCS7(blocksize).unpadder()
|
||||
data = unpadder.update(padded_data)
|
||||
return data + unpadder.finalize()
|
||||
|
||||
|
||||
def long_unpad(message):
|
||||
assert len(message) <= 10**bitsize_marker_length
|
||||
padding_size = int(message[-bitsize_marker_length:])
|
||||
return message[0:-bitsize_marker_length-padding_size]
|
||||
|
||||
|
||||
def aes_encrypt(message, key):
|
||||
iv = os.urandom(16)
|
||||
cipher = Cipher(
|
||||
algorithms.AES(base64.b64decode(key)),
|
||||
modes.CBC(iv),
|
||||
backend=default_backend()
|
||||
)
|
||||
message = pad(message)
|
||||
encryptor = cipher.encryptor()
|
||||
ciphertext = encryptor.update(message) + encryptor.finalize()
|
||||
return base64.b64encode(ciphertext), base64.b64encode(iv)
|
||||
|
||||
|
||||
def aes_decrypt(ciphertext, key, iv):
|
||||
cipher = Cipher(
|
||||
algorithms.AES(base64.b64decode(key)),
|
||||
modes.CBC(base64.b64decode(iv)),
|
||||
backend=default_backend()
|
||||
)
|
||||
decryptor = cipher.decryptor()
|
||||
padded = decryptor.update(base64.b64decode(ciphertext)) + decryptor.finalize()
|
||||
return unpad(padded)
|
||||
|
||||
|
||||
def aes_rsa_encrypt(message, recipient_rsa_pub):
|
||||
aes_key = create_aes_key()
|
||||
aes_ciphertext, iv = aes_encrypt(message, aes_key)
|
||||
# hmac_key = hashlib.sha256(aes_key).hexdigest()
|
||||
|
||||
#sender_pubkey = serialize_pubkey(rsa_priv.public_key())
|
||||
# recipient_rsa_pub = load_pubkey(receiver_pubkey)
|
||||
#recipient_rsa_pub = receiver_pubkey
|
||||
# metadata = loader.recompose_metadata(sender_pubkey, receiver_pubkey)
|
||||
|
||||
encry_aes_key = rsa_encrypt(aes_key, recipient_rsa_pub)
|
||||
|
||||
# hmac_list = [metadata, iv, aes_ciphertext, encry_aes_key]
|
||||
# hmac = create_hmac(hmac_key, hmac_list)
|
||||
# hmac_signature = sign(hmac, rsa_priv)
|
||||
|
||||
# return aes_ciphertext, encry_aes_key, hmac, hmac_signature, iv, metadata
|
||||
return aes_ciphertext, encry_aes_key, iv #, sign
|
||||
|
||||
|
||||
def aes_rsa_decrypt(aes_ciphertext, encry_aes_key, iv, rsa_priv): #, hmac, hmac_signature, rsa_priv, iv, metadata):
|
||||
aes_key = rsa_decrypt(encry_aes_key, rsa_priv)
|
||||
|
||||
# hmac_key = hashlib.sha256(aes_key).hexdigest()
|
||||
# hmac_list = [metadata, iv, aes_ciphertext, encry_aes_key]
|
||||
# independent_hmac = create_hmac(hmac_key, hmac_list)
|
||||
# assert hmac == independent_hmac
|
||||
|
||||
# sender_pub, receiver_pub = [x.split(':')[-1] for x in metadata.split(';')]
|
||||
# sender_pub = load_pubkey(sender_pub)
|
||||
#assert verify_signature(hmac_signature, hmac, sender_pub)
|
||||
|
||||
plaintext = aes_decrypt(aes_ciphertext, aes_key, iv)
|
||||
return plaintext
|
@ -1,52 +0,0 @@
|
||||
import base64
|
||||
import os
|
||||
|
||||
from . import syfr as crypto
|
||||
|
||||
|
||||
def test_rsa_encrypt_and_decrypt():
|
||||
priv = crypto.generate_rsa_key(complexity=512)
|
||||
message = "Attack at Calais"
|
||||
ciphertext = crypto.rsa_encrypt(message, priv.public_key())
|
||||
assert crypto.rsa_decrypt(ciphertext, priv) == message
|
||||
|
||||
|
||||
def test_aes_encrypt_decrypt():
|
||||
priv = crypto.create_aes_key()
|
||||
message = "Sell Watermelons"
|
||||
ciphertext, iv = crypto.aes_encrypt(message, priv)
|
||||
assert crypto.aes_decrypt(ciphertext, priv, iv) == message
|
||||
|
||||
|
||||
def test_full_encrypt():
|
||||
priv1 = crypto.generate_rsa_key()
|
||||
priv2 = crypto.generate_rsa_key()
|
||||
target_pubkey = crypto.serialize_pubkey(priv2.public_key())
|
||||
message = "Santa is not real."
|
||||
|
||||
aes_ciphertext, encry_aes_key, hmac, hmac_signature, iv, metadata = \
|
||||
crypto.encrypt(message, priv1, target_pubkey)
|
||||
|
||||
aes_key = crypto.rsa_decrypt(encry_aes_key, priv2)
|
||||
|
||||
assert crypto.aes_decrypt(aes_ciphertext, aes_key, iv) == message
|
||||
|
||||
assert message == \
|
||||
crypto.decrypt(
|
||||
aes_ciphertext, encry_aes_key, hmac, hmac_signature,
|
||||
priv2, iv, metadata
|
||||
)
|
||||
|
||||
|
||||
def test_sign():
|
||||
priv = crypto.generate_rsa_key(complexity=512)
|
||||
message = "Secret wish list"
|
||||
sig = crypto.sign(message, priv)
|
||||
assert crypto.verify_signature(sig, message, priv.public_key())
|
||||
|
||||
|
||||
def test_long_pad():
|
||||
complexity = 10**3 # won't create exactly this length
|
||||
contents = base64.b64encode(os.urandom(complexity))
|
||||
padded = crypto.long_pad(contents, 3*complexity)
|
||||
assert crypto.long_unpad(padded) == contents
|
@ -1,44 +0,0 @@
|
||||
import base64
|
||||
import hashlib
|
||||
import math
|
||||
import os
|
||||
|
||||
from . import syfr as crypto
|
||||
from . import loader
|
||||
|
||||
|
||||
def random_content(pseudolength):
|
||||
return base64.b64encode(os.urandom(pseudolength))
|
||||
|
||||
|
||||
def test_divide_unite_contents():
|
||||
# random contents
|
||||
complexity = loader.DATA_BLOCK_SIZE * 100 # won't create exactly this length
|
||||
contents = random_content(complexity)
|
||||
size = len(contents)
|
||||
subcontents = loader.divide_contents(contents)
|
||||
assert len(subcontents) == math.ceil(float(size) / float(loader.DATA_BLOCK_SIZE))
|
||||
assert all([len(x) == loader.DATA_BLOCK_SIZE for x in subcontents])
|
||||
|
||||
united = loader.unite_contents(subcontents)
|
||||
assert hashlib.sha256(united).hexdigest() == hashlib.sha256(contents).hexdigest()
|
||||
|
||||
|
||||
def test_encrypt_block():
|
||||
content = crypto.long_pad(random_content(1000))
|
||||
rsa_priv = crypto.generate_rsa_key()
|
||||
priv2 = crypto.generate_rsa_key()
|
||||
receiver_pubkey = crypto.serialize_pubkey(priv2.public_key())
|
||||
|
||||
response = loader.encrypt_block(content, rsa_priv, receiver_pubkey)
|
||||
assert loader.full_decrypt_block(response, priv2) == content
|
||||
|
||||
|
||||
def test_assemble_block_tree():
|
||||
contents = random_content(10**6)
|
||||
rsa_priv = crypto.generate_rsa_key()
|
||||
priv2 = crypto.generate_rsa_key()
|
||||
receiver_pubkey = crypto.serialize_pubkey(priv2.public_key())
|
||||
blocks = loader.assemble_block_tree(contents, rsa_priv, receiver_pubkey)
|
||||
derived_contents = loader.tree_decrypt(blocks[-1], priv2, cached_blocks=blocks)
|
||||
assert derived_contents == contents
|
@ -1,80 +0,0 @@
|
||||
"""
|
||||
1-way UDP to TCP relay.
|
||||
|
||||
Test with netcat
|
||||
1) Run TCP server:
|
||||
nc -l 999
|
||||
2) Run UDP proxy:
|
||||
python udpproxy.py
|
||||
3) Run UDP client:
|
||||
nc -u 127.0.0.1 8888
|
||||
4) Type some strings, type enter, they should show on the TCP server
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
|
||||
|
||||
class ProxyDatagramProtocol(asyncio.DatagramProtocol):
|
||||
|
||||
def __init__(self, remote_address):
|
||||
self.remote_address = remote_address
|
||||
self.remotes = {}
|
||||
self.transport = None
|
||||
super().__init__()
|
||||
|
||||
def connection_made(self, transport):
|
||||
self.transport = transport
|
||||
|
||||
def datagram_received(self, data, addr):
|
||||
if addr in self.remotes:
|
||||
self.remotes[addr].transport.write(data)
|
||||
return
|
||||
loop = asyncio.get_event_loop()
|
||||
self.remotes[addr] = RemoteStreamProtocol(self, data)
|
||||
coro = loop.create_connection(
|
||||
lambda: self.remotes[addr], host=self.remote_address[0], port=int(self.remote_address[1]))
|
||||
asyncio.ensure_future(coro)
|
||||
|
||||
|
||||
class RemoteStreamProtocol(asyncio.Protocol):
|
||||
|
||||
def __init__(self, proxy, data):
|
||||
self.proxy = proxy
|
||||
self.data = data
|
||||
self.transport = None
|
||||
super().__init__()
|
||||
|
||||
def connection_made(self, transport):
|
||||
self.transport = transport
|
||||
self.transport.write(self.data)
|
||||
|
||||
def data_received(self, data, _):
|
||||
pass
|
||||
|
||||
def eof_received(self):
|
||||
pass
|
||||
|
||||
|
||||
def start_datagram_proxy(bind, port, remote_host, remote_port):
|
||||
loop = asyncio.get_event_loop()
|
||||
protocol = ProxyDatagramProtocol((remote_host, remote_port))
|
||||
return (yield from loop.create_datagram_endpoint(lambda: protocol, local_addr=(bind, port)))
|
||||
|
||||
|
||||
def main(bind='0.0.0.0', port=8888, remote_host='127.0.0.1', remote_port=9999):
|
||||
loop = asyncio.get_event_loop()
|
||||
print("Starting datagram proxy...")
|
||||
coro = start_datagram_proxy(bind, port, remote_host, remote_port)
|
||||
transport, _ = loop.run_until_complete(coro)
|
||||
print("Datagram proxy is running on " + str(port))
|
||||
try:
|
||||
loop.run_forever()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
print("Closing transport...")
|
||||
transport.close()
|
||||
loop.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue