mirror of
https://github.com/ComradCollective/Comrad
synced 2024-11-16 00:12:48 +00:00
decryption!?
This commit is contained in:
parent
2b4ba56c10
commit
e6929ae7c7
@ -44,8 +44,8 @@ dutchwhite=229,219,181
|
||||
COLOR_TOOLBAR= smokyblack #5,5,5 #russiangreen #pinetreegreen #kombugreen #(12,5,5) #russiangreen
|
||||
COLOR_BG = (0,73,54)
|
||||
# COLOR_ICON = (201,203,163)
|
||||
COLOR_LOGO = grullo#russiangreen #(0,0,0) #(0,0,0) #(151,177,140) #(132,162,118) #(109,140,106)
|
||||
COLOR_ICON = grullo#russiangreen #(0,0,0) #COLOR_LOGO
|
||||
COLOR_LOGO = dutchwhite#russiangreen #(0,0,0) #(0,0,0) #(151,177,140) #(132,162,118) #(109,140,106)
|
||||
COLOR_ICON = dutchwhite#russiangreen #(0,0,0) #COLOR_LOGO
|
||||
COLOR_TEXT =dutchwhite #(241,233,203) #COLOR_ICON #(207,219,204) #(239,235,206) # (194,211,187) # (171,189,163) # (222,224,198) # COLOR_LOGO #(223, 223, 212)
|
||||
COLOR_CARD = smokyblack #skin2 #huntergreen #(30,23,20) #(51,73,45) # (67,92,61) #(12,9,10)
|
||||
# COLOR_TOOLBAR = (8s9,59,43)
|
||||
@ -221,6 +221,7 @@ class MainApp(MDApp):
|
||||
title = 'Komrade'
|
||||
logged_in=False
|
||||
store = JsonStore('../p2p/.keys.json')
|
||||
store_global = JsonStore('../p2p/.keys.global.json')
|
||||
login_expiry = 60 * 60 * 24 * 7 # once a week
|
||||
texture = ObjectProperty()
|
||||
|
||||
|
1
p2p/.keys.global.json
Normal file
1
p2p/.keys.global.json
Normal file
@ -0,0 +1 @@
|
||||
{"_keys": {"private": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCwc6j5VyvdRgtx\nLhXgHnJg4qqzJjXHiJyQJhYEPChBzoI1prqspOaHPE2d9BY5ArqOzoKmZop8TUi8\npzbnQO5v44m//PqnLx17CM25E5r83TqBK2bAD8appm9kktZZ5/EVjkceKZLat0lD\nSXRI7Xaphhn8WtRJ2zexcMcs/wQamrh5/J86GWPbuqHnPM79Cd+56RWkY+ou3Eqr\ng5Xka5QZJNzXeIHe2tQvTAfMwlAHVfV9qMkf9Ui4R3TUhc9Tp++vNHdfctVAakIG\n5TAVkMVAe6ruIw5VUO9kttsJ3EJRVuNjbmwUcpT3UG+XD9lZ6bX3SOtmjP425Umm\nE4d3oUT/AgMBAAECggEAB5cCBq+kOGFh7p1f3YMRwm8djpUvLQUITv8EZWw9Aw+h\n9DLWxsRVEi4a3Jd6OTuP0MK7RfMVM+GTJmI+71WQrAlqjHKSSYyyRO+NAdABE61k\nbdfzFIHZNsTs97OFOtrKOPYkwvxgz72gjh9jvBtSxln5ViyGAyNF0wEZ4Cqb/5Tj\n37v/8Vyb34EEFHKip3pHDlsbBKEHWMLElc89JgbzL1xxo9jeHetKwzTkLYu+VxBc\nZAoFwwCuMFxBEUgacIEoPUAT5zDxP89dOPF4MTId78bCphDft1XdsH4iu66knwPm\nddMIDgtv1f4JkZXtE4mUbexh0VLVDGzmTffJ/tSTMQKBgQDUigVEMBDbkJRA7BxR\nIjy8CE8MZwqmnR6V4I+qn+qoIX/ydPYx3T5RQ8viO3LnxXK90ZlCmy+xVOks2u62\n/lAY9WULm+Z3fY8+n/Lhm9TETk5UHfQmiwqYRUH0t4iktsXZ2zaOb1MbuFcxGH7h\nd7tSYlMo3w8xsNQAt9sc5G8WVwKBgQDUiIrdOzQZ2wG6etW+aXlFax3clYXyITbR\nhyHIdlnDKhQpHBVXSmfegRmVrmCUxd10euTFW8Z7agxUXhqd3PZrnv3nJ0Y4GLVS\nvoSAiyRtBbqyASynqFlRXn8M17IfrZb81+gkvoF4kkKRzbWv6wVvhf46nCM5qCB5\nnjTJgimNmQKBgClmkUwNCNucOCTFWWa8gpQmEi/aSorWBEUxrwqPiAgkLmYuPl7M\nN/1gdXCmH+Xh4k3zbCU7UXj7j0g7hVCEDVovQvWV8rjH7oVGZutnjXSHxF5CT3LK\nls++ffCLZ8SeDcA4IVJxgQDfUaywltaYmhacLJLDkJQfW8ygA8CHBtSVAoGAD3c0\nK68gNnVyZcCEh0ujkIKf9KpIyfrSw2KC+dRq6cHJH8i0YNrAPjfExdifnJPdbpl2\nxknMYrSv2v/SDgTDRceXEFgSSwi5QSEuATCe4PQWxtdBCZ49iadHtYaIprd6EkIf\n2XSndT+nana+ruN6TMhCXL957LsoSdFSZAt9vJkCgYAoMBzZOWkPUZOuGAWGtgLo\n+CIlYWGYC8My4ynrOBXKQnVs/9ZCEupFm8PBDCkDlkdjUCRQEeYBItg4SKs4IhxX\niODoNMK+phXRRgiH9uZkV6c5wqeyLPIvDU0o62tS7jArApHXC07OS4kN+nGkMABK\nhNwy7RjbFtiLZJN85LKLLQ==\n-----END PRIVATE KEY-----\n", "public": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsHOo+Vcr3UYLcS4V4B5y\nYOKqsyY1x4ickCYWBDwoQc6CNaa6rKTmhzxNnfQWOQK6js6CpmaKfE1IvKc250Du\nb+OJv/z6py8dewjNuROa/N06gStmwA/GqaZvZJLWWefxFY5HHimS2rdJQ0l0SO12\nqYYZ/FrUSds3sXDHLP8EGpq4efyfOhlj27qh5zzO/QnfuekVpGPqLtxKq4OV5GuU\nGSTc13iB3trUL0wHzMJQB1X1fajJH/VIuEd01IXPU6fvrzR3X3LVQGpCBuUwFZDF\nQHuq7iMOVVDvZLbbCdxCUVbjY25sFHKU91Bvlw/ZWem190jrZoz+NuVJphOHd6FE\n/wIDAQAB\n-----END PUBLIC KEY-----\n"}}
|
104
p2p/api.py
104
p2p/api.py
@ -9,7 +9,7 @@ import asyncio,time
|
||||
# logger.setLevel(logging.DEBUG)
|
||||
sys.path.append('../p2p')
|
||||
# logger.info(os.getcwd(), sys.path)
|
||||
|
||||
BSEP=b'||||'
|
||||
|
||||
try:
|
||||
from .crypto import *
|
||||
@ -90,7 +90,7 @@ class Api(object):
|
||||
# self.log('Yawn, getting tired. Going to sleep')
|
||||
# self.root.ids.btn1.trigger_action()
|
||||
|
||||
#i += 1
|
||||
i += 1
|
||||
await asyncio.sleep(60)
|
||||
# pass
|
||||
except asyncio.CancelledError as e:
|
||||
@ -119,18 +119,18 @@ class Api(object):
|
||||
|
||||
if type(key_or_keys) in {list,tuple,dict}:
|
||||
keys = key_or_keys
|
||||
res = await asyncio.gather(*[node.get(key) for key in keys])
|
||||
res = await asyncio.gather(*[self.unpack_well_documented_val(await node.get(key)) for key in keys])
|
||||
#log('RES?',res)
|
||||
else:
|
||||
key = key_or_keys
|
||||
res = await node.get(key)
|
||||
res = await self.unpack_well_documented_val(await node.get(key))
|
||||
|
||||
#node.stop()
|
||||
return res
|
||||
|
||||
return await _get()
|
||||
|
||||
def well_documented_val(self,val):
|
||||
def well_documented_val(self,val,sep=BSEP,encrypt=True):
|
||||
"""
|
||||
What do we want to store with
|
||||
|
||||
@ -139,17 +139,23 @@ class Api(object):
|
||||
3) Public key of author
|
||||
4) Signature of value by author
|
||||
"""
|
||||
from binascii import a2b_uu as ascii2binary
|
||||
from binascii import b2a_uu as binary2ascii
|
||||
|
||||
timestamp=time.time()
|
||||
self.log('timestamp =',timestamp)
|
||||
|
||||
if type(val)!=bytes:
|
||||
value = str(val)
|
||||
try:
|
||||
value_bytes = value.encode('utf-8')
|
||||
except UnicodeDecodeError:
|
||||
value_bytes = value.encode('ascii')
|
||||
else:
|
||||
value_bytes=val
|
||||
|
||||
|
||||
# encrypt?
|
||||
self.log('value while unencrypted =',value_bytes)
|
||||
value_bytes = encrypt_msg(value_bytes, self.public_key_global)
|
||||
self.log('value while encrypted = ',value_bytes)
|
||||
|
||||
#self.log('value =',value)
|
||||
|
||||
@ -161,20 +167,46 @@ class Api(object):
|
||||
signature = sign_msg(value_bytes, self.private_key)
|
||||
self.log('signature =',signature)
|
||||
|
||||
## Verify!
|
||||
authentic = verify_msg(value_bytes,signature,self.public_key)
|
||||
self.log('message is authentic for set??',authentic)
|
||||
|
||||
# value_bytes_ascii = ''.join([chr(x) for x in value_bytes])
|
||||
|
||||
# jsond = {'time':timestamp, 'val':value_bytes_ascii, 'pub':pem_public_key, 'sign':signature}
|
||||
# jsonstr=jsonify(jsond)
|
||||
|
||||
sep=b'||||'
|
||||
|
||||
WDV = sep.join([str(timestamp).encode(), value_bytes,pem_public_key,signature])
|
||||
# self.log('WDV = 'mWD)
|
||||
|
||||
# self.log(WDV.split(sep))
|
||||
|
||||
self.log('well_documented_val() =',WDV)
|
||||
# self.log('well_documented_val() =',WDV)
|
||||
return WDV
|
||||
|
||||
async def unpack_well_documented_val(self,WDV,sep=BSEP):
|
||||
self.log('WDV???',WDV)
|
||||
time,val,pub,sign = WDV.split(sep)
|
||||
pub=load_public_key(pub)
|
||||
|
||||
# verify
|
||||
authentic = verify_msg(val,sign,pub)
|
||||
self.log('message is authentic for GET?',authentic)
|
||||
|
||||
if not authentic:
|
||||
self.log('inauthentic message!')
|
||||
return None
|
||||
|
||||
# decrypt
|
||||
self.log('val before decryption = ',val)
|
||||
val = decrypt_msg(val, self.private_key_global)
|
||||
self.log('val after decryption = ',val)
|
||||
|
||||
time=float(time.decode())
|
||||
#val=val.decode()
|
||||
return time,val,pub,sign
|
||||
|
||||
|
||||
async def set(self,key_or_keys,value_or_values):
|
||||
async def _set():
|
||||
@ -203,12 +235,26 @@ class Api(object):
|
||||
res = await self.get(key_or_keys)
|
||||
self.log('GET_JSON',res)
|
||||
if type(res)==list:
|
||||
# self.log('is a list!',json.loads(res[0]))
|
||||
return [None if x is None else json.loads(x) for x in res]
|
||||
jsonl=[]
|
||||
for time,val,pub,sign in res:
|
||||
dat=json.loads(val.decode())
|
||||
if type(dat)==dict:
|
||||
dat['_time']=time
|
||||
dat['_pub']=pub
|
||||
dat['_sign']=sign
|
||||
jsonl.append(dat)
|
||||
return jsonl
|
||||
else:
|
||||
#log('RES!!!',res)
|
||||
return None if res is None else json.loads(res)
|
||||
time,val,pub,sign = res
|
||||
dat = None if res is None else json.loads(val.decode())
|
||||
if type(dat)==dict:
|
||||
dat['_time']=time
|
||||
dat['_pub']=pub
|
||||
dat['_sign']=sign
|
||||
|
||||
self.log('RETURNING -->',dat)
|
||||
return dat
|
||||
|
||||
|
||||
async def set_json(self,key,value):
|
||||
@ -241,6 +287,8 @@ class Api(object):
|
||||
if person is not None: return {'error':'Username already exists'}
|
||||
|
||||
private_key,public_key = new_keys(password=passkey,save=False)
|
||||
self._private_key = private_key
|
||||
self._public_key = public_key
|
||||
pem_private_key = save_private_key(private_key,password=passkey,return_instead=True)
|
||||
pem_public_key = save_public_key(public_key,return_instead=True)
|
||||
|
||||
@ -248,10 +296,11 @@ class Api(object):
|
||||
private=str(pem_private_key.decode()),
|
||||
public=str(pem_public_key.decode())) #(private_key,password=passkey)
|
||||
await self.set_person(name,public_key)
|
||||
|
||||
|
||||
return {'success':'Account 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')
|
||||
@ -307,6 +356,29 @@ class Api(object):
|
||||
self.app.root.change_screen('login')
|
||||
return self._private_key
|
||||
|
||||
@property
|
||||
def public_key_global(self):
|
||||
if not hasattr(self,'_public_key_global'):
|
||||
try:
|
||||
pem=self.app.store_global.get('_keys').get('public',None)
|
||||
self._public_key_global=load_public_key(pem.encode())
|
||||
return self._public_key_global
|
||||
except ValueError as e:
|
||||
self.log('!!',e)
|
||||
return None
|
||||
|
||||
@property
|
||||
def private_key_global(self):
|
||||
if not hasattr(self,'_private_key_global'):
|
||||
try:
|
||||
pem=self.app.store_global.get('_keys').get('private',None)
|
||||
self._private_key_global=load_private_key(pem.encode())
|
||||
return self._private_key_global
|
||||
except ValueError as e:
|
||||
self.log('!!',e)
|
||||
return None
|
||||
|
||||
|
||||
async def append_json(self,key,data):
|
||||
sofar=await self.get_json(key)
|
||||
if sofar is None: sofar = []
|
||||
@ -364,7 +436,7 @@ class Api(object):
|
||||
|
||||
self.log('file_store!?',file_store)
|
||||
keys = ['/part/'+x for x in file_store['parts']]
|
||||
pieces = await self.get(keys)
|
||||
time,pieces,pub,sign = await self.get(keys)
|
||||
file_store['parts_data']=pieces
|
||||
return file_store
|
||||
|
||||
|
@ -3,6 +3,7 @@ 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
|
||||
|
||||
key_dir = os.path.join(os.path.expanduser('~'),'.keys','komrade')
|
||||
@ -104,7 +105,8 @@ def sign_msg(message, private_key):
|
||||
)
|
||||
|
||||
def verify_msg(message, signature, public_key):
|
||||
return public_key.verify(
|
||||
try:
|
||||
verified = public_key.verify(
|
||||
signature,
|
||||
message,
|
||||
padding.PSS(
|
||||
@ -113,6 +115,10 @@ def verify_msg(message, signature, public_key):
|
||||
),
|
||||
hashes.SHA256()
|
||||
)
|
||||
return True
|
||||
except InvalidSignature:
|
||||
return False
|
||||
return None
|
||||
|
||||
|
||||
|
||||
@ -136,3 +142,18 @@ def verify_msg(message, signature, public_key):
|
||||
# #print(encrypt_msg(b'hello',public_key))
|
||||
|
||||
# print(verify_msg(msg+b'!!',signature,public_key))
|
||||
|
||||
|
||||
|
||||
## ONLY NEEDS RUN ONCE!
|
||||
def gen_global_keys(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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user